Char/Misc driver fixes for 3.13-rc3
Nothing huge, just a few small bugfixes for problems reported, and a device id update. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iEYEABECAAYFAlKiE8QACgkQMUfUDdst+yl9dQCgwXrgSRyBlULDHOdBnKblqrMq gYQAoLVKfuEOXRXBJOD4CzNeCMLButsM =HbWB -----END PGP SIGNATURE----- Merge tag 'char-misc-3.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char/misc driver fixes from Greg KH: "Nothing huge, just a few small bugfixes for problems reported, and a device id update" * tag 'char-misc-3.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: mei: add 9 series PCH mei device ids drivers/char/i8k.c: add Dell XPLS L421X MAINTAINERS: add HSI subsystem misc: mic: Suppress memory space sparse warnings misc: mic: Fix endianness issues. misc: mic: Fix user space namespace pollution from mic_common.h. misc: mic: Bug fix for sysfs poll usage. misc: mic: Minor bug fix in 'retry' loops. misc: mic: Change mic_notify(...) to return true. extcon: remove freed groups caused the panic or warning in unregister flow extcon: arizona: Get pdata from arizona structure not device
This commit is contained in:
Коммит
f64001ef16
5
CREDITS
5
CREDITS
|
@ -655,6 +655,11 @@ S: Stanford University
|
||||||
S: Stanford, California 94305
|
S: Stanford, California 94305
|
||||||
S: USA
|
S: USA
|
||||||
|
|
||||||
|
N: Carlos Chinea
|
||||||
|
E: carlos.chinea@nokia.com
|
||||||
|
E: cch.devel@gmail.com
|
||||||
|
D: Author of HSI Subsystem
|
||||||
|
|
||||||
N: Randolph Chung
|
N: Randolph Chung
|
||||||
E: tausq@debian.org
|
E: tausq@debian.org
|
||||||
D: Linux/PA-RISC hacker
|
D: Linux/PA-RISC hacker
|
||||||
|
|
|
@ -313,7 +313,7 @@ static struct mic_device_desc *get_device_desc(struct mic_info *mic, int type)
|
||||||
int i;
|
int i;
|
||||||
void *dp = get_dp(mic, type);
|
void *dp = get_dp(mic, type);
|
||||||
|
|
||||||
for (i = mic_aligned_size(struct mic_bootparam); i < PAGE_SIZE;
|
for (i = sizeof(struct mic_bootparam); i < PAGE_SIZE;
|
||||||
i += mic_total_desc_size(d)) {
|
i += mic_total_desc_size(d)) {
|
||||||
d = dp + i;
|
d = dp + i;
|
||||||
|
|
||||||
|
@ -445,8 +445,8 @@ init_vr(struct mic_info *mic, int fd, int type,
|
||||||
__func__, mic->name, vr0->va, vr0->info, vr_size,
|
__func__, mic->name, vr0->va, vr0->info, vr_size,
|
||||||
vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
|
vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
|
||||||
mpsslog("magic 0x%x expected 0x%x\n",
|
mpsslog("magic 0x%x expected 0x%x\n",
|
||||||
vr0->info->magic, MIC_MAGIC + type);
|
le32toh(vr0->info->magic), MIC_MAGIC + type);
|
||||||
assert(vr0->info->magic == MIC_MAGIC + type);
|
assert(le32toh(vr0->info->magic) == MIC_MAGIC + type);
|
||||||
if (vr1) {
|
if (vr1) {
|
||||||
vr1->va = (struct mic_vring *)
|
vr1->va = (struct mic_vring *)
|
||||||
&va[MIC_DEVICE_PAGE_END + vr_size];
|
&va[MIC_DEVICE_PAGE_END + vr_size];
|
||||||
|
@ -458,8 +458,8 @@ init_vr(struct mic_info *mic, int fd, int type,
|
||||||
__func__, mic->name, vr1->va, vr1->info, vr_size,
|
__func__, mic->name, vr1->va, vr1->info, vr_size,
|
||||||
vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
|
vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
|
||||||
mpsslog("magic 0x%x expected 0x%x\n",
|
mpsslog("magic 0x%x expected 0x%x\n",
|
||||||
vr1->info->magic, MIC_MAGIC + type + 1);
|
le32toh(vr1->info->magic), MIC_MAGIC + type + 1);
|
||||||
assert(vr1->info->magic == MIC_MAGIC + type + 1);
|
assert(le32toh(vr1->info->magic) == MIC_MAGIC + type + 1);
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
return va;
|
return va;
|
||||||
|
@ -520,7 +520,7 @@ static void *
|
||||||
virtio_net(void *arg)
|
virtio_net(void *arg)
|
||||||
{
|
{
|
||||||
static __u8 vnet_hdr[2][sizeof(struct virtio_net_hdr)];
|
static __u8 vnet_hdr[2][sizeof(struct virtio_net_hdr)];
|
||||||
static __u8 vnet_buf[2][MAX_NET_PKT_SIZE] __aligned(64);
|
static __u8 vnet_buf[2][MAX_NET_PKT_SIZE] __attribute__ ((aligned(64)));
|
||||||
struct iovec vnet_iov[2][2] = {
|
struct iovec vnet_iov[2][2] = {
|
||||||
{ { .iov_base = vnet_hdr[0], .iov_len = sizeof(vnet_hdr[0]) },
|
{ { .iov_base = vnet_hdr[0], .iov_len = sizeof(vnet_hdr[0]) },
|
||||||
{ .iov_base = vnet_buf[0], .iov_len = sizeof(vnet_buf[0]) } },
|
{ .iov_base = vnet_buf[0], .iov_len = sizeof(vnet_buf[0]) } },
|
||||||
|
@ -1412,6 +1412,12 @@ mic_config(void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
ret = lseek(fd, 0, SEEK_SET);
|
||||||
|
if (ret < 0) {
|
||||||
|
mpsslog("%s: Failed to seek to file start '%s': %s\n",
|
||||||
|
mic->name, pathname, strerror(errno));
|
||||||
|
goto close_error1;
|
||||||
|
}
|
||||||
ret = read(fd, value, sizeof(value));
|
ret = read(fd, value, sizeof(value));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
mpsslog("%s: Failed to read sysfs entry '%s': %s\n",
|
mpsslog("%s: Failed to read sysfs entry '%s': %s\n",
|
||||||
|
|
|
@ -4045,6 +4045,14 @@ W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: fs/hpfs/
|
F: fs/hpfs/
|
||||||
|
|
||||||
|
HSI SUBSYSTEM
|
||||||
|
M: Sebastian Reichel <sre@debian.org>
|
||||||
|
S: Maintained
|
||||||
|
F: Documentation/ABI/testing/sysfs-bus-hsi
|
||||||
|
F: drivers/hsi/
|
||||||
|
F: include/linux/hsi/
|
||||||
|
F: include/uapi/linux/hsi/
|
||||||
|
|
||||||
HSO 3G MODEM DRIVER
|
HSO 3G MODEM DRIVER
|
||||||
M: Jan Dumon <j.dumon@option.com>
|
M: Jan Dumon <j.dumon@option.com>
|
||||||
W: http://www.pharscape.org
|
W: http://www.pharscape.org
|
||||||
|
|
|
@ -664,6 +664,13 @@ static struct dmi_system_id __initdata i8k_dmi_table[] = {
|
||||||
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"),
|
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.ident = "Dell XPS421",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "XPS L421X"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1082,7 +1082,7 @@ static void arizona_micd_set_level(struct arizona *arizona, int index,
|
||||||
static int arizona_extcon_probe(struct platform_device *pdev)
|
static int arizona_extcon_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
|
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
|
||||||
struct arizona_pdata *pdata;
|
struct arizona_pdata *pdata = &arizona->pdata;
|
||||||
struct arizona_extcon_info *info;
|
struct arizona_extcon_info *info;
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
int jack_irq_fall, jack_irq_rise;
|
int jack_irq_fall, jack_irq_rise;
|
||||||
|
@ -1091,8 +1091,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
|
||||||
if (!arizona->dapm || !arizona->dapm->card)
|
if (!arizona->dapm || !arizona->dapm->card)
|
||||||
return -EPROBE_DEFER;
|
return -EPROBE_DEFER;
|
||||||
|
|
||||||
pdata = dev_get_platdata(arizona->dev);
|
|
||||||
|
|
||||||
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
|
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
|
||||||
if (!info) {
|
if (!info) {
|
||||||
dev_err(&pdev->dev, "Failed to allocate memory\n");
|
dev_err(&pdev->dev, "Failed to allocate memory\n");
|
||||||
|
|
|
@ -792,6 +792,8 @@ void extcon_dev_unregister(struct extcon_dev *edev)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device_unregister(&edev->dev);
|
||||||
|
|
||||||
if (edev->mutually_exclusive && edev->max_supported) {
|
if (edev->mutually_exclusive && edev->max_supported) {
|
||||||
for (index = 0; edev->mutually_exclusive[index];
|
for (index = 0; edev->mutually_exclusive[index];
|
||||||
index++)
|
index++)
|
||||||
|
@ -812,7 +814,6 @@ void extcon_dev_unregister(struct extcon_dev *edev)
|
||||||
if (switch_class)
|
if (switch_class)
|
||||||
class_compat_remove_link(switch_class, &edev->dev, NULL);
|
class_compat_remove_link(switch_class, &edev->dev, NULL);
|
||||||
#endif
|
#endif
|
||||||
device_unregister(&edev->dev);
|
|
||||||
put_device(&edev->dev);
|
put_device(&edev->dev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(extcon_dev_unregister);
|
EXPORT_SYMBOL_GPL(extcon_dev_unregister);
|
||||||
|
|
|
@ -109,9 +109,12 @@
|
||||||
#define MEI_DEV_ID_PPT_2 0x1CBA /* Panther Point */
|
#define MEI_DEV_ID_PPT_2 0x1CBA /* Panther Point */
|
||||||
#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */
|
#define MEI_DEV_ID_PPT_3 0x1DBA /* Panther Point */
|
||||||
|
|
||||||
#define MEI_DEV_ID_LPT 0x8C3A /* Lynx Point */
|
#define MEI_DEV_ID_LPT_H 0x8C3A /* Lynx Point H */
|
||||||
#define MEI_DEV_ID_LPT_W 0x8D3A /* Lynx Point - Wellsburg */
|
#define MEI_DEV_ID_LPT_W 0x8D3A /* Lynx Point - Wellsburg */
|
||||||
#define MEI_DEV_ID_LPT_LP 0x9C3A /* Lynx Point LP */
|
#define MEI_DEV_ID_LPT_LP 0x9C3A /* Lynx Point LP */
|
||||||
|
#define MEI_DEV_ID_LPT_HR 0x8CBA /* Lynx Point H Refresh */
|
||||||
|
|
||||||
|
#define MEI_DEV_ID_WPT_LP 0x9CBA /* Wildcat Point LP */
|
||||||
/*
|
/*
|
||||||
* MEI HW Section
|
* MEI HW Section
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -76,9 +76,11 @@ static DEFINE_PCI_DEVICE_TABLE(mei_me_pci_tbl) = {
|
||||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)},
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)},
|
||||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
|
||||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
|
||||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT)},
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_H)},
|
||||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_W)},
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_W)},
|
||||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)},
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_LP)},
|
||||||
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_LPT_HR)},
|
||||||
|
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_WPT_LP)},
|
||||||
|
|
||||||
/* required last entry */
|
/* required last entry */
|
||||||
{0, }
|
{0, }
|
||||||
|
|
|
@ -154,14 +154,14 @@ static void mic_reset_inform_host(struct virtio_device *vdev)
|
||||||
{
|
{
|
||||||
struct mic_vdev *mvdev = to_micvdev(vdev);
|
struct mic_vdev *mvdev = to_micvdev(vdev);
|
||||||
struct mic_device_ctrl __iomem *dc = mvdev->dc;
|
struct mic_device_ctrl __iomem *dc = mvdev->dc;
|
||||||
int retry = 100, i;
|
int retry;
|
||||||
|
|
||||||
iowrite8(0, &dc->host_ack);
|
iowrite8(0, &dc->host_ack);
|
||||||
iowrite8(1, &dc->vdev_reset);
|
iowrite8(1, &dc->vdev_reset);
|
||||||
mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
|
mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
|
||||||
|
|
||||||
/* Wait till host completes all card accesses and acks the reset */
|
/* Wait till host completes all card accesses and acks the reset */
|
||||||
for (i = retry; i--;) {
|
for (retry = 100; retry--;) {
|
||||||
if (ioread8(&dc->host_ack))
|
if (ioread8(&dc->host_ack))
|
||||||
break;
|
break;
|
||||||
msleep(100);
|
msleep(100);
|
||||||
|
@ -187,11 +187,12 @@ static void mic_reset(struct virtio_device *vdev)
|
||||||
/*
|
/*
|
||||||
* The virtio_ring code calls this API when it wants to notify the Host.
|
* The virtio_ring code calls this API when it wants to notify the Host.
|
||||||
*/
|
*/
|
||||||
static void mic_notify(struct virtqueue *vq)
|
static bool mic_notify(struct virtqueue *vq)
|
||||||
{
|
{
|
||||||
struct mic_vdev *mvdev = vq->priv;
|
struct mic_vdev *mvdev = vq->priv;
|
||||||
|
|
||||||
mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
|
mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mic_del_vq(struct virtqueue *vq, int n)
|
static void mic_del_vq(struct virtqueue *vq, int n)
|
||||||
|
@ -247,17 +248,17 @@ static struct virtqueue *mic_find_vq(struct virtio_device *vdev,
|
||||||
/* First assign the vring's allocated in host memory */
|
/* First assign the vring's allocated in host memory */
|
||||||
vqconfig = mic_vq_config(mvdev->desc) + index;
|
vqconfig = mic_vq_config(mvdev->desc) + index;
|
||||||
memcpy_fromio(&config, vqconfig, sizeof(config));
|
memcpy_fromio(&config, vqconfig, sizeof(config));
|
||||||
_vr_size = vring_size(config.num, MIC_VIRTIO_RING_ALIGN);
|
_vr_size = vring_size(le16_to_cpu(config.num), MIC_VIRTIO_RING_ALIGN);
|
||||||
vr_size = PAGE_ALIGN(_vr_size + sizeof(struct _mic_vring_info));
|
vr_size = PAGE_ALIGN(_vr_size + sizeof(struct _mic_vring_info));
|
||||||
va = mic_card_map(mvdev->mdev, config.address, vr_size);
|
va = mic_card_map(mvdev->mdev, le64_to_cpu(config.address), vr_size);
|
||||||
if (!va)
|
if (!va)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
mvdev->vr[index] = va;
|
mvdev->vr[index] = va;
|
||||||
memset_io(va, 0x0, _vr_size);
|
memset_io(va, 0x0, _vr_size);
|
||||||
vq = vring_new_virtqueue(index,
|
vq = vring_new_virtqueue(index, le16_to_cpu(config.num),
|
||||||
config.num, MIC_VIRTIO_RING_ALIGN, vdev,
|
MIC_VIRTIO_RING_ALIGN, vdev, false,
|
||||||
false,
|
(void __force *)va, mic_notify, callback,
|
||||||
va, mic_notify, callback, name);
|
name);
|
||||||
if (!vq) {
|
if (!vq) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto unmap;
|
goto unmap;
|
||||||
|
@ -272,7 +273,8 @@ static struct virtqueue *mic_find_vq(struct virtio_device *vdev,
|
||||||
|
|
||||||
/* Allocate and reassign used ring now */
|
/* Allocate and reassign used ring now */
|
||||||
mvdev->used_size[index] = PAGE_ALIGN(sizeof(__u16) * 3 +
|
mvdev->used_size[index] = PAGE_ALIGN(sizeof(__u16) * 3 +
|
||||||
sizeof(struct vring_used_elem) * config.num);
|
sizeof(struct vring_used_elem) *
|
||||||
|
le16_to_cpu(config.num));
|
||||||
used = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
|
used = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
|
||||||
get_order(mvdev->used_size[index]));
|
get_order(mvdev->used_size[index]));
|
||||||
if (!used) {
|
if (!used) {
|
||||||
|
@ -309,7 +311,7 @@ static int mic_find_vqs(struct virtio_device *vdev, unsigned nvqs,
|
||||||
{
|
{
|
||||||
struct mic_vdev *mvdev = to_micvdev(vdev);
|
struct mic_vdev *mvdev = to_micvdev(vdev);
|
||||||
struct mic_device_ctrl __iomem *dc = mvdev->dc;
|
struct mic_device_ctrl __iomem *dc = mvdev->dc;
|
||||||
int i, err, retry = 100;
|
int i, err, retry;
|
||||||
|
|
||||||
/* We must have this many virtqueues. */
|
/* We must have this many virtqueues. */
|
||||||
if (nvqs > ioread8(&mvdev->desc->num_vq))
|
if (nvqs > ioread8(&mvdev->desc->num_vq))
|
||||||
|
@ -331,7 +333,7 @@ static int mic_find_vqs(struct virtio_device *vdev, unsigned nvqs,
|
||||||
* rings have been re-assigned.
|
* rings have been re-assigned.
|
||||||
*/
|
*/
|
||||||
mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
|
mic_send_intr(mvdev->mdev, mvdev->c2h_vdev_db);
|
||||||
for (i = retry; i--;) {
|
for (retry = 100; retry--;) {
|
||||||
if (!ioread8(&dc->used_address_updated))
|
if (!ioread8(&dc->used_address_updated))
|
||||||
break;
|
break;
|
||||||
msleep(100);
|
msleep(100);
|
||||||
|
@ -519,8 +521,8 @@ static void mic_scan_devices(struct mic_driver *mdrv, bool remove)
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
for (i = mic_aligned_size(struct mic_bootparam);
|
for (i = sizeof(struct mic_bootparam); i < MIC_DP_SIZE;
|
||||||
i < MIC_DP_SIZE; i += mic_total_desc_size(d)) {
|
i += mic_total_desc_size(d)) {
|
||||||
d = mdrv->dp + i;
|
d = mdrv->dp + i;
|
||||||
dc = (void __iomem *)d + mic_aligned_desc_size(d);
|
dc = (void __iomem *)d + mic_aligned_desc_size(d);
|
||||||
/*
|
/*
|
||||||
|
@ -539,7 +541,8 @@ static void mic_scan_devices(struct mic_driver *mdrv, bool remove)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* device already exists */
|
/* device already exists */
|
||||||
dev = device_find_child(mdrv->dev, d, mic_match_desc);
|
dev = device_find_child(mdrv->dev, (void __force *)d,
|
||||||
|
mic_match_desc);
|
||||||
if (dev) {
|
if (dev) {
|
||||||
if (remove)
|
if (remove)
|
||||||
iowrite8(MIC_VIRTIO_PARAM_DEV_REMOVE,
|
iowrite8(MIC_VIRTIO_PARAM_DEV_REMOVE,
|
||||||
|
|
|
@ -42,8 +42,8 @@
|
||||||
|
|
||||||
static inline unsigned mic_desc_size(struct mic_device_desc __iomem *desc)
|
static inline unsigned mic_desc_size(struct mic_device_desc __iomem *desc)
|
||||||
{
|
{
|
||||||
return mic_aligned_size(*desc)
|
return sizeof(*desc)
|
||||||
+ ioread8(&desc->num_vq) * mic_aligned_size(struct mic_vqconfig)
|
+ ioread8(&desc->num_vq) * sizeof(struct mic_vqconfig)
|
||||||
+ ioread8(&desc->feature_len) * 2
|
+ ioread8(&desc->feature_len) * 2
|
||||||
+ ioread8(&desc->config_len);
|
+ ioread8(&desc->config_len);
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,7 @@ mic_vq_configspace(struct mic_device_desc __iomem *desc)
|
||||||
}
|
}
|
||||||
static inline unsigned mic_total_desc_size(struct mic_device_desc __iomem *desc)
|
static inline unsigned mic_total_desc_size(struct mic_device_desc __iomem *desc)
|
||||||
{
|
{
|
||||||
return mic_aligned_desc_size(desc) +
|
return mic_aligned_desc_size(desc) + sizeof(struct mic_device_ctrl);
|
||||||
mic_aligned_size(struct mic_device_ctrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int mic_devices_init(struct mic_driver *mdrv);
|
int mic_devices_init(struct mic_driver *mdrv);
|
||||||
|
|
|
@ -62,7 +62,7 @@ void mic_bootparam_init(struct mic_device *mdev)
|
||||||
{
|
{
|
||||||
struct mic_bootparam *bootparam = mdev->dp;
|
struct mic_bootparam *bootparam = mdev->dp;
|
||||||
|
|
||||||
bootparam->magic = MIC_MAGIC;
|
bootparam->magic = cpu_to_le32(MIC_MAGIC);
|
||||||
bootparam->c2h_shutdown_db = mdev->shutdown_db;
|
bootparam->c2h_shutdown_db = mdev->shutdown_db;
|
||||||
bootparam->h2c_shutdown_db = -1;
|
bootparam->h2c_shutdown_db = -1;
|
||||||
bootparam->h2c_config_db = -1;
|
bootparam->h2c_config_db = -1;
|
||||||
|
|
|
@ -41,7 +41,7 @@ static int mic_virtio_copy_to_user(struct mic_vdev *mvdev,
|
||||||
* We are copying from IO below an should ideally use something
|
* We are copying from IO below an should ideally use something
|
||||||
* like copy_to_user_fromio(..) if it existed.
|
* like copy_to_user_fromio(..) if it existed.
|
||||||
*/
|
*/
|
||||||
if (copy_to_user(ubuf, dbuf, len)) {
|
if (copy_to_user(ubuf, (void __force *)dbuf, len)) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
dev_err(mic_dev(mvdev), "%s %d err %d\n",
|
dev_err(mic_dev(mvdev), "%s %d err %d\n",
|
||||||
__func__, __LINE__, err);
|
__func__, __LINE__, err);
|
||||||
|
@ -66,7 +66,7 @@ static int mic_virtio_copy_from_user(struct mic_vdev *mvdev,
|
||||||
* We are copying to IO below and should ideally use something
|
* We are copying to IO below and should ideally use something
|
||||||
* like copy_from_user_toio(..) if it existed.
|
* like copy_from_user_toio(..) if it existed.
|
||||||
*/
|
*/
|
||||||
if (copy_from_user(dbuf, ubuf, len)) {
|
if (copy_from_user((void __force *)dbuf, ubuf, len)) {
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
dev_err(mic_dev(mvdev), "%s %d err %d\n",
|
dev_err(mic_dev(mvdev), "%s %d err %d\n",
|
||||||
__func__, __LINE__, err);
|
__func__, __LINE__, err);
|
||||||
|
@ -293,7 +293,7 @@ static void mic_virtio_init_post(struct mic_vdev *mvdev)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mvdev->mvr[i].vrh.vring.used =
|
mvdev->mvr[i].vrh.vring.used =
|
||||||
mvdev->mdev->aper.va +
|
(void __force *)mvdev->mdev->aper.va +
|
||||||
le64_to_cpu(vqconfig[i].used_address);
|
le64_to_cpu(vqconfig[i].used_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ int mic_virtio_config_change(struct mic_vdev *mvdev,
|
||||||
void __user *argp)
|
void __user *argp)
|
||||||
{
|
{
|
||||||
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
|
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
|
||||||
int ret = 0, retry = 100, i;
|
int ret = 0, retry, i;
|
||||||
struct mic_bootparam *bootparam = mvdev->mdev->dp;
|
struct mic_bootparam *bootparam = mvdev->mdev->dp;
|
||||||
s8 db = bootparam->h2c_config_db;
|
s8 db = bootparam->h2c_config_db;
|
||||||
|
|
||||||
|
@ -401,7 +401,7 @@ int mic_virtio_config_change(struct mic_vdev *mvdev,
|
||||||
mvdev->dc->config_change = MIC_VIRTIO_PARAM_CONFIG_CHANGED;
|
mvdev->dc->config_change = MIC_VIRTIO_PARAM_CONFIG_CHANGED;
|
||||||
mvdev->mdev->ops->send_intr(mvdev->mdev, db);
|
mvdev->mdev->ops->send_intr(mvdev->mdev, db);
|
||||||
|
|
||||||
for (i = retry; i--;) {
|
for (retry = 100; retry--;) {
|
||||||
ret = wait_event_timeout(wake,
|
ret = wait_event_timeout(wake,
|
||||||
mvdev->dc->guest_ack, msecs_to_jiffies(100));
|
mvdev->dc->guest_ack, msecs_to_jiffies(100));
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -467,7 +467,7 @@ static int mic_copy_dp_entry(struct mic_vdev *mvdev,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the first free device page entry */
|
/* Find the first free device page entry */
|
||||||
for (i = mic_aligned_size(struct mic_bootparam);
|
for (i = sizeof(struct mic_bootparam);
|
||||||
i < MIC_DP_SIZE - mic_total_desc_size(dd_config);
|
i < MIC_DP_SIZE - mic_total_desc_size(dd_config);
|
||||||
i += mic_total_desc_size(devp)) {
|
i += mic_total_desc_size(devp)) {
|
||||||
devp = mdev->dp + i;
|
devp = mdev->dp + i;
|
||||||
|
@ -525,6 +525,7 @@ int mic_virtio_add_device(struct mic_vdev *mvdev,
|
||||||
char irqname[10];
|
char irqname[10];
|
||||||
struct mic_bootparam *bootparam = mdev->dp;
|
struct mic_bootparam *bootparam = mdev->dp;
|
||||||
u16 num;
|
u16 num;
|
||||||
|
dma_addr_t vr_addr;
|
||||||
|
|
||||||
mutex_lock(&mdev->mic_mutex);
|
mutex_lock(&mdev->mic_mutex);
|
||||||
|
|
||||||
|
@ -559,17 +560,16 @@ int mic_virtio_add_device(struct mic_vdev *mvdev,
|
||||||
}
|
}
|
||||||
vr->len = vr_size;
|
vr->len = vr_size;
|
||||||
vr->info = vr->va + vring_size(num, MIC_VIRTIO_RING_ALIGN);
|
vr->info = vr->va + vring_size(num, MIC_VIRTIO_RING_ALIGN);
|
||||||
vr->info->magic = MIC_MAGIC + mvdev->virtio_id + i;
|
vr->info->magic = cpu_to_le32(MIC_MAGIC + mvdev->virtio_id + i);
|
||||||
vqconfig[i].address = mic_map_single(mdev,
|
vr_addr = mic_map_single(mdev, vr->va, vr_size);
|
||||||
vr->va, vr_size);
|
if (mic_map_error(vr_addr)) {
|
||||||
if (mic_map_error(vqconfig[i].address)) {
|
|
||||||
free_pages((unsigned long)vr->va, get_order(vr_size));
|
free_pages((unsigned long)vr->va, get_order(vr_size));
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
dev_err(mic_dev(mvdev), "%s %d err %d\n",
|
dev_err(mic_dev(mvdev), "%s %d err %d\n",
|
||||||
__func__, __LINE__, ret);
|
__func__, __LINE__, ret);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
vqconfig[i].address = cpu_to_le64(vqconfig[i].address);
|
vqconfig[i].address = cpu_to_le64(vr_addr);
|
||||||
|
|
||||||
vring_init(&vr->vr, num, vr->va, MIC_VIRTIO_RING_ALIGN);
|
vring_init(&vr->vr, num, vr->va, MIC_VIRTIO_RING_ALIGN);
|
||||||
ret = vringh_init_kern(&mvr->vrh,
|
ret = vringh_init_kern(&mvr->vrh,
|
||||||
|
@ -639,7 +639,7 @@ void mic_virtio_del_device(struct mic_vdev *mvdev)
|
||||||
struct mic_vdev *tmp_mvdev;
|
struct mic_vdev *tmp_mvdev;
|
||||||
struct mic_device *mdev = mvdev->mdev;
|
struct mic_device *mdev = mvdev->mdev;
|
||||||
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
|
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wake);
|
||||||
int i, ret, retry = 100;
|
int i, ret, retry;
|
||||||
struct mic_vqconfig *vqconfig;
|
struct mic_vqconfig *vqconfig;
|
||||||
struct mic_bootparam *bootparam = mdev->dp;
|
struct mic_bootparam *bootparam = mdev->dp;
|
||||||
s8 db;
|
s8 db;
|
||||||
|
@ -652,16 +652,16 @@ void mic_virtio_del_device(struct mic_vdev *mvdev)
|
||||||
"Requesting hot remove id %d\n", mvdev->virtio_id);
|
"Requesting hot remove id %d\n", mvdev->virtio_id);
|
||||||
mvdev->dc->config_change = MIC_VIRTIO_PARAM_DEV_REMOVE;
|
mvdev->dc->config_change = MIC_VIRTIO_PARAM_DEV_REMOVE;
|
||||||
mdev->ops->send_intr(mdev, db);
|
mdev->ops->send_intr(mdev, db);
|
||||||
for (i = retry; i--;) {
|
for (retry = 100; retry--;) {
|
||||||
ret = wait_event_timeout(wake,
|
ret = wait_event_timeout(wake,
|
||||||
mvdev->dc->guest_ack, msecs_to_jiffies(100));
|
mvdev->dc->guest_ack, msecs_to_jiffies(100));
|
||||||
if (ret)
|
if (ret)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dev_dbg(mdev->sdev->parent,
|
dev_dbg(mdev->sdev->parent,
|
||||||
"Device id %d config_change %d guest_ack %d\n",
|
"Device id %d config_change %d guest_ack %d retry %d\n",
|
||||||
mvdev->virtio_id, mvdev->dc->config_change,
|
mvdev->virtio_id, mvdev->dc->config_change,
|
||||||
mvdev->dc->guest_ack);
|
mvdev->dc->guest_ack, retry);
|
||||||
mvdev->dc->config_change = 0;
|
mvdev->dc->config_change = 0;
|
||||||
mvdev->dc->guest_ack = 0;
|
mvdev->dc->guest_ack = 0;
|
||||||
skip_hot_remove:
|
skip_hot_remove:
|
||||||
|
|
|
@ -397,8 +397,8 @@ mic_x100_load_ramdisk(struct mic_device *mdev)
|
||||||
* so copy over the ramdisk @ 128M.
|
* so copy over the ramdisk @ 128M.
|
||||||
*/
|
*/
|
||||||
memcpy_toio(mdev->aper.va + (mdev->bootaddr << 1), fw->data, fw->size);
|
memcpy_toio(mdev->aper.va + (mdev->bootaddr << 1), fw->data, fw->size);
|
||||||
iowrite32(cpu_to_le32(mdev->bootaddr << 1), &bp->hdr.ramdisk_image);
|
iowrite32(mdev->bootaddr << 1, &bp->hdr.ramdisk_image);
|
||||||
iowrite32(cpu_to_le32(fw->size), &bp->hdr.ramdisk_size);
|
iowrite32(fw->size, &bp->hdr.ramdisk_size);
|
||||||
release_firmware(fw);
|
release_firmware(fw);
|
||||||
error:
|
error:
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -23,12 +23,7 @@
|
||||||
|
|
||||||
#include <linux/virtio_ring.h>
|
#include <linux/virtio_ring.h>
|
||||||
|
|
||||||
#ifndef __KERNEL__
|
#define __mic_align(a, x) (((a) + (x) - 1) & ~((x) - 1))
|
||||||
#define ALIGN(a, x) (((a) + (x) - 1) & ~((x) - 1))
|
|
||||||
#define __aligned(x) __attribute__ ((aligned(x)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define mic_aligned_size(x) ALIGN(sizeof(x), 8)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct mic_device_desc: Virtio device information shared between the
|
* struct mic_device_desc: Virtio device information shared between the
|
||||||
|
@ -48,8 +43,8 @@ struct mic_device_desc {
|
||||||
__u8 feature_len;
|
__u8 feature_len;
|
||||||
__u8 config_len;
|
__u8 config_len;
|
||||||
__u8 status;
|
__u8 status;
|
||||||
__u64 config[0];
|
__le64 config[0];
|
||||||
} __aligned(8);
|
} __attribute__ ((aligned(8)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct mic_device_ctrl: Per virtio device information in the device page
|
* struct mic_device_ctrl: Per virtio device information in the device page
|
||||||
|
@ -66,7 +61,7 @@ struct mic_device_desc {
|
||||||
* @h2c_vdev_db: The doorbell number to be used by host. Set by guest.
|
* @h2c_vdev_db: The doorbell number to be used by host. Set by guest.
|
||||||
*/
|
*/
|
||||||
struct mic_device_ctrl {
|
struct mic_device_ctrl {
|
||||||
__u64 vdev;
|
__le64 vdev;
|
||||||
__u8 config_change;
|
__u8 config_change;
|
||||||
__u8 vdev_reset;
|
__u8 vdev_reset;
|
||||||
__u8 guest_ack;
|
__u8 guest_ack;
|
||||||
|
@ -74,7 +69,7 @@ struct mic_device_ctrl {
|
||||||
__u8 used_address_updated;
|
__u8 used_address_updated;
|
||||||
__s8 c2h_vdev_db;
|
__s8 c2h_vdev_db;
|
||||||
__s8 h2c_vdev_db;
|
__s8 h2c_vdev_db;
|
||||||
} __aligned(8);
|
} __attribute__ ((aligned(8)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct mic_bootparam: Virtio device independent information in device page
|
* struct mic_bootparam: Virtio device independent information in device page
|
||||||
|
@ -87,13 +82,13 @@ struct mic_device_ctrl {
|
||||||
* @shutdown_card: Set to 1 by the host when a card shutdown is initiated
|
* @shutdown_card: Set to 1 by the host when a card shutdown is initiated
|
||||||
*/
|
*/
|
||||||
struct mic_bootparam {
|
struct mic_bootparam {
|
||||||
__u32 magic;
|
__le32 magic;
|
||||||
__s8 c2h_shutdown_db;
|
__s8 c2h_shutdown_db;
|
||||||
__s8 h2c_shutdown_db;
|
__s8 h2c_shutdown_db;
|
||||||
__s8 h2c_config_db;
|
__s8 h2c_config_db;
|
||||||
__u8 shutdown_status;
|
__u8 shutdown_status;
|
||||||
__u8 shutdown_card;
|
__u8 shutdown_card;
|
||||||
} __aligned(8);
|
} __attribute__ ((aligned(8)));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct mic_device_page: High level representation of the device page
|
* struct mic_device_page: High level representation of the device page
|
||||||
|
@ -116,10 +111,10 @@ struct mic_device_page {
|
||||||
* @num: The number of entries in the virtio_ring
|
* @num: The number of entries in the virtio_ring
|
||||||
*/
|
*/
|
||||||
struct mic_vqconfig {
|
struct mic_vqconfig {
|
||||||
__u64 address;
|
__le64 address;
|
||||||
__u64 used_address;
|
__le64 used_address;
|
||||||
__u16 num;
|
__le16 num;
|
||||||
} __aligned(8);
|
} __attribute__ ((aligned(8)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The alignment to use between consumer and producer parts of vring.
|
* The alignment to use between consumer and producer parts of vring.
|
||||||
|
@ -154,7 +149,7 @@ struct mic_vqconfig {
|
||||||
*/
|
*/
|
||||||
struct _mic_vring_info {
|
struct _mic_vring_info {
|
||||||
__u16 avail_idx;
|
__u16 avail_idx;
|
||||||
int magic;
|
__le32 magic;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -173,15 +168,13 @@ struct mic_vring {
|
||||||
int len;
|
int len;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define mic_aligned_desc_size(d) ALIGN(mic_desc_size(d), 8)
|
#define mic_aligned_desc_size(d) __mic_align(mic_desc_size(d), 8)
|
||||||
|
|
||||||
#ifndef INTEL_MIC_CARD
|
#ifndef INTEL_MIC_CARD
|
||||||
static inline unsigned mic_desc_size(const struct mic_device_desc *desc)
|
static inline unsigned mic_desc_size(const struct mic_device_desc *desc)
|
||||||
{
|
{
|
||||||
return mic_aligned_size(*desc)
|
return sizeof(*desc) + desc->num_vq * sizeof(struct mic_vqconfig)
|
||||||
+ desc->num_vq * mic_aligned_size(struct mic_vqconfig)
|
+ desc->feature_len * 2 + desc->config_len;
|
||||||
+ desc->feature_len * 2
|
|
||||||
+ desc->config_len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct mic_vqconfig *
|
static inline struct mic_vqconfig *
|
||||||
|
@ -201,8 +194,7 @@ static inline __u8 *mic_vq_configspace(const struct mic_device_desc *desc)
|
||||||
}
|
}
|
||||||
static inline unsigned mic_total_desc_size(struct mic_device_desc *desc)
|
static inline unsigned mic_total_desc_size(struct mic_device_desc *desc)
|
||||||
{
|
{
|
||||||
return mic_aligned_desc_size(desc) +
|
return mic_aligned_desc_size(desc) + sizeof(struct mic_device_ctrl);
|
||||||
mic_aligned_size(struct mic_device_ctrl);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче