diff options
author | David S. Miller <davem@davemloft.net> | 2011-12-23 17:13:56 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-23 17:13:56 -0500 |
commit | abb434cb0539fb355c1c921f8fd761efbbac3462 (patch) | |
tree | 24a7d99ec161f8fd4dc9ff03c9c4cc93be883ce6 /drivers | |
parent | 2494654d4890316e7340fb8b3458daad0474a1b9 (diff) | |
parent | 6350323ad8def2ac00d77cdee3b79c9b9fba75c4 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
net/bluetooth/l2cap_core.c
Just two overlapping changes, one added an initialization of
a local variable, and another change added a new local variable.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
194 files changed, 3794 insertions, 2006 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 6bdedd7cca2c..cf047c406d92 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -820,7 +820,7 @@ config PATA_PLATFORM | |||
820 | 820 | ||
821 | config PATA_OF_PLATFORM | 821 | config PATA_OF_PLATFORM |
822 | tristate "OpenFirmware platform device PATA support" | 822 | tristate "OpenFirmware platform device PATA support" |
823 | depends on PATA_PLATFORM && OF | 823 | depends on PATA_PLATFORM && OF && OF_IRQ |
824 | help | 824 | help |
825 | This option enables support for generic directly connected ATA | 825 | This option enables support for generic directly connected ATA |
826 | devices commonly found on embedded systems with OpenFirmware | 826 | devices commonly found on embedded systems with OpenFirmware |
diff --git a/drivers/base/core.c b/drivers/base/core.c index d8b3d89db043..919daa7cd5b1 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -1743,8 +1743,10 @@ void device_shutdown(void) | |||
1743 | */ | 1743 | */ |
1744 | list_del_init(&dev->kobj.entry); | 1744 | list_del_init(&dev->kobj.entry); |
1745 | spin_unlock(&devices_kset->list_lock); | 1745 | spin_unlock(&devices_kset->list_lock); |
1746 | /* Disable all device's runtime power management */ | 1746 | |
1747 | pm_runtime_disable(dev); | 1747 | /* Don't allow any more runtime suspends */ |
1748 | pm_runtime_get_noresume(dev); | ||
1749 | pm_runtime_barrier(dev); | ||
1748 | 1750 | ||
1749 | if (dev->bus && dev->bus->shutdown) { | 1751 | if (dev->bus && dev->bus->shutdown) { |
1750 | dev_dbg(dev, "shutdown\n"); | 1752 | dev_dbg(dev, "shutdown\n"); |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 8004ac30a7a8..587cce57adae 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -2601,6 +2601,8 @@ static int fill_cmd(ctlr_info_t *h, CommandList_struct *c, __u8 cmd, void *buff, | |||
2601 | c->Request.Timeout = 0; | 2601 | c->Request.Timeout = 0; |
2602 | c->Request.CDB[0] = BMIC_WRITE; | 2602 | c->Request.CDB[0] = BMIC_WRITE; |
2603 | c->Request.CDB[6] = BMIC_CACHE_FLUSH; | 2603 | c->Request.CDB[6] = BMIC_CACHE_FLUSH; |
2604 | c->Request.CDB[7] = (size >> 8) & 0xFF; | ||
2605 | c->Request.CDB[8] = size & 0xFF; | ||
2604 | break; | 2606 | break; |
2605 | case TEST_UNIT_READY: | 2607 | case TEST_UNIT_READY: |
2606 | c->Request.CDBLen = 6; | 2608 | c->Request.CDBLen = 6; |
@@ -4880,7 +4882,7 @@ static int cciss_request_irq(ctlr_info_t *h, | |||
4880 | { | 4882 | { |
4881 | if (h->msix_vector || h->msi_vector) { | 4883 | if (h->msix_vector || h->msi_vector) { |
4882 | if (!request_irq(h->intr[h->intr_mode], msixhandler, | 4884 | if (!request_irq(h->intr[h->intr_mode], msixhandler, |
4883 | IRQF_DISABLED, h->devname, h)) | 4885 | 0, h->devname, h)) |
4884 | return 0; | 4886 | return 0; |
4885 | dev_err(&h->pdev->dev, "Unable to get msi irq %d" | 4887 | dev_err(&h->pdev->dev, "Unable to get msi irq %d" |
4886 | " for %s\n", h->intr[h->intr_mode], | 4888 | " for %s\n", h->intr[h->intr_mode], |
@@ -4889,7 +4891,7 @@ static int cciss_request_irq(ctlr_info_t *h, | |||
4889 | } | 4891 | } |
4890 | 4892 | ||
4891 | if (!request_irq(h->intr[h->intr_mode], intxhandler, | 4893 | if (!request_irq(h->intr[h->intr_mode], intxhandler, |
4892 | IRQF_DISABLED, h->devname, h)) | 4894 | IRQF_SHARED, h->devname, h)) |
4893 | return 0; | 4895 | return 0; |
4894 | dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n", | 4896 | dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n", |
4895 | h->intr[h->intr_mode], h->devname); | 4897 | h->intr[h->intr_mode], h->devname); |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 68b205a9338f..1e888c9e85b3 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -422,7 +422,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) | |||
422 | 422 | ||
423 | /* | 423 | /* |
424 | * We use punch hole to reclaim the free space used by the | 424 | * We use punch hole to reclaim the free space used by the |
425 | * image a.k.a. discard. However we do support discard if | 425 | * image a.k.a. discard. However we do not support discard if |
426 | * encryption is enabled, because it may give an attacker | 426 | * encryption is enabled, because it may give an attacker |
427 | * useful information. | 427 | * useful information. |
428 | */ | 428 | */ |
@@ -797,7 +797,7 @@ static void loop_config_discard(struct loop_device *lo) | |||
797 | } | 797 | } |
798 | 798 | ||
799 | q->limits.discard_granularity = inode->i_sb->s_blocksize; | 799 | q->limits.discard_granularity = inode->i_sb->s_blocksize; |
800 | q->limits.discard_alignment = inode->i_sb->s_blocksize; | 800 | q->limits.discard_alignment = 0; |
801 | q->limits.max_discard_sectors = UINT_MAX >> 9; | 801 | q->limits.max_discard_sectors = UINT_MAX >> 9; |
802 | q->limits.discard_zeroes_data = 1; | 802 | q->limits.discard_zeroes_data = 1; |
803 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); | 803 | queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 65cc424359b0..148ab944378d 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -183,10 +183,6 @@ static LIST_HEAD(rbd_client_list); /* clients */ | |||
183 | 183 | ||
184 | static int __rbd_init_snaps_header(struct rbd_device *rbd_dev); | 184 | static int __rbd_init_snaps_header(struct rbd_device *rbd_dev); |
185 | static void rbd_dev_release(struct device *dev); | 185 | static void rbd_dev_release(struct device *dev); |
186 | static ssize_t rbd_snap_rollback(struct device *dev, | ||
187 | struct device_attribute *attr, | ||
188 | const char *buf, | ||
189 | size_t size); | ||
190 | static ssize_t rbd_snap_add(struct device *dev, | 186 | static ssize_t rbd_snap_add(struct device *dev, |
191 | struct device_attribute *attr, | 187 | struct device_attribute *attr, |
192 | const char *buf, | 188 | const char *buf, |
@@ -461,6 +457,10 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
461 | u32 snap_count = le32_to_cpu(ondisk->snap_count); | 457 | u32 snap_count = le32_to_cpu(ondisk->snap_count); |
462 | int ret = -ENOMEM; | 458 | int ret = -ENOMEM; |
463 | 459 | ||
460 | if (memcmp(ondisk, RBD_HEADER_TEXT, sizeof(RBD_HEADER_TEXT))) { | ||
461 | return -ENXIO; | ||
462 | } | ||
463 | |||
464 | init_rwsem(&header->snap_rwsem); | 464 | init_rwsem(&header->snap_rwsem); |
465 | header->snap_names_len = le64_to_cpu(ondisk->snap_names_len); | 465 | header->snap_names_len = le64_to_cpu(ondisk->snap_names_len); |
466 | header->snapc = kmalloc(sizeof(struct ceph_snap_context) + | 466 | header->snapc = kmalloc(sizeof(struct ceph_snap_context) + |
@@ -1356,32 +1356,6 @@ fail: | |||
1356 | } | 1356 | } |
1357 | 1357 | ||
1358 | /* | 1358 | /* |
1359 | * Request sync osd rollback | ||
1360 | */ | ||
1361 | static int rbd_req_sync_rollback_obj(struct rbd_device *dev, | ||
1362 | u64 snapid, | ||
1363 | const char *obj) | ||
1364 | { | ||
1365 | struct ceph_osd_req_op *ops; | ||
1366 | int ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_ROLLBACK, 0); | ||
1367 | if (ret < 0) | ||
1368 | return ret; | ||
1369 | |||
1370 | ops[0].snap.snapid = snapid; | ||
1371 | |||
1372 | ret = rbd_req_sync_op(dev, NULL, | ||
1373 | CEPH_NOSNAP, | ||
1374 | 0, | ||
1375 | CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, | ||
1376 | ops, | ||
1377 | 1, obj, 0, 0, NULL, NULL, NULL); | ||
1378 | |||
1379 | rbd_destroy_ops(ops); | ||
1380 | |||
1381 | return ret; | ||
1382 | } | ||
1383 | |||
1384 | /* | ||
1385 | * Request sync osd read | 1359 | * Request sync osd read |
1386 | */ | 1360 | */ |
1387 | static int rbd_req_sync_exec(struct rbd_device *dev, | 1361 | static int rbd_req_sync_exec(struct rbd_device *dev, |
@@ -1610,8 +1584,13 @@ static int rbd_read_header(struct rbd_device *rbd_dev, | |||
1610 | goto out_dh; | 1584 | goto out_dh; |
1611 | 1585 | ||
1612 | rc = rbd_header_from_disk(header, dh, snap_count, GFP_KERNEL); | 1586 | rc = rbd_header_from_disk(header, dh, snap_count, GFP_KERNEL); |
1613 | if (rc < 0) | 1587 | if (rc < 0) { |
1588 | if (rc == -ENXIO) { | ||
1589 | pr_warning("unrecognized header format" | ||
1590 | " for image %s", rbd_dev->obj); | ||
1591 | } | ||
1614 | goto out_dh; | 1592 | goto out_dh; |
1593 | } | ||
1615 | 1594 | ||
1616 | if (snap_count != header->total_snaps) { | 1595 | if (snap_count != header->total_snaps) { |
1617 | snap_count = header->total_snaps; | 1596 | snap_count = header->total_snaps; |
@@ -1882,7 +1861,6 @@ static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL); | |||
1882 | static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh); | 1861 | static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh); |
1883 | static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL); | 1862 | static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL); |
1884 | static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add); | 1863 | static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add); |
1885 | static DEVICE_ATTR(rollback_snap, S_IWUSR, NULL, rbd_snap_rollback); | ||
1886 | 1864 | ||
1887 | static struct attribute *rbd_attrs[] = { | 1865 | static struct attribute *rbd_attrs[] = { |
1888 | &dev_attr_size.attr, | 1866 | &dev_attr_size.attr, |
@@ -1893,7 +1871,6 @@ static struct attribute *rbd_attrs[] = { | |||
1893 | &dev_attr_current_snap.attr, | 1871 | &dev_attr_current_snap.attr, |
1894 | &dev_attr_refresh.attr, | 1872 | &dev_attr_refresh.attr, |
1895 | &dev_attr_create_snap.attr, | 1873 | &dev_attr_create_snap.attr, |
1896 | &dev_attr_rollback_snap.attr, | ||
1897 | NULL | 1874 | NULL |
1898 | }; | 1875 | }; |
1899 | 1876 | ||
@@ -2424,64 +2401,6 @@ err_unlock: | |||
2424 | return ret; | 2401 | return ret; |
2425 | } | 2402 | } |
2426 | 2403 | ||
2427 | static ssize_t rbd_snap_rollback(struct device *dev, | ||
2428 | struct device_attribute *attr, | ||
2429 | const char *buf, | ||
2430 | size_t count) | ||
2431 | { | ||
2432 | struct rbd_device *rbd_dev = dev_to_rbd(dev); | ||
2433 | int ret; | ||
2434 | u64 snapid; | ||
2435 | u64 cur_ofs; | ||
2436 | char *seg_name = NULL; | ||
2437 | char *snap_name = kmalloc(count + 1, GFP_KERNEL); | ||
2438 | ret = -ENOMEM; | ||
2439 | if (!snap_name) | ||
2440 | return ret; | ||
2441 | |||
2442 | /* parse snaps add command */ | ||
2443 | snprintf(snap_name, count, "%s", buf); | ||
2444 | seg_name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO); | ||
2445 | if (!seg_name) | ||
2446 | goto done; | ||
2447 | |||
2448 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | ||
2449 | |||
2450 | ret = snap_by_name(&rbd_dev->header, snap_name, &snapid, NULL); | ||
2451 | if (ret < 0) | ||
2452 | goto done_unlock; | ||
2453 | |||
2454 | dout("snapid=%lld\n", snapid); | ||
2455 | |||
2456 | cur_ofs = 0; | ||
2457 | while (cur_ofs < rbd_dev->header.image_size) { | ||
2458 | cur_ofs += rbd_get_segment(&rbd_dev->header, | ||
2459 | rbd_dev->obj, | ||
2460 | cur_ofs, (u64)-1, | ||
2461 | seg_name, NULL); | ||
2462 | dout("seg_name=%s\n", seg_name); | ||
2463 | |||
2464 | ret = rbd_req_sync_rollback_obj(rbd_dev, snapid, seg_name); | ||
2465 | if (ret < 0) | ||
2466 | pr_warning("could not roll back obj %s err=%d\n", | ||
2467 | seg_name, ret); | ||
2468 | } | ||
2469 | |||
2470 | ret = __rbd_update_snaps(rbd_dev); | ||
2471 | if (ret < 0) | ||
2472 | goto done_unlock; | ||
2473 | |||
2474 | ret = count; | ||
2475 | |||
2476 | done_unlock: | ||
2477 | mutex_unlock(&ctl_mutex); | ||
2478 | done: | ||
2479 | kfree(seg_name); | ||
2480 | kfree(snap_name); | ||
2481 | |||
2482 | return ret; | ||
2483 | } | ||
2484 | |||
2485 | static struct bus_attribute rbd_bus_attrs[] = { | 2404 | static struct bus_attribute rbd_bus_attrs[] = { |
2486 | __ATTR(add, S_IWUSR, NULL, rbd_add), | 2405 | __ATTR(add, S_IWUSR, NULL, rbd_add), |
2487 | __ATTR(remove, S_IWUSR, NULL, rbd_remove), | 2406 | __ATTR(remove, S_IWUSR, NULL, rbd_remove), |
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index ae3e167e17ad..89ddab127e33 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c | |||
@@ -16,6 +16,8 @@ | |||
16 | * handle GCR disks | 16 | * handle GCR disks |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #undef DEBUG | ||
20 | |||
19 | #include <linux/stddef.h> | 21 | #include <linux/stddef.h> |
20 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
21 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
@@ -36,13 +38,11 @@ | |||
36 | #include <asm/machdep.h> | 38 | #include <asm/machdep.h> |
37 | #include <asm/pmac_feature.h> | 39 | #include <asm/pmac_feature.h> |
38 | 40 | ||
39 | static DEFINE_MUTEX(swim3_mutex); | ||
40 | static struct request_queue *swim3_queue; | ||
41 | static struct gendisk *disks[2]; | ||
42 | static struct request *fd_req; | ||
43 | |||
44 | #define MAX_FLOPPIES 2 | 41 | #define MAX_FLOPPIES 2 |
45 | 42 | ||
43 | static DEFINE_MUTEX(swim3_mutex); | ||
44 | static struct gendisk *disks[MAX_FLOPPIES]; | ||
45 | |||
46 | enum swim_state { | 46 | enum swim_state { |
47 | idle, | 47 | idle, |
48 | locating, | 48 | locating, |
@@ -177,7 +177,6 @@ struct swim3 { | |||
177 | 177 | ||
178 | struct floppy_state { | 178 | struct floppy_state { |
179 | enum swim_state state; | 179 | enum swim_state state; |
180 | spinlock_t lock; | ||
181 | struct swim3 __iomem *swim3; /* hardware registers */ | 180 | struct swim3 __iomem *swim3; /* hardware registers */ |
182 | struct dbdma_regs __iomem *dma; /* DMA controller registers */ | 181 | struct dbdma_regs __iomem *dma; /* DMA controller registers */ |
183 | int swim3_intr; /* interrupt number for SWIM3 */ | 182 | int swim3_intr; /* interrupt number for SWIM3 */ |
@@ -204,8 +203,20 @@ struct floppy_state { | |||
204 | int wanted; | 203 | int wanted; |
205 | struct macio_dev *mdev; | 204 | struct macio_dev *mdev; |
206 | char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)]; | 205 | char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)]; |
206 | int index; | ||
207 | struct request *cur_req; | ||
207 | }; | 208 | }; |
208 | 209 | ||
210 | #define swim3_err(fmt, arg...) dev_err(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg) | ||
211 | #define swim3_warn(fmt, arg...) dev_warn(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg) | ||
212 | #define swim3_info(fmt, arg...) dev_info(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg) | ||
213 | |||
214 | #ifdef DEBUG | ||
215 | #define swim3_dbg(fmt, arg...) dev_dbg(&fs->mdev->ofdev.dev, "[fd%d] " fmt, fs->index, arg) | ||
216 | #else | ||
217 | #define swim3_dbg(fmt, arg...) do { } while(0) | ||
218 | #endif | ||
219 | |||
209 | static struct floppy_state floppy_states[MAX_FLOPPIES]; | 220 | static struct floppy_state floppy_states[MAX_FLOPPIES]; |
210 | static int floppy_count = 0; | 221 | static int floppy_count = 0; |
211 | static DEFINE_SPINLOCK(swim3_lock); | 222 | static DEFINE_SPINLOCK(swim3_lock); |
@@ -224,17 +235,8 @@ static unsigned short write_postamble[] = { | |||
224 | 0, 0, 0, 0, 0, 0 | 235 | 0, 0, 0, 0, 0, 0 |
225 | }; | 236 | }; |
226 | 237 | ||
227 | static void swim3_select(struct floppy_state *fs, int sel); | ||
228 | static void swim3_action(struct floppy_state *fs, int action); | ||
229 | static int swim3_readbit(struct floppy_state *fs, int bit); | ||
230 | static void do_fd_request(struct request_queue * q); | ||
231 | static void start_request(struct floppy_state *fs); | ||
232 | static void set_timeout(struct floppy_state *fs, int nticks, | ||
233 | void (*proc)(unsigned long)); | ||
234 | static void scan_track(struct floppy_state *fs); | ||
235 | static void seek_track(struct floppy_state *fs, int n); | 238 | static void seek_track(struct floppy_state *fs, int n); |
236 | static void init_dma(struct dbdma_cmd *cp, int cmd, void *buf, int count); | 239 | static void init_dma(struct dbdma_cmd *cp, int cmd, void *buf, int count); |
237 | static void setup_transfer(struct floppy_state *fs); | ||
238 | static void act(struct floppy_state *fs); | 240 | static void act(struct floppy_state *fs); |
239 | static void scan_timeout(unsigned long data); | 241 | static void scan_timeout(unsigned long data); |
240 | static void seek_timeout(unsigned long data); | 242 | static void seek_timeout(unsigned long data); |
@@ -254,18 +256,21 @@ static unsigned int floppy_check_events(struct gendisk *disk, | |||
254 | unsigned int clearing); | 256 | unsigned int clearing); |
255 | static int floppy_revalidate(struct gendisk *disk); | 257 | static int floppy_revalidate(struct gendisk *disk); |
256 | 258 | ||
257 | static bool swim3_end_request(int err, unsigned int nr_bytes) | 259 | static bool swim3_end_request(struct floppy_state *fs, int err, unsigned int nr_bytes) |
258 | { | 260 | { |
259 | if (__blk_end_request(fd_req, err, nr_bytes)) | 261 | struct request *req = fs->cur_req; |
260 | return true; | 262 | int rc; |
261 | 263 | ||
262 | fd_req = NULL; | 264 | swim3_dbg(" end request, err=%d nr_bytes=%d, cur_req=%p\n", |
263 | return false; | 265 | err, nr_bytes, req); |
264 | } | ||
265 | 266 | ||
266 | static bool swim3_end_request_cur(int err) | 267 | if (err) |
267 | { | 268 | nr_bytes = blk_rq_cur_bytes(req); |
268 | return swim3_end_request(err, blk_rq_cur_bytes(fd_req)); | 269 | rc = __blk_end_request(req, err, nr_bytes); |
270 | if (rc) | ||
271 | return true; | ||
272 | fs->cur_req = NULL; | ||
273 | return false; | ||
269 | } | 274 | } |
270 | 275 | ||
271 | static void swim3_select(struct floppy_state *fs, int sel) | 276 | static void swim3_select(struct floppy_state *fs, int sel) |
@@ -303,50 +308,53 @@ static int swim3_readbit(struct floppy_state *fs, int bit) | |||
303 | return (stat & DATA) == 0; | 308 | return (stat & DATA) == 0; |
304 | } | 309 | } |
305 | 310 | ||
306 | static void do_fd_request(struct request_queue * q) | ||
307 | { | ||
308 | int i; | ||
309 | |||
310 | for(i=0; i<floppy_count; i++) { | ||
311 | struct floppy_state *fs = &floppy_states[i]; | ||
312 | if (fs->mdev->media_bay && | ||
313 | check_media_bay(fs->mdev->media_bay) != MB_FD) | ||
314 | continue; | ||
315 | start_request(fs); | ||
316 | } | ||
317 | } | ||
318 | |||
319 | static void start_request(struct floppy_state *fs) | 311 | static void start_request(struct floppy_state *fs) |
320 | { | 312 | { |
321 | struct request *req; | 313 | struct request *req; |
322 | unsigned long x; | 314 | unsigned long x; |
323 | 315 | ||
316 | swim3_dbg("start request, initial state=%d\n", fs->state); | ||
317 | |||
324 | if (fs->state == idle && fs->wanted) { | 318 | if (fs->state == idle && fs->wanted) { |
325 | fs->state = available; | 319 | fs->state = available; |
326 | wake_up(&fs->wait); | 320 | wake_up(&fs->wait); |
327 | return; | 321 | return; |
328 | } | 322 | } |
329 | while (fs->state == idle) { | 323 | while (fs->state == idle) { |
330 | if (!fd_req) { | 324 | swim3_dbg("start request, idle loop, cur_req=%p\n", fs->cur_req); |
331 | fd_req = blk_fetch_request(swim3_queue); | 325 | if (!fs->cur_req) { |
332 | if (!fd_req) | 326 | fs->cur_req = blk_fetch_request(disks[fs->index]->queue); |
327 | swim3_dbg(" fetched request %p\n", fs->cur_req); | ||
328 | if (!fs->cur_req) | ||
333 | break; | 329 | break; |
334 | } | 330 | } |
335 | req = fd_req; | 331 | req = fs->cur_req; |
336 | #if 0 | 332 | |
337 | printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%u buf=%p\n", | 333 | if (fs->mdev->media_bay && |
338 | req->rq_disk->disk_name, req->cmd, | 334 | check_media_bay(fs->mdev->media_bay) != MB_FD) { |
339 | (long)blk_rq_pos(req), blk_rq_sectors(req), req->buffer); | 335 | swim3_dbg("%s", " media bay absent, dropping req\n"); |
340 | printk(" errors=%d current_nr_sectors=%u\n", | 336 | swim3_end_request(fs, -ENODEV, 0); |
341 | req->errors, blk_rq_cur_sectors(req)); | 337 | continue; |
338 | } | ||
339 | |||
340 | #if 0 /* This is really too verbose */ | ||
341 | swim3_dbg("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%u buf=%p\n", | ||
342 | req->rq_disk->disk_name, req->cmd, | ||
343 | (long)blk_rq_pos(req), blk_rq_sectors(req), | ||
344 | req->buffer); | ||
345 | swim3_dbg(" errors=%d current_nr_sectors=%u\n", | ||
346 | req->errors, blk_rq_cur_sectors(req)); | ||
342 | #endif | 347 | #endif |
343 | 348 | ||
344 | if (blk_rq_pos(req) >= fs->total_secs) { | 349 | if (blk_rq_pos(req) >= fs->total_secs) { |
345 | swim3_end_request_cur(-EIO); | 350 | swim3_dbg(" pos out of bounds (%ld, max is %ld)\n", |
351 | (long)blk_rq_pos(req), (long)fs->total_secs); | ||
352 | swim3_end_request(fs, -EIO, 0); | ||
346 | continue; | 353 | continue; |
347 | } | 354 | } |
348 | if (fs->ejected) { | 355 | if (fs->ejected) { |
349 | swim3_end_request_cur(-EIO); | 356 | swim3_dbg("%s", " disk ejected\n"); |
357 | swim3_end_request(fs, -EIO, 0); | ||
350 | continue; | 358 | continue; |
351 | } | 359 | } |
352 | 360 | ||
@@ -354,7 +362,8 @@ static void start_request(struct floppy_state *fs) | |||
354 | if (fs->write_prot < 0) | 362 | if (fs->write_prot < 0) |
355 | fs->write_prot = swim3_readbit(fs, WRITE_PROT); | 363 | fs->write_prot = swim3_readbit(fs, WRITE_PROT); |
356 | if (fs->write_prot) { | 364 | if (fs->write_prot) { |
357 | swim3_end_request_cur(-EIO); | 365 | swim3_dbg("%s", " try to write, disk write protected\n"); |
366 | swim3_end_request(fs, -EIO, 0); | ||
358 | continue; | 367 | continue; |
359 | } | 368 | } |
360 | } | 369 | } |
@@ -369,7 +378,6 @@ static void start_request(struct floppy_state *fs) | |||
369 | x = ((long)blk_rq_pos(req)) % fs->secpercyl; | 378 | x = ((long)blk_rq_pos(req)) % fs->secpercyl; |
370 | fs->head = x / fs->secpertrack; | 379 | fs->head = x / fs->secpertrack; |
371 | fs->req_sector = x % fs->secpertrack + 1; | 380 | fs->req_sector = x % fs->secpertrack + 1; |
372 | fd_req = req; | ||
373 | fs->state = do_transfer; | 381 | fs->state = do_transfer; |
374 | fs->retries = 0; | 382 | fs->retries = 0; |
375 | 383 | ||
@@ -377,12 +385,14 @@ static void start_request(struct floppy_state *fs) | |||
377 | } | 385 | } |
378 | } | 386 | } |
379 | 387 | ||
388 | static void do_fd_request(struct request_queue * q) | ||
389 | { | ||
390 | start_request(q->queuedata); | ||
391 | } | ||
392 | |||
380 | static void set_timeout(struct floppy_state *fs, int nticks, | 393 | static void set_timeout(struct floppy_state *fs, int nticks, |
381 | void (*proc)(unsigned long)) | 394 | void (*proc)(unsigned long)) |
382 | { | 395 | { |
383 | unsigned long flags; | ||
384 | |||
385 | spin_lock_irqsave(&fs->lock, flags); | ||
386 | if (fs->timeout_pending) | 396 | if (fs->timeout_pending) |
387 | del_timer(&fs->timeout); | 397 | del_timer(&fs->timeout); |
388 | fs->timeout.expires = jiffies + nticks; | 398 | fs->timeout.expires = jiffies + nticks; |
@@ -390,7 +400,6 @@ static void set_timeout(struct floppy_state *fs, int nticks, | |||
390 | fs->timeout.data = (unsigned long) fs; | 400 | fs->timeout.data = (unsigned long) fs; |
391 | add_timer(&fs->timeout); | 401 | add_timer(&fs->timeout); |
392 | fs->timeout_pending = 1; | 402 | fs->timeout_pending = 1; |
393 | spin_unlock_irqrestore(&fs->lock, flags); | ||
394 | } | 403 | } |
395 | 404 | ||
396 | static inline void scan_track(struct floppy_state *fs) | 405 | static inline void scan_track(struct floppy_state *fs) |
@@ -442,40 +451,45 @@ static inline void setup_transfer(struct floppy_state *fs) | |||
442 | struct swim3 __iomem *sw = fs->swim3; | 451 | struct swim3 __iomem *sw = fs->swim3; |
443 | struct dbdma_cmd *cp = fs->dma_cmd; | 452 | struct dbdma_cmd *cp = fs->dma_cmd; |
444 | struct dbdma_regs __iomem *dr = fs->dma; | 453 | struct dbdma_regs __iomem *dr = fs->dma; |
454 | struct request *req = fs->cur_req; | ||
445 | 455 | ||
446 | if (blk_rq_cur_sectors(fd_req) <= 0) { | 456 | if (blk_rq_cur_sectors(req) <= 0) { |
447 | printk(KERN_ERR "swim3: transfer 0 sectors?\n"); | 457 | swim3_warn("%s", "Transfer 0 sectors ?\n"); |
448 | return; | 458 | return; |
449 | } | 459 | } |
450 | if (rq_data_dir(fd_req) == WRITE) | 460 | if (rq_data_dir(req) == WRITE) |
451 | n = 1; | 461 | n = 1; |
452 | else { | 462 | else { |
453 | n = fs->secpertrack - fs->req_sector + 1; | 463 | n = fs->secpertrack - fs->req_sector + 1; |
454 | if (n > blk_rq_cur_sectors(fd_req)) | 464 | if (n > blk_rq_cur_sectors(req)) |
455 | n = blk_rq_cur_sectors(fd_req); | 465 | n = blk_rq_cur_sectors(req); |
456 | } | 466 | } |
467 | |||
468 | swim3_dbg(" setup xfer at sect %d (of %d) head %d for %d\n", | ||
469 | fs->req_sector, fs->secpertrack, fs->head, n); | ||
470 | |||
457 | fs->scount = n; | 471 | fs->scount = n; |
458 | swim3_select(fs, fs->head? READ_DATA_1: READ_DATA_0); | 472 | swim3_select(fs, fs->head? READ_DATA_1: READ_DATA_0); |
459 | out_8(&sw->sector, fs->req_sector); | 473 | out_8(&sw->sector, fs->req_sector); |
460 | out_8(&sw->nsect, n); | 474 | out_8(&sw->nsect, n); |
461 | out_8(&sw->gap3, 0); | 475 | out_8(&sw->gap3, 0); |
462 | out_le32(&dr->cmdptr, virt_to_bus(cp)); | 476 | out_le32(&dr->cmdptr, virt_to_bus(cp)); |
463 | if (rq_data_dir(fd_req) == WRITE) { | 477 | if (rq_data_dir(req) == WRITE) { |
464 | /* Set up 3 dma commands: write preamble, data, postamble */ | 478 | /* Set up 3 dma commands: write preamble, data, postamble */ |
465 | init_dma(cp, OUTPUT_MORE, write_preamble, sizeof(write_preamble)); | 479 | init_dma(cp, OUTPUT_MORE, write_preamble, sizeof(write_preamble)); |
466 | ++cp; | 480 | ++cp; |
467 | init_dma(cp, OUTPUT_MORE, fd_req->buffer, 512); | 481 | init_dma(cp, OUTPUT_MORE, req->buffer, 512); |
468 | ++cp; | 482 | ++cp; |
469 | init_dma(cp, OUTPUT_LAST, write_postamble, sizeof(write_postamble)); | 483 | init_dma(cp, OUTPUT_LAST, write_postamble, sizeof(write_postamble)); |
470 | } else { | 484 | } else { |
471 | init_dma(cp, INPUT_LAST, fd_req->buffer, n * 512); | 485 | init_dma(cp, INPUT_LAST, req->buffer, n * 512); |
472 | } | 486 | } |
473 | ++cp; | 487 | ++cp; |
474 | out_le16(&cp->command, DBDMA_STOP); | 488 | out_le16(&cp->command, DBDMA_STOP); |
475 | out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); | 489 | out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); |
476 | in_8(&sw->error); | 490 | in_8(&sw->error); |
477 | out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); | 491 | out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); |
478 | if (rq_data_dir(fd_req) == WRITE) | 492 | if (rq_data_dir(req) == WRITE) |
479 | out_8(&sw->control_bis, WRITE_SECTORS); | 493 | out_8(&sw->control_bis, WRITE_SECTORS); |
480 | in_8(&sw->intr); | 494 | in_8(&sw->intr); |
481 | out_le32(&dr->control, (RUN << 16) | RUN); | 495 | out_le32(&dr->control, (RUN << 16) | RUN); |
@@ -488,12 +502,16 @@ static inline void setup_transfer(struct floppy_state *fs) | |||
488 | static void act(struct floppy_state *fs) | 502 | static void act(struct floppy_state *fs) |
489 | { | 503 | { |
490 | for (;;) { | 504 | for (;;) { |
505 | swim3_dbg(" act loop, state=%d, req_cyl=%d, cur_cyl=%d\n", | ||
506 | fs->state, fs->req_cyl, fs->cur_cyl); | ||
507 | |||
491 | switch (fs->state) { | 508 | switch (fs->state) { |
492 | case idle: | 509 | case idle: |
493 | return; /* XXX shouldn't get here */ | 510 | return; /* XXX shouldn't get here */ |
494 | 511 | ||
495 | case locating: | 512 | case locating: |
496 | if (swim3_readbit(fs, TRACK_ZERO)) { | 513 | if (swim3_readbit(fs, TRACK_ZERO)) { |
514 | swim3_dbg("%s", " locate track 0\n"); | ||
497 | fs->cur_cyl = 0; | 515 | fs->cur_cyl = 0; |
498 | if (fs->req_cyl == 0) | 516 | if (fs->req_cyl == 0) |
499 | fs->state = do_transfer; | 517 | fs->state = do_transfer; |
@@ -511,7 +529,7 @@ static void act(struct floppy_state *fs) | |||
511 | break; | 529 | break; |
512 | } | 530 | } |
513 | if (fs->req_cyl == fs->cur_cyl) { | 531 | if (fs->req_cyl == fs->cur_cyl) { |
514 | printk("whoops, seeking 0\n"); | 532 | swim3_warn("%s", "Whoops, seeking 0\n"); |
515 | fs->state = do_transfer; | 533 | fs->state = do_transfer; |
516 | break; | 534 | break; |
517 | } | 535 | } |
@@ -527,7 +545,9 @@ static void act(struct floppy_state *fs) | |||
527 | case do_transfer: | 545 | case do_transfer: |
528 | if (fs->cur_cyl != fs->req_cyl) { | 546 | if (fs->cur_cyl != fs->req_cyl) { |
529 | if (fs->retries > 5) { | 547 | if (fs->retries > 5) { |
530 | swim3_end_request_cur(-EIO); | 548 | swim3_err("Wrong cylinder in transfer, want: %d got %d\n", |
549 | fs->req_cyl, fs->cur_cyl); | ||
550 | swim3_end_request(fs, -EIO, 0); | ||
531 | fs->state = idle; | 551 | fs->state = idle; |
532 | return; | 552 | return; |
533 | } | 553 | } |
@@ -542,7 +562,7 @@ static void act(struct floppy_state *fs) | |||
542 | return; | 562 | return; |
543 | 563 | ||
544 | default: | 564 | default: |
545 | printk(KERN_ERR"swim3: unknown state %d\n", fs->state); | 565 | swim3_err("Unknown state %d\n", fs->state); |
546 | return; | 566 | return; |
547 | } | 567 | } |
548 | } | 568 | } |
@@ -552,59 +572,75 @@ static void scan_timeout(unsigned long data) | |||
552 | { | 572 | { |
553 | struct floppy_state *fs = (struct floppy_state *) data; | 573 | struct floppy_state *fs = (struct floppy_state *) data; |
554 | struct swim3 __iomem *sw = fs->swim3; | 574 | struct swim3 __iomem *sw = fs->swim3; |
575 | unsigned long flags; | ||
576 | |||
577 | swim3_dbg("* scan timeout, state=%d\n", fs->state); | ||
555 | 578 | ||
579 | spin_lock_irqsave(&swim3_lock, flags); | ||
556 | fs->timeout_pending = 0; | 580 | fs->timeout_pending = 0; |
557 | out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); | 581 | out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS); |
558 | out_8(&sw->select, RELAX); | 582 | out_8(&sw->select, RELAX); |
559 | out_8(&sw->intr_enable, 0); | 583 | out_8(&sw->intr_enable, 0); |
560 | fs->cur_cyl = -1; | 584 | fs->cur_cyl = -1; |
561 | if (fs->retries > 5) { | 585 | if (fs->retries > 5) { |
562 | swim3_end_request_cur(-EIO); | 586 | swim3_end_request(fs, -EIO, 0); |
563 | fs->state = idle; | 587 | fs->state = idle; |
564 | start_request(fs); | 588 | start_request(fs); |
565 | } else { | 589 | } else { |
566 | fs->state = jogging; | 590 | fs->state = jogging; |
567 | act(fs); | 591 | act(fs); |
568 | } | 592 | } |
593 | spin_unlock_irqrestore(&swim3_lock, flags); | ||
569 | } | 594 | } |
570 | 595 | ||
571 | static void seek_timeout(unsigned long data) | 596 | static void seek_timeout(unsigned long data) |
572 | { | 597 | { |
573 | struct floppy_state *fs = (struct floppy_state *) data; | 598 | struct floppy_state *fs = (struct floppy_state *) data; |
574 | struct swim3 __iomem *sw = fs->swim3; | 599 | struct swim3 __iomem *sw = fs->swim3; |
600 | unsigned long flags; | ||
601 | |||
602 | swim3_dbg("* seek timeout, state=%d\n", fs->state); | ||
575 | 603 | ||
604 | spin_lock_irqsave(&swim3_lock, flags); | ||
576 | fs->timeout_pending = 0; | 605 | fs->timeout_pending = 0; |
577 | out_8(&sw->control_bic, DO_SEEK); | 606 | out_8(&sw->control_bic, DO_SEEK); |
578 | out_8(&sw->select, RELAX); | 607 | out_8(&sw->select, RELAX); |
579 | out_8(&sw->intr_enable, 0); | 608 | out_8(&sw->intr_enable, 0); |
580 | printk(KERN_ERR "swim3: seek timeout\n"); | 609 | swim3_err("%s", "Seek timeout\n"); |
581 | swim3_end_request_cur(-EIO); | 610 | swim3_end_request(fs, -EIO, 0); |
582 | fs->state = idle; | 611 | fs->state = idle; |
583 | start_request(fs); | 612 | start_request(fs); |
613 | spin_unlock_irqrestore(&swim3_lock, flags); | ||
584 | } | 614 | } |
585 | 615 | ||
586 | static void settle_timeout(unsigned long data) | 616 | static void settle_timeout(unsigned long data) |
587 | { | 617 | { |
588 | struct floppy_state *fs = (struct floppy_state *) data; | 618 | struct floppy_state *fs = (struct floppy_state *) data; |
589 | struct swim3 __iomem *sw = fs->swim3; | 619 | struct swim3 __iomem *sw = fs->swim3; |
620 | unsigned long flags; | ||
621 | |||
622 | swim3_dbg("* settle timeout, state=%d\n", fs->state); | ||
590 | 623 | ||
624 | spin_lock_irqsave(&swim3_lock, flags); | ||
591 | fs->timeout_pending = 0; | 625 | fs->timeout_pending = 0; |
592 | if (swim3_readbit(fs, SEEK_COMPLETE)) { | 626 | if (swim3_readbit(fs, SEEK_COMPLETE)) { |
593 | out_8(&sw->select, RELAX); | 627 | out_8(&sw->select, RELAX); |
594 | fs->state = locating; | 628 | fs->state = locating; |
595 | act(fs); | 629 | act(fs); |
596 | return; | 630 | goto unlock; |
597 | } | 631 | } |
598 | out_8(&sw->select, RELAX); | 632 | out_8(&sw->select, RELAX); |
599 | if (fs->settle_time < 2*HZ) { | 633 | if (fs->settle_time < 2*HZ) { |
600 | ++fs->settle_time; | 634 | ++fs->settle_time; |
601 | set_timeout(fs, 1, settle_timeout); | 635 | set_timeout(fs, 1, settle_timeout); |
602 | return; | 636 | goto unlock; |
603 | } | 637 | } |
604 | printk(KERN_ERR "swim3: seek settle timeout\n"); | 638 | swim3_err("%s", "Seek settle timeout\n"); |
605 | swim3_end_request_cur(-EIO); | 639 | swim3_end_request(fs, -EIO, 0); |
606 | fs->state = idle; | 640 | fs->state = idle; |
607 | start_request(fs); | 641 | start_request(fs); |
642 | unlock: | ||
643 | spin_unlock_irqrestore(&swim3_lock, flags); | ||
608 | } | 644 | } |
609 | 645 | ||
610 | static void xfer_timeout(unsigned long data) | 646 | static void xfer_timeout(unsigned long data) |
@@ -612,8 +648,12 @@ static void xfer_timeout(unsigned long data) | |||
612 | struct floppy_state *fs = (struct floppy_state *) data; | 648 | struct floppy_state *fs = (struct floppy_state *) data; |
613 | struct swim3 __iomem *sw = fs->swim3; | 649 | struct swim3 __iomem *sw = fs->swim3; |
614 | struct dbdma_regs __iomem *dr = fs->dma; | 650 | struct dbdma_regs __iomem *dr = fs->dma; |
651 | unsigned long flags; | ||
615 | int n; | 652 | int n; |
616 | 653 | ||
654 | swim3_dbg("* xfer timeout, state=%d\n", fs->state); | ||
655 | |||
656 | spin_lock_irqsave(&swim3_lock, flags); | ||
617 | fs->timeout_pending = 0; | 657 | fs->timeout_pending = 0; |
618 | out_le32(&dr->control, RUN << 16); | 658 | out_le32(&dr->control, RUN << 16); |
619 | /* We must wait a bit for dbdma to stop */ | 659 | /* We must wait a bit for dbdma to stop */ |
@@ -622,12 +662,13 @@ static void xfer_timeout(unsigned long data) | |||
622 | out_8(&sw->intr_enable, 0); | 662 | out_8(&sw->intr_enable, 0); |
623 | out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION); | 663 | out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION); |
624 | out_8(&sw->select, RELAX); | 664 | out_8(&sw->select, RELAX); |
625 | printk(KERN_ERR "swim3: timeout %sing sector %ld\n", | 665 | swim3_err("Timeout %sing sector %ld\n", |
626 | (rq_data_dir(fd_req)==WRITE? "writ": "read"), | 666 | (rq_data_dir(fs->cur_req)==WRITE? "writ": "read"), |
627 | (long)blk_rq_pos(fd_req)); | 667 | (long)blk_rq_pos(fs->cur_req)); |
628 | swim3_end_request_cur(-EIO); | 668 | swim3_end_request(fs, -EIO, 0); |
629 | fs->state = idle; | 669 | fs->state = idle; |
630 | start_request(fs); | 670 | start_request(fs); |
671 | spin_unlock_irqrestore(&swim3_lock, flags); | ||
631 | } | 672 | } |
632 | 673 | ||
633 | static irqreturn_t swim3_interrupt(int irq, void *dev_id) | 674 | static irqreturn_t swim3_interrupt(int irq, void *dev_id) |
@@ -638,12 +679,17 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) | |||
638 | int stat, resid; | 679 | int stat, resid; |
639 | struct dbdma_regs __iomem *dr; | 680 | struct dbdma_regs __iomem *dr; |
640 | struct dbdma_cmd *cp; | 681 | struct dbdma_cmd *cp; |
682 | unsigned long flags; | ||
683 | struct request *req = fs->cur_req; | ||
684 | |||
685 | swim3_dbg("* interrupt, state=%d\n", fs->state); | ||
641 | 686 | ||
687 | spin_lock_irqsave(&swim3_lock, flags); | ||
642 | intr = in_8(&sw->intr); | 688 | intr = in_8(&sw->intr); |
643 | err = (intr & ERROR_INTR)? in_8(&sw->error): 0; | 689 | err = (intr & ERROR_INTR)? in_8(&sw->error): 0; |
644 | if ((intr & ERROR_INTR) && fs->state != do_transfer) | 690 | if ((intr & ERROR_INTR) && fs->state != do_transfer) |
645 | printk(KERN_ERR "swim3_interrupt, state=%d, dir=%x, intr=%x, err=%x\n", | 691 | swim3_err("Non-transfer error interrupt: state=%d, dir=%x, intr=%x, err=%x\n", |
646 | fs->state, rq_data_dir(fd_req), intr, err); | 692 | fs->state, rq_data_dir(req), intr, err); |
647 | switch (fs->state) { | 693 | switch (fs->state) { |
648 | case locating: | 694 | case locating: |
649 | if (intr & SEEN_SECTOR) { | 695 | if (intr & SEEN_SECTOR) { |
@@ -653,10 +699,10 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) | |||
653 | del_timer(&fs->timeout); | 699 | del_timer(&fs->timeout); |
654 | fs->timeout_pending = 0; | 700 | fs->timeout_pending = 0; |
655 | if (sw->ctrack == 0xff) { | 701 | if (sw->ctrack == 0xff) { |
656 | printk(KERN_ERR "swim3: seen sector but cyl=ff?\n"); | 702 | swim3_err("%s", "Seen sector but cyl=ff?\n"); |
657 | fs->cur_cyl = -1; | 703 | fs->cur_cyl = -1; |
658 | if (fs->retries > 5) { | 704 | if (fs->retries > 5) { |
659 | swim3_end_request_cur(-EIO); | 705 | swim3_end_request(fs, -EIO, 0); |
660 | fs->state = idle; | 706 | fs->state = idle; |
661 | start_request(fs); | 707 | start_request(fs); |
662 | } else { | 708 | } else { |
@@ -668,8 +714,8 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) | |||
668 | fs->cur_cyl = sw->ctrack; | 714 | fs->cur_cyl = sw->ctrack; |
669 | fs->cur_sector = sw->csect; | 715 | fs->cur_sector = sw->csect; |
670 | if (fs->expect_cyl != -1 && fs->expect_cyl != fs->cur_cyl) | 716 | if (fs->expect_cyl != -1 && fs->expect_cyl != fs->cur_cyl) |
671 | printk(KERN_ERR "swim3: expected cyl %d, got %d\n", | 717 | swim3_err("Expected cyl %d, got %d\n", |
672 | fs->expect_cyl, fs->cur_cyl); | 718 | fs->expect_cyl, fs->cur_cyl); |
673 | fs->state = do_transfer; | 719 | fs->state = do_transfer; |
674 | act(fs); | 720 | act(fs); |
675 | } | 721 | } |
@@ -704,7 +750,7 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) | |||
704 | fs->timeout_pending = 0; | 750 | fs->timeout_pending = 0; |
705 | dr = fs->dma; | 751 | dr = fs->dma; |
706 | cp = fs->dma_cmd; | 752 | cp = fs->dma_cmd; |
707 | if (rq_data_dir(fd_req) == WRITE) | 753 | if (rq_data_dir(req) == WRITE) |
708 | ++cp; | 754 | ++cp; |
709 | /* | 755 | /* |
710 | * Check that the main data transfer has finished. | 756 | * Check that the main data transfer has finished. |
@@ -729,31 +775,32 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) | |||
729 | if (intr & ERROR_INTR) { | 775 | if (intr & ERROR_INTR) { |
730 | n = fs->scount - 1 - resid / 512; | 776 | n = fs->scount - 1 - resid / 512; |
731 | if (n > 0) { | 777 | if (n > 0) { |
732 | blk_update_request(fd_req, 0, n << 9); | 778 | blk_update_request(req, 0, n << 9); |
733 | fs->req_sector += n; | 779 | fs->req_sector += n; |
734 | } | 780 | } |
735 | if (fs->retries < 5) { | 781 | if (fs->retries < 5) { |
736 | ++fs->retries; | 782 | ++fs->retries; |
737 | act(fs); | 783 | act(fs); |
738 | } else { | 784 | } else { |
739 | printk("swim3: error %sing block %ld (err=%x)\n", | 785 | swim3_err("Error %sing block %ld (err=%x)\n", |
740 | rq_data_dir(fd_req) == WRITE? "writ": "read", | 786 | rq_data_dir(req) == WRITE? "writ": "read", |
741 | (long)blk_rq_pos(fd_req), err); | 787 | (long)blk_rq_pos(req), err); |
742 | swim3_end_request_cur(-EIO); | 788 | swim3_end_request(fs, -EIO, 0); |
743 | fs->state = idle; | 789 | fs->state = idle; |
744 | } | 790 | } |
745 | } else { | 791 | } else { |
746 | if ((stat & ACTIVE) == 0 || resid != 0) { | 792 | if ((stat & ACTIVE) == 0 || resid != 0) { |
747 | /* musta been an error */ | 793 | /* musta been an error */ |
748 | printk(KERN_ERR "swim3: fd dma: stat=%x resid=%d\n", stat, resid); | 794 | swim3_err("fd dma error: stat=%x resid=%d\n", stat, resid); |
749 | printk(KERN_ERR " state=%d, dir=%x, intr=%x, err=%x\n", | 795 | swim3_err(" state=%d, dir=%x, intr=%x, err=%x\n", |
750 | fs->state, rq_data_dir(fd_req), intr, err); | 796 | fs->state, rq_data_dir(req), intr, err); |
751 | swim3_end_request_cur(-EIO); | 797 | swim3_end_request(fs, -EIO, 0); |
752 | fs->state = idle; | 798 | fs->state = idle; |
753 | start_request(fs); | 799 | start_request(fs); |
754 | break; | 800 | break; |
755 | } | 801 | } |
756 | if (swim3_end_request(0, fs->scount << 9)) { | 802 | fs->retries = 0; |
803 | if (swim3_end_request(fs, 0, fs->scount << 9)) { | ||
757 | fs->req_sector += fs->scount; | 804 | fs->req_sector += fs->scount; |
758 | if (fs->req_sector > fs->secpertrack) { | 805 | if (fs->req_sector > fs->secpertrack) { |
759 | fs->req_sector -= fs->secpertrack; | 806 | fs->req_sector -= fs->secpertrack; |
@@ -770,8 +817,9 @@ static irqreturn_t swim3_interrupt(int irq, void *dev_id) | |||
770 | start_request(fs); | 817 | start_request(fs); |
771 | break; | 818 | break; |
772 | default: | 819 | default: |
773 | printk(KERN_ERR "swim3: don't know what to do in state %d\n", fs->state); | 820 | swim3_err("Don't know what to do in state %d\n", fs->state); |
774 | } | 821 | } |
822 | spin_unlock_irqrestore(&swim3_lock, flags); | ||
775 | return IRQ_HANDLED; | 823 | return IRQ_HANDLED; |
776 | } | 824 | } |
777 | 825 | ||
@@ -781,26 +829,31 @@ static void fd_dma_interrupt(int irq, void *dev_id) | |||
781 | } | 829 | } |
782 | */ | 830 | */ |
783 | 831 | ||
832 | /* Called under the mutex to grab exclusive access to a drive */ | ||
784 | static int grab_drive(struct floppy_state *fs, enum swim_state state, | 833 | static int grab_drive(struct floppy_state *fs, enum swim_state state, |
785 | int interruptible) | 834 | int interruptible) |
786 | { | 835 | { |
787 | unsigned long flags; | 836 | unsigned long flags; |
788 | 837 | ||
789 | spin_lock_irqsave(&fs->lock, flags); | 838 | swim3_dbg("%s", "-> grab drive\n"); |
790 | if (fs->state != idle) { | 839 | |
840 | spin_lock_irqsave(&swim3_lock, flags); | ||
841 | if (fs->state != idle && fs->state != available) { | ||
791 | ++fs->wanted; | 842 | ++fs->wanted; |
792 | while (fs->state != available) { | 843 | while (fs->state != available) { |
844 | spin_unlock_irqrestore(&swim3_lock, flags); | ||
793 | if (interruptible && signal_pending(current)) { | 845 | if (interruptible && signal_pending(current)) { |
794 | --fs->wanted; | 846 | --fs->wanted; |
795 | spin_unlock_irqrestore(&fs->lock, flags); | ||
796 | return -EINTR; | 847 | return -EINTR; |
797 | } | 848 | } |
798 | interruptible_sleep_on(&fs->wait); | 849 | interruptible_sleep_on(&fs->wait); |
850 | spin_lock_irqsave(&swim3_lock, flags); | ||
799 | } | 851 | } |
800 | --fs->wanted; | 852 | --fs->wanted; |
801 | } | 853 | } |
802 | fs->state = state; | 854 | fs->state = state; |
803 | spin_unlock_irqrestore(&fs->lock, flags); | 855 | spin_unlock_irqrestore(&swim3_lock, flags); |
856 | |||
804 | return 0; | 857 | return 0; |
805 | } | 858 | } |
806 | 859 | ||
@@ -808,10 +861,12 @@ static void release_drive(struct floppy_state *fs) | |||
808 | { | 861 | { |
809 | unsigned long flags; | 862 | unsigned long flags; |
810 | 863 | ||
811 | spin_lock_irqsave(&fs->lock, flags); | 864 | swim3_dbg("%s", "-> release drive\n"); |
865 | |||
866 | spin_lock_irqsave(&swim3_lock, flags); | ||
812 | fs->state = idle; | 867 | fs->state = idle; |
813 | start_request(fs); | 868 | start_request(fs); |
814 | spin_unlock_irqrestore(&fs->lock, flags); | 869 | spin_unlock_irqrestore(&swim3_lock, flags); |
815 | } | 870 | } |
816 | 871 | ||
817 | static int fd_eject(struct floppy_state *fs) | 872 | static int fd_eject(struct floppy_state *fs) |
@@ -966,6 +1021,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) | |||
966 | { | 1021 | { |
967 | struct floppy_state *fs = disk->private_data; | 1022 | struct floppy_state *fs = disk->private_data; |
968 | struct swim3 __iomem *sw = fs->swim3; | 1023 | struct swim3 __iomem *sw = fs->swim3; |
1024 | |||
969 | mutex_lock(&swim3_mutex); | 1025 | mutex_lock(&swim3_mutex); |
970 | if (fs->ref_count > 0 && --fs->ref_count == 0) { | 1026 | if (fs->ref_count > 0 && --fs->ref_count == 0) { |
971 | swim3_action(fs, MOTOR_OFF); | 1027 | swim3_action(fs, MOTOR_OFF); |
@@ -1031,30 +1087,48 @@ static const struct block_device_operations floppy_fops = { | |||
1031 | .revalidate_disk= floppy_revalidate, | 1087 | .revalidate_disk= floppy_revalidate, |
1032 | }; | 1088 | }; |
1033 | 1089 | ||
1090 | static void swim3_mb_event(struct macio_dev* mdev, int mb_state) | ||
1091 | { | ||
1092 | struct floppy_state *fs = macio_get_drvdata(mdev); | ||
1093 | struct swim3 __iomem *sw = fs->swim3; | ||
1094 | |||
1095 | if (!fs) | ||
1096 | return; | ||
1097 | if (mb_state != MB_FD) | ||
1098 | return; | ||
1099 | |||
1100 | /* Clear state */ | ||
1101 | out_8(&sw->intr_enable, 0); | ||
1102 | in_8(&sw->intr); | ||
1103 | in_8(&sw->error); | ||
1104 | } | ||
1105 | |||
1034 | static int swim3_add_device(struct macio_dev *mdev, int index) | 1106 | static int swim3_add_device(struct macio_dev *mdev, int index) |
1035 | { | 1107 | { |
1036 | struct device_node *swim = mdev->ofdev.dev.of_node; | 1108 | struct device_node *swim = mdev->ofdev.dev.of_node; |
1037 | struct floppy_state *fs = &floppy_states[index]; | 1109 | struct floppy_state *fs = &floppy_states[index]; |
1038 | int rc = -EBUSY; | 1110 | int rc = -EBUSY; |
1039 | 1111 | ||
1112 | /* Do this first for message macros */ | ||
1113 | memset(fs, 0, sizeof(*fs)); | ||
1114 | fs->mdev = mdev; | ||
1115 | fs->index = index; | ||
1116 | |||
1040 | /* Check & Request resources */ | 1117 | /* Check & Request resources */ |
1041 | if (macio_resource_count(mdev) < 2) { | 1118 | if (macio_resource_count(mdev) < 2) { |
1042 | printk(KERN_WARNING "ifd%d: no address for %s\n", | 1119 | swim3_err("%s", "No address in device-tree\n"); |
1043 | index, swim->full_name); | ||
1044 | return -ENXIO; | 1120 | return -ENXIO; |
1045 | } | 1121 | } |
1046 | if (macio_irq_count(mdev) < 2) { | 1122 | if (macio_irq_count(mdev) < 1) { |
1047 | printk(KERN_WARNING "fd%d: no intrs for device %s\n", | 1123 | swim3_err("%s", "No interrupt in device-tree\n"); |
1048 | index, swim->full_name); | 1124 | return -ENXIO; |
1049 | } | 1125 | } |
1050 | if (macio_request_resource(mdev, 0, "swim3 (mmio)")) { | 1126 | if (macio_request_resource(mdev, 0, "swim3 (mmio)")) { |
1051 | printk(KERN_ERR "fd%d: can't request mmio resource for %s\n", | 1127 | swim3_err("%s", "Can't request mmio resource\n"); |
1052 | index, swim->full_name); | ||
1053 | return -EBUSY; | 1128 | return -EBUSY; |
1054 | } | 1129 | } |
1055 | if (macio_request_resource(mdev, 1, "swim3 (dma)")) { | 1130 | if (macio_request_resource(mdev, 1, "swim3 (dma)")) { |
1056 | printk(KERN_ERR "fd%d: can't request dma resource for %s\n", | 1131 | swim3_err("%s", "Can't request dma resource\n"); |
1057 | index, swim->full_name); | ||
1058 | macio_release_resource(mdev, 0); | 1132 | macio_release_resource(mdev, 0); |
1059 | return -EBUSY; | 1133 | return -EBUSY; |
1060 | } | 1134 | } |
@@ -1063,22 +1137,18 @@ static int swim3_add_device(struct macio_dev *mdev, int index) | |||
1063 | if (mdev->media_bay == NULL) | 1137 | if (mdev->media_bay == NULL) |
1064 | pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); | 1138 | pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); |
1065 | 1139 | ||
1066 | memset(fs, 0, sizeof(*fs)); | ||
1067 | spin_lock_init(&fs->lock); | ||
1068 | fs->state = idle; | 1140 | fs->state = idle; |
1069 | fs->swim3 = (struct swim3 __iomem *) | 1141 | fs->swim3 = (struct swim3 __iomem *) |
1070 | ioremap(macio_resource_start(mdev, 0), 0x200); | 1142 | ioremap(macio_resource_start(mdev, 0), 0x200); |
1071 | if (fs->swim3 == NULL) { | 1143 | if (fs->swim3 == NULL) { |
1072 | printk("fd%d: couldn't map registers for %s\n", | 1144 | swim3_err("%s", "Couldn't map mmio registers\n"); |
1073 | index, swim->full_name); | ||
1074 | rc = -ENOMEM; | 1145 | rc = -ENOMEM; |
1075 | goto out_release; | 1146 | goto out_release; |
1076 | } | 1147 | } |
1077 | fs->dma = (struct dbdma_regs __iomem *) | 1148 | fs->dma = (struct dbdma_regs __iomem *) |
1078 | ioremap(macio_resource_start(mdev, 1), 0x200); | 1149 | ioremap(macio_resource_start(mdev, 1), 0x200); |
1079 | if (fs->dma == NULL) { | 1150 | if (fs->dma == NULL) { |
1080 | printk("fd%d: couldn't map DMA for %s\n", | 1151 | swim3_err("%s", "Couldn't map dma registers\n"); |
1081 | index, swim->full_name); | ||
1082 | iounmap(fs->swim3); | 1152 | iounmap(fs->swim3); |
1083 | rc = -ENOMEM; | 1153 | rc = -ENOMEM; |
1084 | goto out_release; | 1154 | goto out_release; |
@@ -1090,31 +1160,25 @@ static int swim3_add_device(struct macio_dev *mdev, int index) | |||
1090 | fs->secpercyl = 36; | 1160 | fs->secpercyl = 36; |
1091 | fs->secpertrack = 18; | 1161 | fs->secpertrack = 18; |
1092 | fs->total_secs = 2880; | 1162 | fs->total_secs = 2880; |
1093 | fs->mdev = mdev; | ||
1094 | init_waitqueue_head(&fs->wait); | 1163 | init_waitqueue_head(&fs->wait); |
1095 | 1164 | ||
1096 | fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space); | 1165 | fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space); |
1097 | memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd)); | 1166 | memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd)); |
1098 | st_le16(&fs->dma_cmd[1].command, DBDMA_STOP); | 1167 | st_le16(&fs->dma_cmd[1].command, DBDMA_STOP); |
1099 | 1168 | ||
1169 | if (mdev->media_bay == NULL || check_media_bay(mdev->media_bay) == MB_FD) | ||
1170 | swim3_mb_event(mdev, MB_FD); | ||
1171 | |||
1100 | if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { | 1172 | if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { |
1101 | printk(KERN_ERR "fd%d: couldn't request irq %d for %s\n", | 1173 | swim3_err("%s", "Couldn't request interrupt\n"); |
1102 | index, fs->swim3_intr, swim->full_name); | ||
1103 | pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); | 1174 | pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); |
1104 | goto out_unmap; | 1175 | goto out_unmap; |
1105 | return -EBUSY; | 1176 | return -EBUSY; |
1106 | } | 1177 | } |
1107 | /* | ||
1108 | if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) { | ||
1109 | printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA", | ||
1110 | fs->dma_intr); | ||
1111 | return -EBUSY; | ||
1112 | } | ||
1113 | */ | ||
1114 | 1178 | ||
1115 | init_timer(&fs->timeout); | 1179 | init_timer(&fs->timeout); |
1116 | 1180 | ||
1117 | printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, | 1181 | swim3_info("SWIM3 floppy controller %s\n", |
1118 | mdev->media_bay ? "in media bay" : ""); | 1182 | mdev->media_bay ? "in media bay" : ""); |
1119 | 1183 | ||
1120 | return 0; | 1184 | return 0; |
@@ -1132,41 +1196,42 @@ static int swim3_add_device(struct macio_dev *mdev, int index) | |||
1132 | 1196 | ||
1133 | static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device_id *match) | 1197 | static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device_id *match) |
1134 | { | 1198 | { |
1135 | int i, rc; | ||
1136 | struct gendisk *disk; | 1199 | struct gendisk *disk; |
1200 | int index, rc; | ||
1201 | |||
1202 | index = floppy_count++; | ||
1203 | if (index >= MAX_FLOPPIES) | ||
1204 | return -ENXIO; | ||
1137 | 1205 | ||
1138 | /* Add the drive */ | 1206 | /* Add the drive */ |
1139 | rc = swim3_add_device(mdev, floppy_count); | 1207 | rc = swim3_add_device(mdev, index); |
1140 | if (rc) | 1208 | if (rc) |
1141 | return rc; | 1209 | return rc; |
1210 | /* Now register that disk. Same comment about failure handling */ | ||
1211 | disk = disks[index] = alloc_disk(1); | ||
1212 | if (disk == NULL) | ||
1213 | return -ENOMEM; | ||
1214 | disk->queue = blk_init_queue(do_fd_request, &swim3_lock); | ||
1215 | if (disk->queue == NULL) { | ||
1216 | put_disk(disk); | ||
1217 | return -ENOMEM; | ||
1218 | } | ||
1219 | disk->queue->queuedata = &floppy_states[index]; | ||
1142 | 1220 | ||
1143 | /* Now create the queue if not there yet */ | 1221 | if (index == 0) { |
1144 | if (swim3_queue == NULL) { | ||
1145 | /* If we failed, there isn't much we can do as the driver is still | 1222 | /* If we failed, there isn't much we can do as the driver is still |
1146 | * too dumb to remove the device, just bail out | 1223 | * too dumb to remove the device, just bail out |
1147 | */ | 1224 | */ |
1148 | if (register_blkdev(FLOPPY_MAJOR, "fd")) | 1225 | if (register_blkdev(FLOPPY_MAJOR, "fd")) |
1149 | return 0; | 1226 | return 0; |
1150 | swim3_queue = blk_init_queue(do_fd_request, &swim3_lock); | ||
1151 | if (swim3_queue == NULL) { | ||
1152 | unregister_blkdev(FLOPPY_MAJOR, "fd"); | ||
1153 | return 0; | ||
1154 | } | ||
1155 | } | 1227 | } |
1156 | 1228 | ||
1157 | /* Now register that disk. Same comment about failure handling */ | ||
1158 | i = floppy_count++; | ||
1159 | disk = disks[i] = alloc_disk(1); | ||
1160 | if (disk == NULL) | ||
1161 | return 0; | ||
1162 | |||
1163 | disk->major = FLOPPY_MAJOR; | 1229 | disk->major = FLOPPY_MAJOR; |
1164 | disk->first_minor = i; | 1230 | disk->first_minor = index; |
1165 | disk->fops = &floppy_fops; | 1231 | disk->fops = &floppy_fops; |
1166 | disk->private_data = &floppy_states[i]; | 1232 | disk->private_data = &floppy_states[index]; |
1167 | disk->queue = swim3_queue; | ||
1168 | disk->flags |= GENHD_FL_REMOVABLE; | 1233 | disk->flags |= GENHD_FL_REMOVABLE; |
1169 | sprintf(disk->disk_name, "fd%d", i); | 1234 | sprintf(disk->disk_name, "fd%d", index); |
1170 | set_capacity(disk, 2880); | 1235 | set_capacity(disk, 2880); |
1171 | add_disk(disk); | 1236 | add_disk(disk); |
1172 | 1237 | ||
@@ -1194,6 +1259,9 @@ static struct macio_driver swim3_driver = | |||
1194 | .of_match_table = swim3_match, | 1259 | .of_match_table = swim3_match, |
1195 | }, | 1260 | }, |
1196 | .probe = swim3_attach, | 1261 | .probe = swim3_attach, |
1262 | #ifdef CONFIG_PMAC_MEDIABAY | ||
1263 | .mediabay_event = swim3_mb_event, | ||
1264 | #endif | ||
1197 | #if 0 | 1265 | #if 0 |
1198 | .suspend = swim3_suspend, | 1266 | .suspend = swim3_suspend, |
1199 | .resume = swim3_resume, | 1267 | .resume = swim3_resume, |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index c2917ffad2c2..34767a6d7f42 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -139,6 +139,8 @@ | |||
139 | #define IPMI_WDOG_SET_TIMER 0x24 | 139 | #define IPMI_WDOG_SET_TIMER 0x24 |
140 | #define IPMI_WDOG_GET_TIMER 0x25 | 140 | #define IPMI_WDOG_GET_TIMER 0x25 |
141 | 141 | ||
142 | #define IPMI_WDOG_TIMER_NOT_INIT_RESP 0x80 | ||
143 | |||
142 | /* These are here until the real ones get into the watchdog.h interface. */ | 144 | /* These are here until the real ones get into the watchdog.h interface. */ |
143 | #ifndef WDIOC_GETTIMEOUT | 145 | #ifndef WDIOC_GETTIMEOUT |
144 | #define WDIOC_GETTIMEOUT _IOW(WATCHDOG_IOCTL_BASE, 20, int) | 146 | #define WDIOC_GETTIMEOUT _IOW(WATCHDOG_IOCTL_BASE, 20, int) |
@@ -596,6 +598,7 @@ static int ipmi_heartbeat(void) | |||
596 | struct kernel_ipmi_msg msg; | 598 | struct kernel_ipmi_msg msg; |
597 | int rv; | 599 | int rv; |
598 | struct ipmi_system_interface_addr addr; | 600 | struct ipmi_system_interface_addr addr; |
601 | int timeout_retries = 0; | ||
599 | 602 | ||
600 | if (ipmi_ignore_heartbeat) | 603 | if (ipmi_ignore_heartbeat) |
601 | return 0; | 604 | return 0; |
@@ -616,6 +619,7 @@ static int ipmi_heartbeat(void) | |||
616 | 619 | ||
617 | mutex_lock(&heartbeat_lock); | 620 | mutex_lock(&heartbeat_lock); |
618 | 621 | ||
622 | restart: | ||
619 | atomic_set(&heartbeat_tofree, 2); | 623 | atomic_set(&heartbeat_tofree, 2); |
620 | 624 | ||
621 | /* | 625 | /* |
@@ -653,7 +657,33 @@ static int ipmi_heartbeat(void) | |||
653 | /* Wait for the heartbeat to be sent. */ | 657 | /* Wait for the heartbeat to be sent. */ |
654 | wait_for_completion(&heartbeat_wait); | 658 | wait_for_completion(&heartbeat_wait); |
655 | 659 | ||
656 | if (heartbeat_recv_msg.msg.data[0] != 0) { | 660 | if (heartbeat_recv_msg.msg.data[0] == IPMI_WDOG_TIMER_NOT_INIT_RESP) { |
661 | timeout_retries++; | ||
662 | if (timeout_retries > 3) { | ||
663 | printk(KERN_ERR PFX ": Unable to restore the IPMI" | ||
664 | " watchdog's settings, giving up.\n"); | ||
665 | rv = -EIO; | ||
666 | goto out_unlock; | ||
667 | } | ||
668 | |||
669 | /* | ||
670 | * The timer was not initialized, that means the BMC was | ||
671 | * probably reset and lost the watchdog information. Attempt | ||
672 | * to restore the timer's info. Note that we still hold | ||
673 | * the heartbeat lock, to keep a heartbeat from happening | ||
674 | * in this process, so must say no heartbeat to avoid a | ||
675 | * deadlock on this mutex. | ||
676 | */ | ||
677 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); | ||
678 | if (rv) { | ||
679 | printk(KERN_ERR PFX ": Unable to send the command to" | ||
680 | " set the watchdog's settings, giving up.\n"); | ||
681 | goto out_unlock; | ||
682 | } | ||
683 | |||
684 | /* We might need a new heartbeat, so do it now */ | ||
685 | goto restart; | ||
686 | } else if (heartbeat_recv_msg.msg.data[0] != 0) { | ||
657 | /* | 687 | /* |
658 | * Got an error in the heartbeat response. It was already | 688 | * Got an error in the heartbeat response. It was already |
659 | * reported in ipmi_wdog_msg_handler, but we should return | 689 | * reported in ipmi_wdog_msg_handler, but we should return |
@@ -662,6 +692,7 @@ static int ipmi_heartbeat(void) | |||
662 | rv = -EINVAL; | 692 | rv = -EINVAL; |
663 | } | 693 | } |
664 | 694 | ||
695 | out_unlock: | ||
665 | mutex_unlock(&heartbeat_lock); | 696 | mutex_unlock(&heartbeat_lock); |
666 | 697 | ||
667 | return rv; | 698 | return rv; |
@@ -922,11 +953,15 @@ static struct miscdevice ipmi_wdog_miscdev = { | |||
922 | static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg, | 953 | static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg, |
923 | void *handler_data) | 954 | void *handler_data) |
924 | { | 955 | { |
925 | if (msg->msg.data[0] != 0) { | 956 | if (msg->msg.cmd == IPMI_WDOG_RESET_TIMER && |
957 | msg->msg.data[0] == IPMI_WDOG_TIMER_NOT_INIT_RESP) | ||
958 | printk(KERN_INFO PFX "response: The IPMI controller appears" | ||
959 | " to have been reset, will attempt to reinitialize" | ||
960 | " the watchdog timer\n"); | ||
961 | else if (msg->msg.data[0] != 0) | ||
926 | printk(KERN_ERR PFX "response: Error %x on cmd %x\n", | 962 | printk(KERN_ERR PFX "response: Error %x on cmd %x\n", |
927 | msg->msg.data[0], | 963 | msg->msg.data[0], |
928 | msg->msg.cmd); | 964 | msg->msg.cmd); |
929 | } | ||
930 | 965 | ||
931 | ipmi_free_recv_msg(msg); | 966 | ipmi_free_recv_msg(msg); |
932 | } | 967 | } |
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index c811cb107904..2cce44a1d7d0 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c | |||
@@ -746,6 +746,37 @@ static void __exit ibft_exit(void) | |||
746 | ibft_cleanup(); | 746 | ibft_cleanup(); |
747 | } | 747 | } |
748 | 748 | ||
749 | #ifdef CONFIG_ACPI | ||
750 | static const struct { | ||
751 | char *sign; | ||
752 | } ibft_signs[] = { | ||
753 | /* | ||
754 | * One spec says "IBFT", the other says "iBFT". We have to check | ||
755 | * for both. | ||
756 | */ | ||
757 | { ACPI_SIG_IBFT }, | ||
758 | { "iBFT" }, | ||
759 | }; | ||
760 | |||
761 | static void __init acpi_find_ibft_region(void) | ||
762 | { | ||
763 | int i; | ||
764 | struct acpi_table_header *table = NULL; | ||
765 | |||
766 | if (acpi_disabled) | ||
767 | return; | ||
768 | |||
769 | for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) { | ||
770 | acpi_get_table(ibft_signs[i].sign, 0, &table); | ||
771 | ibft_addr = (struct acpi_table_ibft *)table; | ||
772 | } | ||
773 | } | ||
774 | #else | ||
775 | static void __init acpi_find_ibft_region(void) | ||
776 | { | ||
777 | } | ||
778 | #endif | ||
779 | |||
749 | /* | 780 | /* |
750 | * ibft_init() - creates sysfs tree entries for the iBFT data. | 781 | * ibft_init() - creates sysfs tree entries for the iBFT data. |
751 | */ | 782 | */ |
@@ -753,9 +784,16 @@ static int __init ibft_init(void) | |||
753 | { | 784 | { |
754 | int rc = 0; | 785 | int rc = 0; |
755 | 786 | ||
787 | /* | ||
788 | As on UEFI systems the setup_arch()/find_ibft_region() | ||
789 | is called before ACPI tables are parsed and it only does | ||
790 | legacy finding. | ||
791 | */ | ||
792 | if (!ibft_addr) | ||
793 | acpi_find_ibft_region(); | ||
794 | |||
756 | if (ibft_addr) { | 795 | if (ibft_addr) { |
757 | printk(KERN_INFO "iBFT detected at 0x%llx.\n", | 796 | pr_info("iBFT detected.\n"); |
758 | (u64)isa_virt_to_bus(ibft_addr)); | ||
759 | 797 | ||
760 | rc = ibft_check_device(); | 798 | rc = ibft_check_device(); |
761 | if (rc) | 799 | if (rc) |
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c index bfe723266fd8..4da4eb9ae926 100644 --- a/drivers/firmware/iscsi_ibft_find.c +++ b/drivers/firmware/iscsi_ibft_find.c | |||
@@ -45,13 +45,6 @@ EXPORT_SYMBOL_GPL(ibft_addr); | |||
45 | static const struct { | 45 | static const struct { |
46 | char *sign; | 46 | char *sign; |
47 | } ibft_signs[] = { | 47 | } ibft_signs[] = { |
48 | #ifdef CONFIG_ACPI | ||
49 | /* | ||
50 | * One spec says "IBFT", the other says "iBFT". We have to check | ||
51 | * for both. | ||
52 | */ | ||
53 | { ACPI_SIG_IBFT }, | ||
54 | #endif | ||
55 | { "iBFT" }, | 48 | { "iBFT" }, |
56 | { "BIFT" }, /* Broadcom iSCSI Offload */ | 49 | { "BIFT" }, /* Broadcom iSCSI Offload */ |
57 | }; | 50 | }; |
@@ -62,14 +55,6 @@ static const struct { | |||
62 | #define VGA_MEM 0xA0000 /* VGA buffer */ | 55 | #define VGA_MEM 0xA0000 /* VGA buffer */ |
63 | #define VGA_SIZE 0x20000 /* 128kB */ | 56 | #define VGA_SIZE 0x20000 /* 128kB */ |
64 | 57 | ||
65 | #ifdef CONFIG_ACPI | ||
66 | static int __init acpi_find_ibft(struct acpi_table_header *header) | ||
67 | { | ||
68 | ibft_addr = (struct acpi_table_ibft *)header; | ||
69 | return 0; | ||
70 | } | ||
71 | #endif /* CONFIG_ACPI */ | ||
72 | |||
73 | static int __init find_ibft_in_mem(void) | 58 | static int __init find_ibft_in_mem(void) |
74 | { | 59 | { |
75 | unsigned long pos; | 60 | unsigned long pos; |
@@ -94,6 +79,7 @@ static int __init find_ibft_in_mem(void) | |||
94 | * the table cannot be valid. */ | 79 | * the table cannot be valid. */ |
95 | if (pos + len <= (IBFT_END-1)) { | 80 | if (pos + len <= (IBFT_END-1)) { |
96 | ibft_addr = (struct acpi_table_ibft *)virt; | 81 | ibft_addr = (struct acpi_table_ibft *)virt; |
82 | pr_info("iBFT found at 0x%lx.\n", pos); | ||
97 | goto done; | 83 | goto done; |
98 | } | 84 | } |
99 | } | 85 | } |
@@ -108,20 +94,12 @@ done: | |||
108 | */ | 94 | */ |
109 | unsigned long __init find_ibft_region(unsigned long *sizep) | 95 | unsigned long __init find_ibft_region(unsigned long *sizep) |
110 | { | 96 | { |
111 | #ifdef CONFIG_ACPI | ||
112 | int i; | ||
113 | #endif | ||
114 | ibft_addr = NULL; | 97 | ibft_addr = NULL; |
115 | 98 | ||
116 | #ifdef CONFIG_ACPI | ||
117 | for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) | ||
118 | acpi_table_parse(ibft_signs[i].sign, acpi_find_ibft); | ||
119 | #endif /* CONFIG_ACPI */ | ||
120 | |||
121 | /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will | 99 | /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will |
122 | * only use ACPI for this */ | 100 | * only use ACPI for this */ |
123 | 101 | ||
124 | if (!ibft_addr && !efi_enabled) | 102 | if (!efi_enabled) |
125 | find_ibft_in_mem(); | 103 | find_ibft_in_mem(); |
126 | 104 | ||
127 | if (ibft_addr) { | 105 | if (ibft_addr) { |
diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c index 038f5eb8b13d..f8ce29ef9f88 100644 --- a/drivers/gpio/gpio-da9052.c +++ b/drivers/gpio/gpio-da9052.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/mfd/da9052/da9052.h> | 22 | #include <linux/mfd/da9052/da9052.h> |
23 | #include <linux/mfd/da9052/reg.h> | 23 | #include <linux/mfd/da9052/reg.h> |
24 | #include <linux/mfd/da9052/pdata.h> | 24 | #include <linux/mfd/da9052/pdata.h> |
25 | #include <linux/mfd/da9052/gpio.h> | ||
26 | 25 | ||
27 | #define DA9052_INPUT 1 | 26 | #define DA9052_INPUT 1 |
28 | #define DA9052_OUTPUT_OPENDRAIN 2 | 27 | #define DA9052_OUTPUT_OPENDRAIN 2 |
@@ -43,6 +42,9 @@ | |||
43 | #define DA9052_GPIO_MASK_UPPER_NIBBLE 0xF0 | 42 | #define DA9052_GPIO_MASK_UPPER_NIBBLE 0xF0 |
44 | #define DA9052_GPIO_MASK_LOWER_NIBBLE 0x0F | 43 | #define DA9052_GPIO_MASK_LOWER_NIBBLE 0x0F |
45 | #define DA9052_GPIO_NIBBLE_SHIFT 4 | 44 | #define DA9052_GPIO_NIBBLE_SHIFT 4 |
45 | #define DA9052_IRQ_GPI0 16 | ||
46 | #define DA9052_GPIO_ODD_SHIFT 7 | ||
47 | #define DA9052_GPIO_EVEN_SHIFT 3 | ||
46 | 48 | ||
47 | struct da9052_gpio { | 49 | struct da9052_gpio { |
48 | struct da9052 *da9052; | 50 | struct da9052 *da9052; |
@@ -104,33 +106,26 @@ static int da9052_gpio_get(struct gpio_chip *gc, unsigned offset) | |||
104 | static void da9052_gpio_set(struct gpio_chip *gc, unsigned offset, int value) | 106 | static void da9052_gpio_set(struct gpio_chip *gc, unsigned offset, int value) |
105 | { | 107 | { |
106 | struct da9052_gpio *gpio = to_da9052_gpio(gc); | 108 | struct da9052_gpio *gpio = to_da9052_gpio(gc); |
107 | unsigned char register_value = 0; | ||
108 | int ret; | 109 | int ret; |
109 | 110 | ||
110 | if (da9052_gpio_port_odd(offset)) { | 111 | if (da9052_gpio_port_odd(offset)) { |
111 | if (value) { | ||
112 | register_value = DA9052_GPIO_ODD_PORT_MODE; | ||
113 | ret = da9052_reg_update(gpio->da9052, (offset >> 1) + | 112 | ret = da9052_reg_update(gpio->da9052, (offset >> 1) + |
114 | DA9052_GPIO_0_1_REG, | 113 | DA9052_GPIO_0_1_REG, |
115 | DA9052_GPIO_ODD_PORT_MODE, | 114 | DA9052_GPIO_ODD_PORT_MODE, |
116 | register_value); | 115 | value << DA9052_GPIO_ODD_SHIFT); |
117 | if (ret != 0) | 116 | if (ret != 0) |
118 | dev_err(gpio->da9052->dev, | 117 | dev_err(gpio->da9052->dev, |
119 | "Failed to updated gpio odd reg,%d", | 118 | "Failed to updated gpio odd reg,%d", |
120 | ret); | 119 | ret); |
121 | } | ||
122 | } else { | 120 | } else { |
123 | if (value) { | ||
124 | register_value = DA9052_GPIO_EVEN_PORT_MODE; | ||
125 | ret = da9052_reg_update(gpio->da9052, (offset >> 1) + | 121 | ret = da9052_reg_update(gpio->da9052, (offset >> 1) + |
126 | DA9052_GPIO_0_1_REG, | 122 | DA9052_GPIO_0_1_REG, |
127 | DA9052_GPIO_EVEN_PORT_MODE, | 123 | DA9052_GPIO_EVEN_PORT_MODE, |
128 | register_value); | 124 | value << DA9052_GPIO_EVEN_SHIFT); |
129 | if (ret != 0) | 125 | if (ret != 0) |
130 | dev_err(gpio->da9052->dev, | 126 | dev_err(gpio->da9052->dev, |
131 | "Failed to updated gpio even reg,%d", | 127 | "Failed to updated gpio even reg,%d", |
132 | ret); | 128 | ret); |
133 | } | ||
134 | } | 129 | } |
135 | } | 130 | } |
136 | 131 | ||
@@ -201,9 +196,9 @@ static struct gpio_chip reference_gp __devinitdata = { | |||
201 | .direction_input = da9052_gpio_direction_input, | 196 | .direction_input = da9052_gpio_direction_input, |
202 | .direction_output = da9052_gpio_direction_output, | 197 | .direction_output = da9052_gpio_direction_output, |
203 | .to_irq = da9052_gpio_to_irq, | 198 | .to_irq = da9052_gpio_to_irq, |
204 | .can_sleep = 1; | 199 | .can_sleep = 1, |
205 | .ngpio = 16; | 200 | .ngpio = 16, |
206 | .base = -1; | 201 | .base = -1, |
207 | }; | 202 | }; |
208 | 203 | ||
209 | static int __devinit da9052_gpio_probe(struct platform_device *pdev) | 204 | static int __devinit da9052_gpio_probe(struct platform_device *pdev) |
diff --git a/drivers/gpio/gpio-ml-ioh.c b/drivers/gpio/gpio-ml-ioh.c index ea8e73869250..461958fc2264 100644 --- a/drivers/gpio/gpio-ml-ioh.c +++ b/drivers/gpio/gpio-ml-ioh.c | |||
@@ -332,6 +332,34 @@ static void ioh_irq_mask(struct irq_data *d) | |||
332 | &chip->reg->regs[chip->ch].imask); | 332 | &chip->reg->regs[chip->ch].imask); |
333 | } | 333 | } |
334 | 334 | ||
335 | static void ioh_irq_disable(struct irq_data *d) | ||
336 | { | ||
337 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
338 | struct ioh_gpio *chip = gc->private; | ||
339 | unsigned long flags; | ||
340 | u32 ien; | ||
341 | |||
342 | spin_lock_irqsave(&chip->spinlock, flags); | ||
343 | ien = ioread32(&chip->reg->regs[chip->ch].ien); | ||
344 | ien &= ~(1 << (d->irq - chip->irq_base)); | ||
345 | iowrite32(ien, &chip->reg->regs[chip->ch].ien); | ||
346 | spin_unlock_irqrestore(&chip->spinlock, flags); | ||
347 | } | ||
348 | |||
349 | static void ioh_irq_enable(struct irq_data *d) | ||
350 | { | ||
351 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
352 | struct ioh_gpio *chip = gc->private; | ||
353 | unsigned long flags; | ||
354 | u32 ien; | ||
355 | |||
356 | spin_lock_irqsave(&chip->spinlock, flags); | ||
357 | ien = ioread32(&chip->reg->regs[chip->ch].ien); | ||
358 | ien |= 1 << (d->irq - chip->irq_base); | ||
359 | iowrite32(ien, &chip->reg->regs[chip->ch].ien); | ||
360 | spin_unlock_irqrestore(&chip->spinlock, flags); | ||
361 | } | ||
362 | |||
335 | static irqreturn_t ioh_gpio_handler(int irq, void *dev_id) | 363 | static irqreturn_t ioh_gpio_handler(int irq, void *dev_id) |
336 | { | 364 | { |
337 | struct ioh_gpio *chip = dev_id; | 365 | struct ioh_gpio *chip = dev_id; |
@@ -339,7 +367,7 @@ static irqreturn_t ioh_gpio_handler(int irq, void *dev_id) | |||
339 | int i, j; | 367 | int i, j; |
340 | int ret = IRQ_NONE; | 368 | int ret = IRQ_NONE; |
341 | 369 | ||
342 | for (i = 0; i < 8; i++) { | 370 | for (i = 0; i < 8; i++, chip++) { |
343 | reg_val = ioread32(&chip->reg->regs[i].istatus); | 371 | reg_val = ioread32(&chip->reg->regs[i].istatus); |
344 | for (j = 0; j < num_ports[i]; j++) { | 372 | for (j = 0; j < num_ports[i]; j++) { |
345 | if (reg_val & BIT(j)) { | 373 | if (reg_val & BIT(j)) { |
@@ -370,6 +398,8 @@ static __devinit void ioh_gpio_alloc_generic_chip(struct ioh_gpio *chip, | |||
370 | ct->chip.irq_mask = ioh_irq_mask; | 398 | ct->chip.irq_mask = ioh_irq_mask; |
371 | ct->chip.irq_unmask = ioh_irq_unmask; | 399 | ct->chip.irq_unmask = ioh_irq_unmask; |
372 | ct->chip.irq_set_type = ioh_irq_type; | 400 | ct->chip.irq_set_type = ioh_irq_type; |
401 | ct->chip.irq_disable = ioh_irq_disable; | ||
402 | ct->chip.irq_enable = ioh_irq_enable; | ||
373 | 403 | ||
374 | irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, | 404 | irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE, |
375 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | 405 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); |
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index ec3fcf0a7e12..5cd04b65c556 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c | |||
@@ -132,6 +132,15 @@ static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val | |||
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
135 | static int mpc5121_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) | ||
136 | { | ||
137 | /* GPIO 28..31 are input only on MPC5121 */ | ||
138 | if (gpio >= 28) | ||
139 | return -EINVAL; | ||
140 | |||
141 | return mpc8xxx_gpio_dir_out(gc, gpio, val); | ||
142 | } | ||
143 | |||
135 | static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) | 144 | static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) |
136 | { | 145 | { |
137 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); | 146 | struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc); |
@@ -340,11 +349,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np) | |||
340 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; | 349 | mm_gc->save_regs = mpc8xxx_gpio_save_regs; |
341 | gc->ngpio = MPC8XXX_GPIO_PINS; | 350 | gc->ngpio = MPC8XXX_GPIO_PINS; |
342 | gc->direction_input = mpc8xxx_gpio_dir_in; | 351 | gc->direction_input = mpc8xxx_gpio_dir_in; |
343 | gc->direction_output = mpc8xxx_gpio_dir_out; | 352 | gc->direction_output = of_device_is_compatible(np, "fsl,mpc5121-gpio") ? |
344 | if (of_device_is_compatible(np, "fsl,mpc8572-gpio")) | 353 | mpc5121_gpio_dir_out : mpc8xxx_gpio_dir_out; |
345 | gc->get = mpc8572_gpio_get; | 354 | gc->get = of_device_is_compatible(np, "fsl,mpc8572-gpio") ? |
346 | else | 355 | mpc8572_gpio_get : mpc8xxx_gpio_get; |
347 | gc->get = mpc8xxx_gpio_get; | ||
348 | gc->set = mpc8xxx_gpio_set; | 356 | gc->set = mpc8xxx_gpio_set; |
349 | gc->to_irq = mpc8xxx_gpio_to_irq; | 357 | gc->to_irq = mpc8xxx_gpio_to_irq; |
350 | 358 | ||
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index 093c90bd3c1d..4102f63230fd 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c | |||
@@ -238,10 +238,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id) | |||
238 | int ret, irq, i; | 238 | int ret, irq, i; |
239 | static DECLARE_BITMAP(init_irq, NR_IRQS); | 239 | static DECLARE_BITMAP(init_irq, NR_IRQS); |
240 | 240 | ||
241 | pdata = dev->dev.platform_data; | ||
242 | if (pdata == NULL) | ||
243 | return -ENODEV; | ||
244 | |||
245 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 241 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
246 | if (chip == NULL) | 242 | if (chip == NULL) |
247 | return -ENOMEM; | 243 | return -ENOMEM; |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d09a6e02dc95..004b048c5192 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -62,6 +62,7 @@ static int i915_capabilities(struct seq_file *m, void *data) | |||
62 | const struct intel_device_info *info = INTEL_INFO(dev); | 62 | const struct intel_device_info *info = INTEL_INFO(dev); |
63 | 63 | ||
64 | seq_printf(m, "gen: %d\n", info->gen); | 64 | seq_printf(m, "gen: %d\n", info->gen); |
65 | seq_printf(m, "pch: %d\n", INTEL_PCH_TYPE(dev)); | ||
65 | #define B(x) seq_printf(m, #x ": %s\n", yesno(info->x)) | 66 | #define B(x) seq_printf(m, #x ": %s\n", yesno(info->x)) |
66 | B(is_mobile); | 67 | B(is_mobile); |
67 | B(is_i85x); | 68 | B(is_i85x); |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index a9533c54c93c..a9ae374861e7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1454,6 +1454,14 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) | |||
1454 | 1454 | ||
1455 | diff1 = now - dev_priv->last_time1; | 1455 | diff1 = now - dev_priv->last_time1; |
1456 | 1456 | ||
1457 | /* Prevent division-by-zero if we are asking too fast. | ||
1458 | * Also, we don't get interesting results if we are polling | ||
1459 | * faster than once in 10ms, so just return the saved value | ||
1460 | * in such cases. | ||
1461 | */ | ||
1462 | if (diff1 <= 10) | ||
1463 | return dev_priv->chipset_power; | ||
1464 | |||
1457 | count1 = I915_READ(DMIEC); | 1465 | count1 = I915_READ(DMIEC); |
1458 | count2 = I915_READ(DDREC); | 1466 | count2 = I915_READ(DDREC); |
1459 | count3 = I915_READ(CSIEC); | 1467 | count3 = I915_READ(CSIEC); |
@@ -1484,6 +1492,8 @@ unsigned long i915_chipset_val(struct drm_i915_private *dev_priv) | |||
1484 | dev_priv->last_count1 = total_count; | 1492 | dev_priv->last_count1 = total_count; |
1485 | dev_priv->last_time1 = now; | 1493 | dev_priv->last_time1 = now; |
1486 | 1494 | ||
1495 | dev_priv->chipset_power = ret; | ||
1496 | |||
1487 | return ret; | 1497 | return ret; |
1488 | } | 1498 | } |
1489 | 1499 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 15bfa9145d2b..a1103fc6597d 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -58,15 +58,15 @@ module_param_named(powersave, i915_powersave, int, 0600); | |||
58 | MODULE_PARM_DESC(powersave, | 58 | MODULE_PARM_DESC(powersave, |
59 | "Enable powersavings, fbc, downclocking, etc. (default: true)"); | 59 | "Enable powersavings, fbc, downclocking, etc. (default: true)"); |
60 | 60 | ||
61 | unsigned int i915_semaphores __read_mostly = 0; | 61 | int i915_semaphores __read_mostly = -1; |
62 | module_param_named(semaphores, i915_semaphores, int, 0600); | 62 | module_param_named(semaphores, i915_semaphores, int, 0600); |
63 | MODULE_PARM_DESC(semaphores, | 63 | MODULE_PARM_DESC(semaphores, |
64 | "Use semaphores for inter-ring sync (default: false)"); | 64 | "Use semaphores for inter-ring sync (default: -1 (use per-chip defaults))"); |
65 | 65 | ||
66 | unsigned int i915_enable_rc6 __read_mostly = 0; | 66 | int i915_enable_rc6 __read_mostly = -1; |
67 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); | 67 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); |
68 | MODULE_PARM_DESC(i915_enable_rc6, | 68 | MODULE_PARM_DESC(i915_enable_rc6, |
69 | "Enable power-saving render C-state 6 (default: true)"); | 69 | "Enable power-saving render C-state 6 (default: -1 (use per-chip default)"); |
70 | 70 | ||
71 | int i915_enable_fbc __read_mostly = -1; | 71 | int i915_enable_fbc __read_mostly = -1; |
72 | module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); | 72 | module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); |
@@ -328,7 +328,7 @@ void intel_detect_pch(struct drm_device *dev) | |||
328 | } | 328 | } |
329 | } | 329 | } |
330 | 330 | ||
331 | static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | 331 | void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) |
332 | { | 332 | { |
333 | int count; | 333 | int count; |
334 | 334 | ||
@@ -344,6 +344,22 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | |||
344 | udelay(10); | 344 | udelay(10); |
345 | } | 345 | } |
346 | 346 | ||
347 | void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | ||
348 | { | ||
349 | int count; | ||
350 | |||
351 | count = 0; | ||
352 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1)) | ||
353 | udelay(10); | ||
354 | |||
355 | I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 1); | ||
356 | POSTING_READ(FORCEWAKE_MT); | ||
357 | |||
358 | count = 0; | ||
359 | while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0) | ||
360 | udelay(10); | ||
361 | } | ||
362 | |||
347 | /* | 363 | /* |
348 | * Generally this is called implicitly by the register read function. However, | 364 | * Generally this is called implicitly by the register read function. However, |
349 | * if some sequence requires the GT to not power down then this function should | 365 | * if some sequence requires the GT to not power down then this function should |
@@ -356,15 +372,21 @@ void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | |||
356 | 372 | ||
357 | /* Forcewake is atomic in case we get in here without the lock */ | 373 | /* Forcewake is atomic in case we get in here without the lock */ |
358 | if (atomic_add_return(1, &dev_priv->forcewake_count) == 1) | 374 | if (atomic_add_return(1, &dev_priv->forcewake_count) == 1) |
359 | __gen6_gt_force_wake_get(dev_priv); | 375 | dev_priv->display.force_wake_get(dev_priv); |
360 | } | 376 | } |
361 | 377 | ||
362 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | 378 | void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
363 | { | 379 | { |
364 | I915_WRITE_NOTRACE(FORCEWAKE, 0); | 380 | I915_WRITE_NOTRACE(FORCEWAKE, 0); |
365 | POSTING_READ(FORCEWAKE); | 381 | POSTING_READ(FORCEWAKE); |
366 | } | 382 | } |
367 | 383 | ||
384 | void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) | ||
385 | { | ||
386 | I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0); | ||
387 | POSTING_READ(FORCEWAKE_MT); | ||
388 | } | ||
389 | |||
368 | /* | 390 | /* |
369 | * see gen6_gt_force_wake_get() | 391 | * see gen6_gt_force_wake_get() |
370 | */ | 392 | */ |
@@ -373,7 +395,7 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | |||
373 | WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); | 395 | WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); |
374 | 396 | ||
375 | if (atomic_dec_and_test(&dev_priv->forcewake_count)) | 397 | if (atomic_dec_and_test(&dev_priv->forcewake_count)) |
376 | __gen6_gt_force_wake_put(dev_priv); | 398 | dev_priv->display.force_wake_put(dev_priv); |
377 | } | 399 | } |
378 | 400 | ||
379 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) | 401 | void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv) |
@@ -903,8 +925,9 @@ MODULE_LICENSE("GPL and additional rights"); | |||
903 | /* We give fast paths for the really cool registers */ | 925 | /* We give fast paths for the really cool registers */ |
904 | #define NEEDS_FORCE_WAKE(dev_priv, reg) \ | 926 | #define NEEDS_FORCE_WAKE(dev_priv, reg) \ |
905 | (((dev_priv)->info->gen >= 6) && \ | 927 | (((dev_priv)->info->gen >= 6) && \ |
906 | ((reg) < 0x40000) && \ | 928 | ((reg) < 0x40000) && \ |
907 | ((reg) != FORCEWAKE)) | 929 | ((reg) != FORCEWAKE) && \ |
930 | ((reg) != ECOBUS)) | ||
908 | 931 | ||
909 | #define __i915_read(x, y) \ | 932 | #define __i915_read(x, y) \ |
910 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ | 933 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4a9c1b979804..554bef7a3b9c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -107,6 +107,7 @@ struct opregion_header; | |||
107 | struct opregion_acpi; | 107 | struct opregion_acpi; |
108 | struct opregion_swsci; | 108 | struct opregion_swsci; |
109 | struct opregion_asle; | 109 | struct opregion_asle; |
110 | struct drm_i915_private; | ||
110 | 111 | ||
111 | struct intel_opregion { | 112 | struct intel_opregion { |
112 | struct opregion_header *header; | 113 | struct opregion_header *header; |
@@ -221,6 +222,8 @@ struct drm_i915_display_funcs { | |||
221 | struct drm_i915_gem_object *obj); | 222 | struct drm_i915_gem_object *obj); |
222 | int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, | 223 | int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
223 | int x, int y); | 224 | int x, int y); |
225 | void (*force_wake_get)(struct drm_i915_private *dev_priv); | ||
226 | void (*force_wake_put)(struct drm_i915_private *dev_priv); | ||
224 | /* clock updates for mode set */ | 227 | /* clock updates for mode set */ |
225 | /* cursor updates */ | 228 | /* cursor updates */ |
226 | /* render clock increase/decrease */ | 229 | /* render clock increase/decrease */ |
@@ -710,6 +713,7 @@ typedef struct drm_i915_private { | |||
710 | 713 | ||
711 | u64 last_count1; | 714 | u64 last_count1; |
712 | unsigned long last_time1; | 715 | unsigned long last_time1; |
716 | unsigned long chipset_power; | ||
713 | u64 last_count2; | 717 | u64 last_count2; |
714 | struct timespec last_time2; | 718 | struct timespec last_time2; |
715 | unsigned long gfx_power; | 719 | unsigned long gfx_power; |
@@ -998,11 +1002,11 @@ extern int i915_max_ioctl; | |||
998 | extern unsigned int i915_fbpercrtc __always_unused; | 1002 | extern unsigned int i915_fbpercrtc __always_unused; |
999 | extern int i915_panel_ignore_lid __read_mostly; | 1003 | extern int i915_panel_ignore_lid __read_mostly; |
1000 | extern unsigned int i915_powersave __read_mostly; | 1004 | extern unsigned int i915_powersave __read_mostly; |
1001 | extern unsigned int i915_semaphores __read_mostly; | 1005 | extern int i915_semaphores __read_mostly; |
1002 | extern unsigned int i915_lvds_downclock __read_mostly; | 1006 | extern unsigned int i915_lvds_downclock __read_mostly; |
1003 | extern int i915_panel_use_ssc __read_mostly; | 1007 | extern int i915_panel_use_ssc __read_mostly; |
1004 | extern int i915_vbt_sdvo_panel_type __read_mostly; | 1008 | extern int i915_vbt_sdvo_panel_type __read_mostly; |
1005 | extern unsigned int i915_enable_rc6 __read_mostly; | 1009 | extern int i915_enable_rc6 __read_mostly; |
1006 | extern int i915_enable_fbc __read_mostly; | 1010 | extern int i915_enable_fbc __read_mostly; |
1007 | extern bool i915_enable_hangcheck __read_mostly; | 1011 | extern bool i915_enable_hangcheck __read_mostly; |
1008 | 1012 | ||
@@ -1308,6 +1312,11 @@ extern void gen6_set_rps(struct drm_device *dev, u8 val); | |||
1308 | extern void intel_detect_pch(struct drm_device *dev); | 1312 | extern void intel_detect_pch(struct drm_device *dev); |
1309 | extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); | 1313 | extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); |
1310 | 1314 | ||
1315 | extern void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv); | ||
1316 | extern void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv); | ||
1317 | extern void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv); | ||
1318 | extern void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv); | ||
1319 | |||
1311 | /* overlay */ | 1320 | /* overlay */ |
1312 | #ifdef CONFIG_DEBUG_FS | 1321 | #ifdef CONFIG_DEBUG_FS |
1313 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); | 1322 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); |
@@ -1352,8 +1361,9 @@ void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); | |||
1352 | /* We give fast paths for the really cool registers */ | 1361 | /* We give fast paths for the really cool registers */ |
1353 | #define NEEDS_FORCE_WAKE(dev_priv, reg) \ | 1362 | #define NEEDS_FORCE_WAKE(dev_priv, reg) \ |
1354 | (((dev_priv)->info->gen >= 6) && \ | 1363 | (((dev_priv)->info->gen >= 6) && \ |
1355 | ((reg) < 0x40000) && \ | 1364 | ((reg) < 0x40000) && \ |
1356 | ((reg) != FORCEWAKE)) | 1365 | ((reg) != FORCEWAKE) && \ |
1366 | ((reg) != ECOBUS)) | ||
1357 | 1367 | ||
1358 | #define __i915_read(x, y) \ | 1368 | #define __i915_read(x, y) \ |
1359 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg); | 1369 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg); |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 3693e83a97f3..c681dc149d2a 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "i915_drv.h" | 32 | #include "i915_drv.h" |
33 | #include "i915_trace.h" | 33 | #include "i915_trace.h" |
34 | #include "intel_drv.h" | 34 | #include "intel_drv.h" |
35 | #include <linux/dma_remapping.h> | ||
35 | 36 | ||
36 | struct change_domains { | 37 | struct change_domains { |
37 | uint32_t invalidate_domains; | 38 | uint32_t invalidate_domains; |
@@ -746,6 +747,22 @@ i915_gem_execbuffer_flush(struct drm_device *dev, | |||
746 | return 0; | 747 | return 0; |
747 | } | 748 | } |
748 | 749 | ||
750 | static bool | ||
751 | intel_enable_semaphores(struct drm_device *dev) | ||
752 | { | ||
753 | if (INTEL_INFO(dev)->gen < 6) | ||
754 | return 0; | ||
755 | |||
756 | if (i915_semaphores >= 0) | ||
757 | return i915_semaphores; | ||
758 | |||
759 | /* Enable semaphores on SNB when IO remapping is off */ | ||
760 | if (INTEL_INFO(dev)->gen == 6) | ||
761 | return !intel_iommu_enabled; | ||
762 | |||
763 | return 1; | ||
764 | } | ||
765 | |||
749 | static int | 766 | static int |
750 | i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, | 767 | i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, |
751 | struct intel_ring_buffer *to) | 768 | struct intel_ring_buffer *to) |
@@ -758,7 +775,7 @@ i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, | |||
758 | return 0; | 775 | return 0; |
759 | 776 | ||
760 | /* XXX gpu semaphores are implicated in various hard hangs on SNB */ | 777 | /* XXX gpu semaphores are implicated in various hard hangs on SNB */ |
761 | if (INTEL_INFO(obj->base.dev)->gen < 6 || !i915_semaphores) | 778 | if (!intel_enable_semaphores(obj->base.dev)) |
762 | return i915_gem_object_wait_rendering(obj); | 779 | return i915_gem_object_wait_rendering(obj); |
763 | 780 | ||
764 | idx = intel_ring_sync_index(from, to); | 781 | idx = intel_ring_sync_index(from, to); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b080cc824001..a26d5b0a3690 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -3303,10 +3303,10 @@ | |||
3303 | /* or SDVOB */ | 3303 | /* or SDVOB */ |
3304 | #define HDMIB 0xe1140 | 3304 | #define HDMIB 0xe1140 |
3305 | #define PORT_ENABLE (1 << 31) | 3305 | #define PORT_ENABLE (1 << 31) |
3306 | #define TRANSCODER_A (0) | 3306 | #define TRANSCODER(pipe) ((pipe) << 30) |
3307 | #define TRANSCODER_B (1 << 30) | 3307 | #define TRANSCODER_CPT(pipe) ((pipe) << 29) |
3308 | #define TRANSCODER(pipe) ((pipe) << 30) | 3308 | #define TRANSCODER_MASK (1 << 30) |
3309 | #define TRANSCODER_MASK (1 << 30) | 3309 | #define TRANSCODER_MASK_CPT (3 << 29) |
3310 | #define COLOR_FORMAT_8bpc (0) | 3310 | #define COLOR_FORMAT_8bpc (0) |
3311 | #define COLOR_FORMAT_12bpc (3 << 26) | 3311 | #define COLOR_FORMAT_12bpc (3 << 26) |
3312 | #define SDVOB_HOTPLUG_ENABLE (1 << 23) | 3312 | #define SDVOB_HOTPLUG_ENABLE (1 << 23) |
@@ -3447,8 +3447,30 @@ | |||
3447 | #define EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B (0x38<<22) | 3447 | #define EDP_LINK_TRAIN_800_1200MV_0DB_SNB_B (0x38<<22) |
3448 | #define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22) | 3448 | #define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22) |
3449 | 3449 | ||
3450 | /* IVB */ | ||
3451 | #define EDP_LINK_TRAIN_400MV_0DB_IVB (0x24 <<22) | ||
3452 | #define EDP_LINK_TRAIN_400MV_3_5DB_IVB (0x2a <<22) | ||
3453 | #define EDP_LINK_TRAIN_400MV_6DB_IVB (0x2f <<22) | ||
3454 | #define EDP_LINK_TRAIN_600MV_0DB_IVB (0x30 <<22) | ||
3455 | #define EDP_LINK_TRAIN_600MV_3_5DB_IVB (0x36 <<22) | ||
3456 | #define EDP_LINK_TRAIN_800MV_0DB_IVB (0x38 <<22) | ||
3457 | #define EDP_LINK_TRAIN_800MV_3_5DB_IVB (0x33 <<22) | ||
3458 | |||
3459 | /* legacy values */ | ||
3460 | #define EDP_LINK_TRAIN_500MV_0DB_IVB (0x00 <<22) | ||
3461 | #define EDP_LINK_TRAIN_1000MV_0DB_IVB (0x20 <<22) | ||
3462 | #define EDP_LINK_TRAIN_500MV_3_5DB_IVB (0x02 <<22) | ||
3463 | #define EDP_LINK_TRAIN_1000MV_3_5DB_IVB (0x22 <<22) | ||
3464 | #define EDP_LINK_TRAIN_1000MV_6DB_IVB (0x23 <<22) | ||
3465 | |||
3466 | #define EDP_LINK_TRAIN_VOL_EMP_MASK_IVB (0x3f<<22) | ||
3467 | |||
3450 | #define FORCEWAKE 0xA18C | 3468 | #define FORCEWAKE 0xA18C |
3451 | #define FORCEWAKE_ACK 0x130090 | 3469 | #define FORCEWAKE_ACK 0x130090 |
3470 | #define FORCEWAKE_MT 0xa188 /* multi-threaded */ | ||
3471 | #define FORCEWAKE_MT_ACK 0x130040 | ||
3472 | #define ECOBUS 0xa180 | ||
3473 | #define FORCEWAKE_MT_ENABLE (1<<5) | ||
3452 | 3474 | ||
3453 | #define GT_FIFO_FREE_ENTRIES 0x120008 | 3475 | #define GT_FIFO_FREE_ENTRIES 0x120008 |
3454 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 | 3476 | #define GT_FIFO_NUM_RESERVED_ENTRIES 20 |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e77a863a3833..d809b038ca88 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -38,8 +38,8 @@ | |||
38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
39 | #include "i915_trace.h" | 39 | #include "i915_trace.h" |
40 | #include "drm_dp_helper.h" | 40 | #include "drm_dp_helper.h" |
41 | |||
42 | #include "drm_crtc_helper.h" | 41 | #include "drm_crtc_helper.h" |
42 | #include <linux/dma_remapping.h> | ||
43 | 43 | ||
44 | #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) | 44 | #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) |
45 | 45 | ||
@@ -4670,6 +4670,7 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) | |||
4670 | /** | 4670 | /** |
4671 | * intel_choose_pipe_bpp_dither - figure out what color depth the pipe should send | 4671 | * intel_choose_pipe_bpp_dither - figure out what color depth the pipe should send |
4672 | * @crtc: CRTC structure | 4672 | * @crtc: CRTC structure |
4673 | * @mode: requested mode | ||
4673 | * | 4674 | * |
4674 | * A pipe may be connected to one or more outputs. Based on the depth of the | 4675 | * A pipe may be connected to one or more outputs. Based on the depth of the |
4675 | * attached framebuffer, choose a good color depth to use on the pipe. | 4676 | * attached framebuffer, choose a good color depth to use on the pipe. |
@@ -4681,13 +4682,15 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) | |||
4681 | * HDMI supports only 8bpc or 12bpc, so clamp to 8bpc with dither for 10bpc | 4682 | * HDMI supports only 8bpc or 12bpc, so clamp to 8bpc with dither for 10bpc |
4682 | * Displays may support a restricted set as well, check EDID and clamp as | 4683 | * Displays may support a restricted set as well, check EDID and clamp as |
4683 | * appropriate. | 4684 | * appropriate. |
4685 | * DP may want to dither down to 6bpc to fit larger modes | ||
4684 | * | 4686 | * |
4685 | * RETURNS: | 4687 | * RETURNS: |
4686 | * Dithering requirement (i.e. false if display bpc and pipe bpc match, | 4688 | * Dithering requirement (i.e. false if display bpc and pipe bpc match, |
4687 | * true if they don't match). | 4689 | * true if they don't match). |
4688 | */ | 4690 | */ |
4689 | static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | 4691 | static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, |
4690 | unsigned int *pipe_bpp) | 4692 | unsigned int *pipe_bpp, |
4693 | struct drm_display_mode *mode) | ||
4691 | { | 4694 | { |
4692 | struct drm_device *dev = crtc->dev; | 4695 | struct drm_device *dev = crtc->dev; |
4693 | struct drm_i915_private *dev_priv = dev->dev_private; | 4696 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -4758,6 +4761,11 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
4758 | } | 4761 | } |
4759 | } | 4762 | } |
4760 | 4763 | ||
4764 | if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) { | ||
4765 | DRM_DEBUG_KMS("Dithering DP to 6bpc\n"); | ||
4766 | display_bpc = 6; | ||
4767 | } | ||
4768 | |||
4761 | /* | 4769 | /* |
4762 | * We could just drive the pipe at the highest bpc all the time and | 4770 | * We could just drive the pipe at the highest bpc all the time and |
4763 | * enable dithering as needed, but that costs bandwidth. So choose | 4771 | * enable dithering as needed, but that costs bandwidth. So choose |
@@ -5019,6 +5027,16 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
5019 | pipeconf &= ~PIPECONF_DOUBLE_WIDE; | 5027 | pipeconf &= ~PIPECONF_DOUBLE_WIDE; |
5020 | } | 5028 | } |
5021 | 5029 | ||
5030 | /* default to 8bpc */ | ||
5031 | pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN); | ||
5032 | if (is_dp) { | ||
5033 | if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) { | ||
5034 | pipeconf |= PIPECONF_BPP_6 | | ||
5035 | PIPECONF_DITHER_EN | | ||
5036 | PIPECONF_DITHER_TYPE_SP; | ||
5037 | } | ||
5038 | } | ||
5039 | |||
5022 | dpll |= DPLL_VCO_ENABLE; | 5040 | dpll |= DPLL_VCO_ENABLE; |
5023 | 5041 | ||
5024 | DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); | 5042 | DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); |
@@ -5480,7 +5498,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
5480 | /* determine panel color depth */ | 5498 | /* determine panel color depth */ |
5481 | temp = I915_READ(PIPECONF(pipe)); | 5499 | temp = I915_READ(PIPECONF(pipe)); |
5482 | temp &= ~PIPE_BPC_MASK; | 5500 | temp &= ~PIPE_BPC_MASK; |
5483 | dither = intel_choose_pipe_bpp_dither(crtc, &pipe_bpp); | 5501 | dither = intel_choose_pipe_bpp_dither(crtc, &pipe_bpp, mode); |
5484 | switch (pipe_bpp) { | 5502 | switch (pipe_bpp) { |
5485 | case 18: | 5503 | case 18: |
5486 | temp |= PIPE_6BPC; | 5504 | temp |= PIPE_6BPC; |
@@ -7189,11 +7207,16 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
7189 | work->old_fb_obj = intel_fb->obj; | 7207 | work->old_fb_obj = intel_fb->obj; |
7190 | INIT_WORK(&work->work, intel_unpin_work_fn); | 7208 | INIT_WORK(&work->work, intel_unpin_work_fn); |
7191 | 7209 | ||
7210 | ret = drm_vblank_get(dev, intel_crtc->pipe); | ||
7211 | if (ret) | ||
7212 | goto free_work; | ||
7213 | |||
7192 | /* We borrow the event spin lock for protecting unpin_work */ | 7214 | /* We borrow the event spin lock for protecting unpin_work */ |
7193 | spin_lock_irqsave(&dev->event_lock, flags); | 7215 | spin_lock_irqsave(&dev->event_lock, flags); |
7194 | if (intel_crtc->unpin_work) { | 7216 | if (intel_crtc->unpin_work) { |
7195 | spin_unlock_irqrestore(&dev->event_lock, flags); | 7217 | spin_unlock_irqrestore(&dev->event_lock, flags); |
7196 | kfree(work); | 7218 | kfree(work); |
7219 | drm_vblank_put(dev, intel_crtc->pipe); | ||
7197 | 7220 | ||
7198 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); | 7221 | DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); |
7199 | return -EBUSY; | 7222 | return -EBUSY; |
@@ -7212,10 +7235,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
7212 | 7235 | ||
7213 | crtc->fb = fb; | 7236 | crtc->fb = fb; |
7214 | 7237 | ||
7215 | ret = drm_vblank_get(dev, intel_crtc->pipe); | ||
7216 | if (ret) | ||
7217 | goto cleanup_objs; | ||
7218 | |||
7219 | work->pending_flip_obj = obj; | 7238 | work->pending_flip_obj = obj; |
7220 | 7239 | ||
7221 | work->enable_stall_check = true; | 7240 | work->enable_stall_check = true; |
@@ -7238,7 +7257,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
7238 | 7257 | ||
7239 | cleanup_pending: | 7258 | cleanup_pending: |
7240 | atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); | 7259 | atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); |
7241 | cleanup_objs: | ||
7242 | drm_gem_object_unreference(&work->old_fb_obj->base); | 7260 | drm_gem_object_unreference(&work->old_fb_obj->base); |
7243 | drm_gem_object_unreference(&obj->base); | 7261 | drm_gem_object_unreference(&obj->base); |
7244 | mutex_unlock(&dev->struct_mutex); | 7262 | mutex_unlock(&dev->struct_mutex); |
@@ -7247,6 +7265,8 @@ cleanup_objs: | |||
7247 | intel_crtc->unpin_work = NULL; | 7265 | intel_crtc->unpin_work = NULL; |
7248 | spin_unlock_irqrestore(&dev->event_lock, flags); | 7266 | spin_unlock_irqrestore(&dev->event_lock, flags); |
7249 | 7267 | ||
7268 | drm_vblank_put(dev, intel_crtc->pipe); | ||
7269 | free_work: | ||
7250 | kfree(work); | 7270 | kfree(work); |
7251 | 7271 | ||
7252 | return ret; | 7272 | return ret; |
@@ -7887,6 +7907,33 @@ void intel_init_emon(struct drm_device *dev) | |||
7887 | dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); | 7907 | dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); |
7888 | } | 7908 | } |
7889 | 7909 | ||
7910 | static bool intel_enable_rc6(struct drm_device *dev) | ||
7911 | { | ||
7912 | /* | ||
7913 | * Respect the kernel parameter if it is set | ||
7914 | */ | ||
7915 | if (i915_enable_rc6 >= 0) | ||
7916 | return i915_enable_rc6; | ||
7917 | |||
7918 | /* | ||
7919 | * Disable RC6 on Ironlake | ||
7920 | */ | ||
7921 | if (INTEL_INFO(dev)->gen == 5) | ||
7922 | return 0; | ||
7923 | |||
7924 | /* | ||
7925 | * Enable rc6 on Sandybridge if DMA remapping is disabled | ||
7926 | */ | ||
7927 | if (INTEL_INFO(dev)->gen == 6) { | ||
7928 | DRM_DEBUG_DRIVER("Sandybridge: intel_iommu_enabled %s -- RC6 %sabled\n", | ||
7929 | intel_iommu_enabled ? "true" : "false", | ||
7930 | !intel_iommu_enabled ? "en" : "dis"); | ||
7931 | return !intel_iommu_enabled; | ||
7932 | } | ||
7933 | DRM_DEBUG_DRIVER("RC6 enabled\n"); | ||
7934 | return 1; | ||
7935 | } | ||
7936 | |||
7890 | void gen6_enable_rps(struct drm_i915_private *dev_priv) | 7937 | void gen6_enable_rps(struct drm_i915_private *dev_priv) |
7891 | { | 7938 | { |
7892 | u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); | 7939 | u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); |
@@ -7923,7 +7970,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) | |||
7923 | I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); | 7970 | I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); |
7924 | I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ | 7971 | I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ |
7925 | 7972 | ||
7926 | if (i915_enable_rc6) | 7973 | if (intel_enable_rc6(dev_priv->dev)) |
7927 | rc6_mask = GEN6_RC_CTL_RC6p_ENABLE | | 7974 | rc6_mask = GEN6_RC_CTL_RC6p_ENABLE | |
7928 | GEN6_RC_CTL_RC6_ENABLE; | 7975 | GEN6_RC_CTL_RC6_ENABLE; |
7929 | 7976 | ||
@@ -8372,7 +8419,7 @@ void ironlake_enable_rc6(struct drm_device *dev) | |||
8372 | /* rc6 disabled by default due to repeated reports of hanging during | 8419 | /* rc6 disabled by default due to repeated reports of hanging during |
8373 | * boot and resume. | 8420 | * boot and resume. |
8374 | */ | 8421 | */ |
8375 | if (!i915_enable_rc6) | 8422 | if (!intel_enable_rc6(dev)) |
8376 | return; | 8423 | return; |
8377 | 8424 | ||
8378 | mutex_lock(&dev->struct_mutex); | 8425 | mutex_lock(&dev->struct_mutex); |
@@ -8491,6 +8538,28 @@ static void intel_init_display(struct drm_device *dev) | |||
8491 | 8538 | ||
8492 | /* For FIFO watermark updates */ | 8539 | /* For FIFO watermark updates */ |
8493 | if (HAS_PCH_SPLIT(dev)) { | 8540 | if (HAS_PCH_SPLIT(dev)) { |
8541 | dev_priv->display.force_wake_get = __gen6_gt_force_wake_get; | ||
8542 | dev_priv->display.force_wake_put = __gen6_gt_force_wake_put; | ||
8543 | |||
8544 | /* IVB configs may use multi-threaded forcewake */ | ||
8545 | if (IS_IVYBRIDGE(dev)) { | ||
8546 | u32 ecobus; | ||
8547 | |||
8548 | mutex_lock(&dev->struct_mutex); | ||
8549 | __gen6_gt_force_wake_mt_get(dev_priv); | ||
8550 | ecobus = I915_READ(ECOBUS); | ||
8551 | __gen6_gt_force_wake_mt_put(dev_priv); | ||
8552 | mutex_unlock(&dev->struct_mutex); | ||
8553 | |||
8554 | if (ecobus & FORCEWAKE_MT_ENABLE) { | ||
8555 | DRM_DEBUG_KMS("Using MT version of forcewake\n"); | ||
8556 | dev_priv->display.force_wake_get = | ||
8557 | __gen6_gt_force_wake_mt_get; | ||
8558 | dev_priv->display.force_wake_put = | ||
8559 | __gen6_gt_force_wake_mt_put; | ||
8560 | } | ||
8561 | } | ||
8562 | |||
8494 | if (HAS_PCH_IBX(dev)) | 8563 | if (HAS_PCH_IBX(dev)) |
8495 | dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating; | 8564 | dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating; |
8496 | else if (HAS_PCH_CPT(dev)) | 8565 | else if (HAS_PCH_CPT(dev)) |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 4d0358fad937..92b041b66e49 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -208,13 +208,15 @@ intel_dp_link_clock(uint8_t link_bw) | |||
208 | */ | 208 | */ |
209 | 209 | ||
210 | static int | 210 | static int |
211 | intel_dp_link_required(struct intel_dp *intel_dp, int pixel_clock) | 211 | intel_dp_link_required(struct intel_dp *intel_dp, int pixel_clock, int check_bpp) |
212 | { | 212 | { |
213 | struct drm_crtc *crtc = intel_dp->base.base.crtc; | 213 | struct drm_crtc *crtc = intel_dp->base.base.crtc; |
214 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 214 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
215 | int bpp = 24; | 215 | int bpp = 24; |
216 | 216 | ||
217 | if (intel_crtc) | 217 | if (check_bpp) |
218 | bpp = check_bpp; | ||
219 | else if (intel_crtc) | ||
218 | bpp = intel_crtc->bpp; | 220 | bpp = intel_crtc->bpp; |
219 | 221 | ||
220 | return (pixel_clock * bpp + 9) / 10; | 222 | return (pixel_clock * bpp + 9) / 10; |
@@ -233,6 +235,7 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
233 | struct intel_dp *intel_dp = intel_attached_dp(connector); | 235 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
234 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); | 236 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); |
235 | int max_lanes = intel_dp_max_lane_count(intel_dp); | 237 | int max_lanes = intel_dp_max_lane_count(intel_dp); |
238 | int max_rate, mode_rate; | ||
236 | 239 | ||
237 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { | 240 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { |
238 | if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay) | 241 | if (mode->hdisplay > intel_dp->panel_fixed_mode->hdisplay) |
@@ -242,9 +245,17 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
242 | return MODE_PANEL; | 245 | return MODE_PANEL; |
243 | } | 246 | } |
244 | 247 | ||
245 | if (intel_dp_link_required(intel_dp, mode->clock) | 248 | mode_rate = intel_dp_link_required(intel_dp, mode->clock, 0); |
246 | > intel_dp_max_data_rate(max_link_clock, max_lanes)) | 249 | max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes); |
247 | return MODE_CLOCK_HIGH; | 250 | |
251 | if (mode_rate > max_rate) { | ||
252 | mode_rate = intel_dp_link_required(intel_dp, | ||
253 | mode->clock, 18); | ||
254 | if (mode_rate > max_rate) | ||
255 | return MODE_CLOCK_HIGH; | ||
256 | else | ||
257 | mode->private_flags |= INTEL_MODE_DP_FORCE_6BPC; | ||
258 | } | ||
248 | 259 | ||
249 | if (mode->clock < 10000) | 260 | if (mode->clock < 10000) |
250 | return MODE_CLOCK_LOW; | 261 | return MODE_CLOCK_LOW; |
@@ -362,8 +373,8 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, | |||
362 | * clock divider. | 373 | * clock divider. |
363 | */ | 374 | */ |
364 | if (is_cpu_edp(intel_dp)) { | 375 | if (is_cpu_edp(intel_dp)) { |
365 | if (IS_GEN6(dev)) | 376 | if (IS_GEN6(dev) || IS_GEN7(dev)) |
366 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ | 377 | aux_clock_divider = 200; /* SNB & IVB eDP input clock at 400Mhz */ |
367 | else | 378 | else |
368 | aux_clock_divider = 225; /* eDP input clock at 450Mhz */ | 379 | aux_clock_divider = 225; /* eDP input clock at 450Mhz */ |
369 | } else if (HAS_PCH_SPLIT(dev)) | 380 | } else if (HAS_PCH_SPLIT(dev)) |
@@ -672,6 +683,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
672 | int lane_count, clock; | 683 | int lane_count, clock; |
673 | int max_lane_count = intel_dp_max_lane_count(intel_dp); | 684 | int max_lane_count = intel_dp_max_lane_count(intel_dp); |
674 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; | 685 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; |
686 | int bpp = mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 0; | ||
675 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | 687 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; |
676 | 688 | ||
677 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { | 689 | if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { |
@@ -689,7 +701,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
689 | for (clock = 0; clock <= max_clock; clock++) { | 701 | for (clock = 0; clock <= max_clock; clock++) { |
690 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 702 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
691 | 703 | ||
692 | if (intel_dp_link_required(intel_dp, mode->clock) | 704 | if (intel_dp_link_required(intel_dp, mode->clock, bpp) |
693 | <= link_avail) { | 705 | <= link_avail) { |
694 | intel_dp->link_bw = bws[clock]; | 706 | intel_dp->link_bw = bws[clock]; |
695 | intel_dp->lane_count = lane_count; | 707 | intel_dp->lane_count = lane_count; |
@@ -817,10 +829,11 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
817 | } | 829 | } |
818 | 830 | ||
819 | /* | 831 | /* |
820 | * There are three kinds of DP registers: | 832 | * There are four kinds of DP registers: |
821 | * | 833 | * |
822 | * IBX PCH | 834 | * IBX PCH |
823 | * CPU | 835 | * SNB CPU |
836 | * IVB CPU | ||
824 | * CPT PCH | 837 | * CPT PCH |
825 | * | 838 | * |
826 | * IBX PCH and CPU are the same for almost everything, | 839 | * IBX PCH and CPU are the same for almost everything, |
@@ -873,7 +886,25 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
873 | 886 | ||
874 | /* Split out the IBX/CPU vs CPT settings */ | 887 | /* Split out the IBX/CPU vs CPT settings */ |
875 | 888 | ||
876 | if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { | 889 | if (is_cpu_edp(intel_dp) && IS_GEN7(dev)) { |
890 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | ||
891 | intel_dp->DP |= DP_SYNC_HS_HIGH; | ||
892 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | ||
893 | intel_dp->DP |= DP_SYNC_VS_HIGH; | ||
894 | intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; | ||
895 | |||
896 | if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) | ||
897 | intel_dp->DP |= DP_ENHANCED_FRAMING; | ||
898 | |||
899 | intel_dp->DP |= intel_crtc->pipe << 29; | ||
900 | |||
901 | /* don't miss out required setting for eDP */ | ||
902 | intel_dp->DP |= DP_PLL_ENABLE; | ||
903 | if (adjusted_mode->clock < 200000) | ||
904 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; | ||
905 | else | ||
906 | intel_dp->DP |= DP_PLL_FREQ_270MHZ; | ||
907 | } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { | ||
877 | intel_dp->DP |= intel_dp->color_range; | 908 | intel_dp->DP |= intel_dp->color_range; |
878 | 909 | ||
879 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 910 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
@@ -1375,34 +1406,59 @@ static char *link_train_names[] = { | |||
1375 | * These are source-specific values; current Intel hardware supports | 1406 | * These are source-specific values; current Intel hardware supports |
1376 | * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB | 1407 | * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB |
1377 | */ | 1408 | */ |
1378 | #define I830_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_800 | ||
1379 | #define I830_DP_VOLTAGE_MAX_CPT DP_TRAIN_VOLTAGE_SWING_1200 | ||
1380 | 1409 | ||
1381 | static uint8_t | 1410 | static uint8_t |
1382 | intel_dp_pre_emphasis_max(uint8_t voltage_swing) | 1411 | intel_dp_voltage_max(struct intel_dp *intel_dp) |
1383 | { | 1412 | { |
1384 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | 1413 | struct drm_device *dev = intel_dp->base.base.dev; |
1385 | case DP_TRAIN_VOLTAGE_SWING_400: | 1414 | |
1386 | return DP_TRAIN_PRE_EMPHASIS_6; | 1415 | if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) |
1387 | case DP_TRAIN_VOLTAGE_SWING_600: | 1416 | return DP_TRAIN_VOLTAGE_SWING_800; |
1388 | return DP_TRAIN_PRE_EMPHASIS_6; | 1417 | else if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) |
1389 | case DP_TRAIN_VOLTAGE_SWING_800: | 1418 | return DP_TRAIN_VOLTAGE_SWING_1200; |
1390 | return DP_TRAIN_PRE_EMPHASIS_3_5; | 1419 | else |
1391 | case DP_TRAIN_VOLTAGE_SWING_1200: | 1420 | return DP_TRAIN_VOLTAGE_SWING_800; |
1392 | default: | 1421 | } |
1393 | return DP_TRAIN_PRE_EMPHASIS_0; | 1422 | |
1423 | static uint8_t | ||
1424 | intel_dp_pre_emphasis_max(struct intel_dp *intel_dp, uint8_t voltage_swing) | ||
1425 | { | ||
1426 | struct drm_device *dev = intel_dp->base.base.dev; | ||
1427 | |||
1428 | if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) { | ||
1429 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | ||
1430 | case DP_TRAIN_VOLTAGE_SWING_400: | ||
1431 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
1432 | case DP_TRAIN_VOLTAGE_SWING_600: | ||
1433 | case DP_TRAIN_VOLTAGE_SWING_800: | ||
1434 | return DP_TRAIN_PRE_EMPHASIS_3_5; | ||
1435 | default: | ||
1436 | return DP_TRAIN_PRE_EMPHASIS_0; | ||
1437 | } | ||
1438 | } else { | ||
1439 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | ||
1440 | case DP_TRAIN_VOLTAGE_SWING_400: | ||
1441 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
1442 | case DP_TRAIN_VOLTAGE_SWING_600: | ||
1443 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
1444 | case DP_TRAIN_VOLTAGE_SWING_800: | ||
1445 | return DP_TRAIN_PRE_EMPHASIS_3_5; | ||
1446 | case DP_TRAIN_VOLTAGE_SWING_1200: | ||
1447 | default: | ||
1448 | return DP_TRAIN_PRE_EMPHASIS_0; | ||
1449 | } | ||
1394 | } | 1450 | } |
1395 | } | 1451 | } |
1396 | 1452 | ||
1397 | static void | 1453 | static void |
1398 | intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) | 1454 | intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) |
1399 | { | 1455 | { |
1400 | struct drm_device *dev = intel_dp->base.base.dev; | ||
1401 | uint8_t v = 0; | 1456 | uint8_t v = 0; |
1402 | uint8_t p = 0; | 1457 | uint8_t p = 0; |
1403 | int lane; | 1458 | int lane; |
1404 | uint8_t *adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS); | 1459 | uint8_t *adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS); |
1405 | int voltage_max; | 1460 | uint8_t voltage_max; |
1461 | uint8_t preemph_max; | ||
1406 | 1462 | ||
1407 | for (lane = 0; lane < intel_dp->lane_count; lane++) { | 1463 | for (lane = 0; lane < intel_dp->lane_count; lane++) { |
1408 | uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane); | 1464 | uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane); |
@@ -1414,15 +1470,13 @@ intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_ST | |||
1414 | p = this_p; | 1470 | p = this_p; |
1415 | } | 1471 | } |
1416 | 1472 | ||
1417 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) | 1473 | voltage_max = intel_dp_voltage_max(intel_dp); |
1418 | voltage_max = I830_DP_VOLTAGE_MAX_CPT; | ||
1419 | else | ||
1420 | voltage_max = I830_DP_VOLTAGE_MAX; | ||
1421 | if (v >= voltage_max) | 1474 | if (v >= voltage_max) |
1422 | v = voltage_max | DP_TRAIN_MAX_SWING_REACHED; | 1475 | v = voltage_max | DP_TRAIN_MAX_SWING_REACHED; |
1423 | 1476 | ||
1424 | if (p >= intel_dp_pre_emphasis_max(v)) | 1477 | preemph_max = intel_dp_pre_emphasis_max(intel_dp, v); |
1425 | p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | 1478 | if (p >= preemph_max) |
1479 | p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | ||
1426 | 1480 | ||
1427 | for (lane = 0; lane < 4; lane++) | 1481 | for (lane = 0; lane < 4; lane++) |
1428 | intel_dp->train_set[lane] = v | p; | 1482 | intel_dp->train_set[lane] = v | p; |
@@ -1494,6 +1548,37 @@ intel_gen6_edp_signal_levels(uint8_t train_set) | |||
1494 | } | 1548 | } |
1495 | } | 1549 | } |
1496 | 1550 | ||
1551 | /* Gen7's DP voltage swing and pre-emphasis control */ | ||
1552 | static uint32_t | ||
1553 | intel_gen7_edp_signal_levels(uint8_t train_set) | ||
1554 | { | ||
1555 | int signal_levels = train_set & (DP_TRAIN_VOLTAGE_SWING_MASK | | ||
1556 | DP_TRAIN_PRE_EMPHASIS_MASK); | ||
1557 | switch (signal_levels) { | ||
1558 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0: | ||
1559 | return EDP_LINK_TRAIN_400MV_0DB_IVB; | ||
1560 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_3_5: | ||
1561 | return EDP_LINK_TRAIN_400MV_3_5DB_IVB; | ||
1562 | case DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_6: | ||
1563 | return EDP_LINK_TRAIN_400MV_6DB_IVB; | ||
1564 | |||
1565 | case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_0: | ||
1566 | return EDP_LINK_TRAIN_600MV_0DB_IVB; | ||
1567 | case DP_TRAIN_VOLTAGE_SWING_600 | DP_TRAIN_PRE_EMPHASIS_3_5: | ||
1568 | return EDP_LINK_TRAIN_600MV_3_5DB_IVB; | ||
1569 | |||
1570 | case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_0: | ||
1571 | return EDP_LINK_TRAIN_800MV_0DB_IVB; | ||
1572 | case DP_TRAIN_VOLTAGE_SWING_800 | DP_TRAIN_PRE_EMPHASIS_3_5: | ||
1573 | return EDP_LINK_TRAIN_800MV_3_5DB_IVB; | ||
1574 | |||
1575 | default: | ||
1576 | DRM_DEBUG_KMS("Unsupported voltage swing/pre-emphasis level:" | ||
1577 | "0x%x\n", signal_levels); | ||
1578 | return EDP_LINK_TRAIN_500MV_0DB_IVB; | ||
1579 | } | ||
1580 | } | ||
1581 | |||
1497 | static uint8_t | 1582 | static uint8_t |
1498 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | 1583 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], |
1499 | int lane) | 1584 | int lane) |
@@ -1599,7 +1684,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1599 | DP_LINK_CONFIGURATION_SIZE); | 1684 | DP_LINK_CONFIGURATION_SIZE); |
1600 | 1685 | ||
1601 | DP |= DP_PORT_EN; | 1686 | DP |= DP_PORT_EN; |
1602 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) | 1687 | |
1688 | if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) | ||
1603 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1689 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
1604 | else | 1690 | else |
1605 | DP &= ~DP_LINK_TRAIN_MASK; | 1691 | DP &= ~DP_LINK_TRAIN_MASK; |
@@ -1613,7 +1699,11 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1613 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 1699 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
1614 | uint32_t signal_levels; | 1700 | uint32_t signal_levels; |
1615 | 1701 | ||
1616 | if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { | 1702 | |
1703 | if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) { | ||
1704 | signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]); | ||
1705 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels; | ||
1706 | } else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { | ||
1617 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1707 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1618 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1708 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1619 | } else { | 1709 | } else { |
@@ -1622,7 +1712,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) | |||
1622 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1712 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1623 | } | 1713 | } |
1624 | 1714 | ||
1625 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) | 1715 | if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) |
1626 | reg = DP | DP_LINK_TRAIN_PAT_1_CPT; | 1716 | reg = DP | DP_LINK_TRAIN_PAT_1_CPT; |
1627 | else | 1717 | else |
1628 | reg = DP | DP_LINK_TRAIN_PAT_1; | 1718 | reg = DP | DP_LINK_TRAIN_PAT_1; |
@@ -1703,7 +1793,10 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1703 | break; | 1793 | break; |
1704 | } | 1794 | } |
1705 | 1795 | ||
1706 | if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { | 1796 | if (IS_GEN7(dev) && is_cpu_edp(intel_dp)) { |
1797 | signal_levels = intel_gen7_edp_signal_levels(intel_dp->train_set[0]); | ||
1798 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_IVB) | signal_levels; | ||
1799 | } else if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { | ||
1707 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); | 1800 | signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); |
1708 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1801 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1709 | } else { | 1802 | } else { |
@@ -1711,7 +1804,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1711 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1804 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1712 | } | 1805 | } |
1713 | 1806 | ||
1714 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) | 1807 | if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) |
1715 | reg = DP | DP_LINK_TRAIN_PAT_2_CPT; | 1808 | reg = DP | DP_LINK_TRAIN_PAT_2_CPT; |
1716 | else | 1809 | else |
1717 | reg = DP | DP_LINK_TRAIN_PAT_2; | 1810 | reg = DP | DP_LINK_TRAIN_PAT_2; |
@@ -1752,7 +1845,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) | |||
1752 | ++tries; | 1845 | ++tries; |
1753 | } | 1846 | } |
1754 | 1847 | ||
1755 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) | 1848 | if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) |
1756 | reg = DP | DP_LINK_TRAIN_OFF_CPT; | 1849 | reg = DP | DP_LINK_TRAIN_OFF_CPT; |
1757 | else | 1850 | else |
1758 | reg = DP | DP_LINK_TRAIN_OFF; | 1851 | reg = DP | DP_LINK_TRAIN_OFF; |
@@ -1782,7 +1875,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1782 | udelay(100); | 1875 | udelay(100); |
1783 | } | 1876 | } |
1784 | 1877 | ||
1785 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) { | 1878 | if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) { |
1786 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1879 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
1787 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); | 1880 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); |
1788 | } else { | 1881 | } else { |
@@ -1794,7 +1887,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1794 | msleep(17); | 1887 | msleep(17); |
1795 | 1888 | ||
1796 | if (is_edp(intel_dp)) { | 1889 | if (is_edp(intel_dp)) { |
1797 | if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) | 1890 | if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) |
1798 | DP |= DP_LINK_TRAIN_OFF_CPT; | 1891 | DP |= DP_LINK_TRAIN_OFF_CPT; |
1799 | else | 1892 | else |
1800 | DP |= DP_LINK_TRAIN_OFF; | 1893 | DP |= DP_LINK_TRAIN_OFF; |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index bd9a604b73da..a1b4343814e8 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -110,6 +110,7 @@ | |||
110 | /* drm_display_mode->private_flags */ | 110 | /* drm_display_mode->private_flags */ |
111 | #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) | 111 | #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) |
112 | #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) | 112 | #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) |
113 | #define INTEL_MODE_DP_FORCE_6BPC (0x10) | ||
113 | 114 | ||
114 | static inline void | 115 | static inline void |
115 | intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, | 116 | intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 42f165a520de..e44191132ac4 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -715,6 +715,14 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
715 | DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"), | 715 | DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"), |
716 | }, | 716 | }, |
717 | }, | 717 | }, |
718 | { | ||
719 | .callback = intel_no_lvds_dmi_callback, | ||
720 | .ident = "Asus AT5NM10T-I", | ||
721 | .matches = { | ||
722 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), | ||
723 | DMI_MATCH(DMI_BOARD_NAME, "AT5NM10T-I"), | ||
724 | }, | ||
725 | }, | ||
718 | 726 | ||
719 | { } /* terminating entry */ | 727 | { } /* terminating entry */ |
720 | }; | 728 | }; |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 21f60b7d69a3..04d79fd1dc9d 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -178,13 +178,10 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev) | |||
178 | if (HAS_PCH_SPLIT(dev)) { | 178 | if (HAS_PCH_SPLIT(dev)) { |
179 | max >>= 16; | 179 | max >>= 16; |
180 | } else { | 180 | } else { |
181 | if (IS_PINEVIEW(dev)) { | 181 | if (INTEL_INFO(dev)->gen < 4) |
182 | max >>= 17; | 182 | max >>= 17; |
183 | } else { | 183 | else |
184 | max >>= 16; | 184 | max >>= 16; |
185 | if (INTEL_INFO(dev)->gen < 4) | ||
186 | max &= ~1; | ||
187 | } | ||
188 | 185 | ||
189 | if (is_backlight_combination_mode(dev)) | 186 | if (is_backlight_combination_mode(dev)) |
190 | max *= 0xff; | 187 | max *= 0xff; |
@@ -203,13 +200,12 @@ u32 intel_panel_get_backlight(struct drm_device *dev) | |||
203 | val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; | 200 | val = I915_READ(BLC_PWM_CPU_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; |
204 | } else { | 201 | } else { |
205 | val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; | 202 | val = I915_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; |
206 | if (IS_PINEVIEW(dev)) | 203 | if (INTEL_INFO(dev)->gen < 4) |
207 | val >>= 1; | 204 | val >>= 1; |
208 | 205 | ||
209 | if (is_backlight_combination_mode(dev)) { | 206 | if (is_backlight_combination_mode(dev)) { |
210 | u8 lbpc; | 207 | u8 lbpc; |
211 | 208 | ||
212 | val &= ~1; | ||
213 | pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc); | 209 | pci_read_config_byte(dev->pdev, PCI_LBPC, &lbpc); |
214 | val *= lbpc; | 210 | val *= lbpc; |
215 | } | 211 | } |
@@ -246,11 +242,9 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev, u32 level | |||
246 | } | 242 | } |
247 | 243 | ||
248 | tmp = I915_READ(BLC_PWM_CTL); | 244 | tmp = I915_READ(BLC_PWM_CTL); |
249 | if (IS_PINEVIEW(dev)) { | 245 | if (INTEL_INFO(dev)->gen < 4) |
250 | tmp &= ~(BACKLIGHT_DUTY_CYCLE_MASK - 1); | ||
251 | level <<= 1; | 246 | level <<= 1; |
252 | } else | 247 | tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK; |
253 | tmp &= ~BACKLIGHT_DUTY_CYCLE_MASK; | ||
254 | I915_WRITE(BLC_PWM_CTL, tmp | level); | 248 | I915_WRITE(BLC_PWM_CTL, tmp | level); |
255 | } | 249 | } |
256 | 250 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 3003fb25aefd..f7b9268df266 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK) | 50 | #define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK) |
51 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) | 51 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) |
52 | #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) | 52 | #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) |
53 | #define IS_DIGITAL(c) (c->output_flag & (SDVO_TMDS_MASK | SDVO_LVDS_MASK)) | ||
53 | 54 | ||
54 | 55 | ||
55 | static const char *tv_format_names[] = { | 56 | static const char *tv_format_names[] = { |
@@ -1086,8 +1087,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1086 | } | 1087 | } |
1087 | sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; | 1088 | sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; |
1088 | } | 1089 | } |
1089 | if (intel_crtc->pipe == 1) | 1090 | |
1090 | sdvox |= SDVO_PIPE_B_SELECT; | 1091 | if (INTEL_PCH_TYPE(dev) >= PCH_CPT) |
1092 | sdvox |= TRANSCODER_CPT(intel_crtc->pipe); | ||
1093 | else | ||
1094 | sdvox |= TRANSCODER(intel_crtc->pipe); | ||
1095 | |||
1091 | if (intel_sdvo->has_hdmi_audio) | 1096 | if (intel_sdvo->has_hdmi_audio) |
1092 | sdvox |= SDVO_AUDIO_ENABLE; | 1097 | sdvox |= SDVO_AUDIO_ENABLE; |
1093 | 1098 | ||
@@ -1314,6 +1319,18 @@ intel_sdvo_tmds_sink_detect(struct drm_connector *connector) | |||
1314 | return status; | 1319 | return status; |
1315 | } | 1320 | } |
1316 | 1321 | ||
1322 | static bool | ||
1323 | intel_sdvo_connector_matches_edid(struct intel_sdvo_connector *sdvo, | ||
1324 | struct edid *edid) | ||
1325 | { | ||
1326 | bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); | ||
1327 | bool connector_is_digital = !!IS_DIGITAL(sdvo); | ||
1328 | |||
1329 | DRM_DEBUG_KMS("connector_is_digital? %d, monitor_is_digital? %d\n", | ||
1330 | connector_is_digital, monitor_is_digital); | ||
1331 | return connector_is_digital == monitor_is_digital; | ||
1332 | } | ||
1333 | |||
1317 | static enum drm_connector_status | 1334 | static enum drm_connector_status |
1318 | intel_sdvo_detect(struct drm_connector *connector, bool force) | 1335 | intel_sdvo_detect(struct drm_connector *connector, bool force) |
1319 | { | 1336 | { |
@@ -1358,10 +1375,12 @@ intel_sdvo_detect(struct drm_connector *connector, bool force) | |||
1358 | if (edid == NULL) | 1375 | if (edid == NULL) |
1359 | edid = intel_sdvo_get_analog_edid(connector); | 1376 | edid = intel_sdvo_get_analog_edid(connector); |
1360 | if (edid != NULL) { | 1377 | if (edid != NULL) { |
1361 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | 1378 | if (intel_sdvo_connector_matches_edid(intel_sdvo_connector, |
1362 | ret = connector_status_disconnected; | 1379 | edid)) |
1363 | else | ||
1364 | ret = connector_status_connected; | 1380 | ret = connector_status_connected; |
1381 | else | ||
1382 | ret = connector_status_disconnected; | ||
1383 | |||
1365 | connector->display_info.raw_edid = NULL; | 1384 | connector->display_info.raw_edid = NULL; |
1366 | kfree(edid); | 1385 | kfree(edid); |
1367 | } else | 1386 | } else |
@@ -1402,11 +1421,8 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
1402 | edid = intel_sdvo_get_analog_edid(connector); | 1421 | edid = intel_sdvo_get_analog_edid(connector); |
1403 | 1422 | ||
1404 | if (edid != NULL) { | 1423 | if (edid != NULL) { |
1405 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); | 1424 | if (intel_sdvo_connector_matches_edid(to_intel_sdvo_connector(connector), |
1406 | bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); | 1425 | edid)) { |
1407 | bool connector_is_digital = !!IS_TMDS(intel_sdvo_connector); | ||
1408 | |||
1409 | if (connector_is_digital == monitor_is_digital) { | ||
1410 | drm_mode_connector_update_edid_property(connector, edid); | 1426 | drm_mode_connector_update_edid_property(connector, edid); |
1411 | drm_add_edid_modes(connector, edid); | 1427 | drm_add_edid_modes(connector, edid); |
1412 | } | 1428 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 06e413e6a920..4b27efa4405b 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -233,13 +233,12 @@ u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder) | |||
233 | switch (radeon_encoder->encoder_id) { | 233 | switch (radeon_encoder->encoder_id) { |
234 | case ENCODER_OBJECT_ID_TRAVIS: | 234 | case ENCODER_OBJECT_ID_TRAVIS: |
235 | case ENCODER_OBJECT_ID_NUTMEG: | 235 | case ENCODER_OBJECT_ID_NUTMEG: |
236 | return true; | 236 | return radeon_encoder->encoder_id; |
237 | default: | 237 | default: |
238 | return false; | 238 | return ENCODER_OBJECT_ID_NONE; |
239 | } | 239 | } |
240 | } | 240 | } |
241 | 241 | return ENCODER_OBJECT_ID_NONE; | |
242 | return false; | ||
243 | } | 242 | } |
244 | 243 | ||
245 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, | 244 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 8cca91a93bde..dc279706ca70 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -390,6 +390,11 @@ extern int vmw_context_check(struct vmw_private *dev_priv, | |||
390 | struct ttm_object_file *tfile, | 390 | struct ttm_object_file *tfile, |
391 | int id, | 391 | int id, |
392 | struct vmw_resource **p_res); | 392 | struct vmw_resource **p_res); |
393 | extern int vmw_user_lookup_handle(struct vmw_private *dev_priv, | ||
394 | struct ttm_object_file *tfile, | ||
395 | uint32_t handle, | ||
396 | struct vmw_surface **out_surf, | ||
397 | struct vmw_dma_buffer **out_buf); | ||
393 | extern void vmw_surface_res_free(struct vmw_resource *res); | 398 | extern void vmw_surface_res_free(struct vmw_resource *res); |
394 | extern int vmw_surface_init(struct vmw_private *dev_priv, | 399 | extern int vmw_surface_init(struct vmw_private *dev_priv, |
395 | struct vmw_surface *srf, | 400 | struct vmw_surface *srf, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c index 03bbc2a6f9a7..a0c2f12b1e1b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | |||
@@ -33,6 +33,7 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv) | |||
33 | { | 33 | { |
34 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; | 34 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
35 | uint32_t fifo_min, hwversion; | 35 | uint32_t fifo_min, hwversion; |
36 | const struct vmw_fifo_state *fifo = &dev_priv->fifo; | ||
36 | 37 | ||
37 | if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO)) | 38 | if (!(dev_priv->capabilities & SVGA_CAP_EXTENDED_FIFO)) |
38 | return false; | 39 | return false; |
@@ -41,7 +42,12 @@ bool vmw_fifo_have_3d(struct vmw_private *dev_priv) | |||
41 | if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int)) | 42 | if (fifo_min <= SVGA_FIFO_3D_HWVERSION * sizeof(unsigned int)) |
42 | return false; | 43 | return false; |
43 | 44 | ||
44 | hwversion = ioread32(fifo_mem + SVGA_FIFO_3D_HWVERSION); | 45 | hwversion = ioread32(fifo_mem + |
46 | ((fifo->capabilities & | ||
47 | SVGA_FIFO_CAP_3D_HWVERSION_REVISED) ? | ||
48 | SVGA_FIFO_3D_HWVERSION_REVISED : | ||
49 | SVGA_FIFO_3D_HWVERSION)); | ||
50 | |||
45 | if (hwversion == 0) | 51 | if (hwversion == 0) |
46 | return false; | 52 | return false; |
47 | 53 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 3f6343502d1f..66917c6c3813 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
@@ -58,8 +58,14 @@ int vmw_getparam_ioctl(struct drm_device *dev, void *data, | |||
58 | case DRM_VMW_PARAM_FIFO_HW_VERSION: | 58 | case DRM_VMW_PARAM_FIFO_HW_VERSION: |
59 | { | 59 | { |
60 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; | 60 | __le32 __iomem *fifo_mem = dev_priv->mmio_virt; |
61 | 61 | const struct vmw_fifo_state *fifo = &dev_priv->fifo; | |
62 | param->value = ioread32(fifo_mem + SVGA_FIFO_3D_HWVERSION); | 62 | |
63 | param->value = | ||
64 | ioread32(fifo_mem + | ||
65 | ((fifo->capabilities & | ||
66 | SVGA_FIFO_CAP_3D_HWVERSION_REVISED) ? | ||
67 | SVGA_FIFO_3D_HWVERSION_REVISED : | ||
68 | SVGA_FIFO_3D_HWVERSION)); | ||
63 | break; | 69 | break; |
64 | } | 70 | } |
65 | default: | 71 | default: |
@@ -140,7 +146,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, | |||
140 | goto out_clips; | 146 | goto out_clips; |
141 | } | 147 | } |
142 | 148 | ||
143 | clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); | 149 | clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); |
144 | if (clips == NULL) { | 150 | if (clips == NULL) { |
145 | DRM_ERROR("Failed to allocate clip rect list.\n"); | 151 | DRM_ERROR("Failed to allocate clip rect list.\n"); |
146 | ret = -ENOMEM; | 152 | ret = -ENOMEM; |
@@ -166,13 +172,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, | |||
166 | ret = -EINVAL; | 172 | ret = -EINVAL; |
167 | goto out_no_fb; | 173 | goto out_no_fb; |
168 | } | 174 | } |
169 | |||
170 | vfb = vmw_framebuffer_to_vfb(obj_to_fb(obj)); | 175 | vfb = vmw_framebuffer_to_vfb(obj_to_fb(obj)); |
171 | if (!vfb->dmabuf) { | ||
172 | DRM_ERROR("Framebuffer not dmabuf backed.\n"); | ||
173 | ret = -EINVAL; | ||
174 | goto out_no_fb; | ||
175 | } | ||
176 | 176 | ||
177 | ret = ttm_read_lock(&vmaster->lock, true); | 177 | ret = ttm_read_lock(&vmaster->lock, true); |
178 | if (unlikely(ret != 0)) | 178 | if (unlikely(ret != 0)) |
@@ -232,7 +232,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data, | |||
232 | goto out_clips; | 232 | goto out_clips; |
233 | } | 233 | } |
234 | 234 | ||
235 | clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); | 235 | clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); |
236 | if (clips == NULL) { | 236 | if (clips == NULL) { |
237 | DRM_ERROR("Failed to allocate clip rect list.\n"); | 237 | DRM_ERROR("Failed to allocate clip rect list.\n"); |
238 | ret = -ENOMEM; | 238 | ret = -ENOMEM; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index 37d40545ed77..8aa1dbb45c67 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -31,6 +31,44 @@ | |||
31 | /* Might need a hrtimer here? */ | 31 | /* Might need a hrtimer here? */ |
32 | #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) | 32 | #define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1) |
33 | 33 | ||
34 | |||
35 | struct vmw_clip_rect { | ||
36 | int x1, x2, y1, y2; | ||
37 | }; | ||
38 | |||
39 | /** | ||
40 | * Clip @num_rects number of @rects against @clip storing the | ||
41 | * results in @out_rects and the number of passed rects in @out_num. | ||
42 | */ | ||
43 | void vmw_clip_cliprects(struct drm_clip_rect *rects, | ||
44 | int num_rects, | ||
45 | struct vmw_clip_rect clip, | ||
46 | SVGASignedRect *out_rects, | ||
47 | int *out_num) | ||
48 | { | ||
49 | int i, k; | ||
50 | |||
51 | for (i = 0, k = 0; i < num_rects; i++) { | ||
52 | int x1 = max_t(int, clip.x1, rects[i].x1); | ||
53 | int y1 = max_t(int, clip.y1, rects[i].y1); | ||
54 | int x2 = min_t(int, clip.x2, rects[i].x2); | ||
55 | int y2 = min_t(int, clip.y2, rects[i].y2); | ||
56 | |||
57 | if (x1 >= x2) | ||
58 | continue; | ||
59 | if (y1 >= y2) | ||
60 | continue; | ||
61 | |||
62 | out_rects[k].left = x1; | ||
63 | out_rects[k].top = y1; | ||
64 | out_rects[k].right = x2; | ||
65 | out_rects[k].bottom = y2; | ||
66 | k++; | ||
67 | } | ||
68 | |||
69 | *out_num = k; | ||
70 | } | ||
71 | |||
34 | void vmw_display_unit_cleanup(struct vmw_display_unit *du) | 72 | void vmw_display_unit_cleanup(struct vmw_display_unit *du) |
35 | { | 73 | { |
36 | if (du->cursor_surface) | 74 | if (du->cursor_surface) |
@@ -82,6 +120,43 @@ int vmw_cursor_update_image(struct vmw_private *dev_priv, | |||
82 | return 0; | 120 | return 0; |
83 | } | 121 | } |
84 | 122 | ||
123 | int vmw_cursor_update_dmabuf(struct vmw_private *dev_priv, | ||
124 | struct vmw_dma_buffer *dmabuf, | ||
125 | u32 width, u32 height, | ||
126 | u32 hotspotX, u32 hotspotY) | ||
127 | { | ||
128 | struct ttm_bo_kmap_obj map; | ||
129 | unsigned long kmap_offset; | ||
130 | unsigned long kmap_num; | ||
131 | void *virtual; | ||
132 | bool dummy; | ||
133 | int ret; | ||
134 | |||
135 | kmap_offset = 0; | ||
136 | kmap_num = (width*height*4 + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
137 | |||
138 | ret = ttm_bo_reserve(&dmabuf->base, true, false, false, 0); | ||
139 | if (unlikely(ret != 0)) { | ||
140 | DRM_ERROR("reserve failed\n"); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | |||
144 | ret = ttm_bo_kmap(&dmabuf->base, kmap_offset, kmap_num, &map); | ||
145 | if (unlikely(ret != 0)) | ||
146 | goto err_unreserve; | ||
147 | |||
148 | virtual = ttm_kmap_obj_virtual(&map, &dummy); | ||
149 | ret = vmw_cursor_update_image(dev_priv, virtual, width, height, | ||
150 | hotspotX, hotspotY); | ||
151 | |||
152 | ttm_bo_kunmap(&map); | ||
153 | err_unreserve: | ||
154 | ttm_bo_unreserve(&dmabuf->base); | ||
155 | |||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | |||
85 | void vmw_cursor_update_position(struct vmw_private *dev_priv, | 160 | void vmw_cursor_update_position(struct vmw_private *dev_priv, |
86 | bool show, int x, int y) | 161 | bool show, int x, int y) |
87 | { | 162 | { |
@@ -110,24 +185,21 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |||
110 | return -EINVAL; | 185 | return -EINVAL; |
111 | 186 | ||
112 | if (handle) { | 187 | if (handle) { |
113 | ret = vmw_user_surface_lookup_handle(dev_priv, tfile, | 188 | ret = vmw_user_lookup_handle(dev_priv, tfile, |
114 | handle, &surface); | 189 | handle, &surface, &dmabuf); |
115 | if (!ret) { | 190 | if (ret) { |
116 | if (!surface->snooper.image) { | 191 | DRM_ERROR("failed to find surface or dmabuf: %i\n", ret); |
117 | DRM_ERROR("surface not suitable for cursor\n"); | 192 | return -EINVAL; |
118 | vmw_surface_unreference(&surface); | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | } else { | ||
122 | ret = vmw_user_dmabuf_lookup(tfile, | ||
123 | handle, &dmabuf); | ||
124 | if (ret) { | ||
125 | DRM_ERROR("failed to find surface or dmabuf: %i\n", ret); | ||
126 | return -EINVAL; | ||
127 | } | ||
128 | } | 193 | } |
129 | } | 194 | } |
130 | 195 | ||
196 | /* need to do this before taking down old image */ | ||
197 | if (surface && !surface->snooper.image) { | ||
198 | DRM_ERROR("surface not suitable for cursor\n"); | ||
199 | vmw_surface_unreference(&surface); | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | |||
131 | /* takedown old cursor */ | 203 | /* takedown old cursor */ |
132 | if (du->cursor_surface) { | 204 | if (du->cursor_surface) { |
133 | du->cursor_surface->snooper.crtc = NULL; | 205 | du->cursor_surface->snooper.crtc = NULL; |
@@ -146,36 +218,11 @@ int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, | |||
146 | vmw_cursor_update_image(dev_priv, surface->snooper.image, | 218 | vmw_cursor_update_image(dev_priv, surface->snooper.image, |
147 | 64, 64, du->hotspot_x, du->hotspot_y); | 219 | 64, 64, du->hotspot_x, du->hotspot_y); |
148 | } else if (dmabuf) { | 220 | } else if (dmabuf) { |
149 | struct ttm_bo_kmap_obj map; | ||
150 | unsigned long kmap_offset; | ||
151 | unsigned long kmap_num; | ||
152 | void *virtual; | ||
153 | bool dummy; | ||
154 | |||
155 | /* vmw_user_surface_lookup takes one reference */ | 221 | /* vmw_user_surface_lookup takes one reference */ |
156 | du->cursor_dmabuf = dmabuf; | 222 | du->cursor_dmabuf = dmabuf; |
157 | 223 | ||
158 | kmap_offset = 0; | 224 | ret = vmw_cursor_update_dmabuf(dev_priv, dmabuf, width, height, |
159 | kmap_num = (64*64*4) >> PAGE_SHIFT; | 225 | du->hotspot_x, du->hotspot_y); |
160 | |||
161 | ret = ttm_bo_reserve(&dmabuf->base, true, false, false, 0); | ||
162 | if (unlikely(ret != 0)) { | ||
163 | DRM_ERROR("reserve failed\n"); | ||
164 | return -EINVAL; | ||
165 | } | ||
166 | |||
167 | ret = ttm_bo_kmap(&dmabuf->base, kmap_offset, kmap_num, &map); | ||
168 | if (unlikely(ret != 0)) | ||
169 | goto err_unreserve; | ||
170 | |||
171 | virtual = ttm_kmap_obj_virtual(&map, &dummy); | ||
172 | vmw_cursor_update_image(dev_priv, virtual, 64, 64, | ||
173 | du->hotspot_x, du->hotspot_y); | ||
174 | |||
175 | ttm_bo_kunmap(&map); | ||
176 | err_unreserve: | ||
177 | ttm_bo_unreserve(&dmabuf->base); | ||
178 | |||
179 | } else { | 226 | } else { |
180 | vmw_cursor_update_position(dev_priv, false, 0, 0); | 227 | vmw_cursor_update_position(dev_priv, false, 0, 0); |
181 | return 0; | 228 | return 0; |
@@ -377,8 +424,9 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, | |||
377 | struct drm_clip_rect *clips, | 424 | struct drm_clip_rect *clips, |
378 | unsigned num_clips, int inc) | 425 | unsigned num_clips, int inc) |
379 | { | 426 | { |
380 | struct drm_clip_rect *clips_ptr; | ||
381 | struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; | 427 | struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; |
428 | struct drm_clip_rect *clips_ptr; | ||
429 | struct drm_clip_rect *tmp; | ||
382 | struct drm_crtc *crtc; | 430 | struct drm_crtc *crtc; |
383 | size_t fifo_size; | 431 | size_t fifo_size; |
384 | int i, num_units; | 432 | int i, num_units; |
@@ -391,7 +439,6 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, | |||
391 | } *cmd; | 439 | } *cmd; |
392 | SVGASignedRect *blits; | 440 | SVGASignedRect *blits; |
393 | 441 | ||
394 | |||
395 | num_units = 0; | 442 | num_units = 0; |
396 | list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, | 443 | list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, |
397 | head) { | 444 | head) { |
@@ -402,13 +449,24 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, | |||
402 | 449 | ||
403 | BUG_ON(!clips || !num_clips); | 450 | BUG_ON(!clips || !num_clips); |
404 | 451 | ||
452 | tmp = kzalloc(sizeof(*tmp) * num_clips, GFP_KERNEL); | ||
453 | if (unlikely(tmp == NULL)) { | ||
454 | DRM_ERROR("Temporary cliprect memory alloc failed.\n"); | ||
455 | return -ENOMEM; | ||
456 | } | ||
457 | |||
405 | fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips; | 458 | fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips; |
406 | cmd = kzalloc(fifo_size, GFP_KERNEL); | 459 | cmd = kzalloc(fifo_size, GFP_KERNEL); |
407 | if (unlikely(cmd == NULL)) { | 460 | if (unlikely(cmd == NULL)) { |
408 | DRM_ERROR("Temporary fifo memory alloc failed.\n"); | 461 | DRM_ERROR("Temporary fifo memory alloc failed.\n"); |
409 | return -ENOMEM; | 462 | ret = -ENOMEM; |
463 | goto out_free_tmp; | ||
410 | } | 464 | } |
411 | 465 | ||
466 | /* setup blits pointer */ | ||
467 | blits = (SVGASignedRect *)&cmd[1]; | ||
468 | |||
469 | /* initial clip region */ | ||
412 | left = clips->x1; | 470 | left = clips->x1; |
413 | right = clips->x2; | 471 | right = clips->x2; |
414 | top = clips->y1; | 472 | top = clips->y1; |
@@ -434,45 +492,60 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, | |||
434 | cmd->body.srcRect.bottom = bottom; | 492 | cmd->body.srcRect.bottom = bottom; |
435 | 493 | ||
436 | clips_ptr = clips; | 494 | clips_ptr = clips; |
437 | blits = (SVGASignedRect *)&cmd[1]; | ||
438 | for (i = 0; i < num_clips; i++, clips_ptr += inc) { | 495 | for (i = 0; i < num_clips; i++, clips_ptr += inc) { |
439 | blits[i].left = clips_ptr->x1 - left; | 496 | tmp[i].x1 = clips_ptr->x1 - left; |
440 | blits[i].right = clips_ptr->x2 - left; | 497 | tmp[i].x2 = clips_ptr->x2 - left; |
441 | blits[i].top = clips_ptr->y1 - top; | 498 | tmp[i].y1 = clips_ptr->y1 - top; |
442 | blits[i].bottom = clips_ptr->y2 - top; | 499 | tmp[i].y2 = clips_ptr->y2 - top; |
443 | } | 500 | } |
444 | 501 | ||
445 | /* do per unit writing, reuse fifo for each */ | 502 | /* do per unit writing, reuse fifo for each */ |
446 | for (i = 0; i < num_units; i++) { | 503 | for (i = 0; i < num_units; i++) { |
447 | struct vmw_display_unit *unit = units[i]; | 504 | struct vmw_display_unit *unit = units[i]; |
448 | int clip_x1 = left - unit->crtc.x; | 505 | struct vmw_clip_rect clip; |
449 | int clip_y1 = top - unit->crtc.y; | 506 | int num; |
450 | int clip_x2 = right - unit->crtc.x; | 507 | |
451 | int clip_y2 = bottom - unit->crtc.y; | 508 | clip.x1 = left - unit->crtc.x; |
509 | clip.y1 = top - unit->crtc.y; | ||
510 | clip.x2 = right - unit->crtc.x; | ||
511 | clip.y2 = bottom - unit->crtc.y; | ||
452 | 512 | ||
453 | /* skip any crtcs that misses the clip region */ | 513 | /* skip any crtcs that misses the clip region */ |
454 | if (clip_x1 >= unit->crtc.mode.hdisplay || | 514 | if (clip.x1 >= unit->crtc.mode.hdisplay || |
455 | clip_y1 >= unit->crtc.mode.vdisplay || | 515 | clip.y1 >= unit->crtc.mode.vdisplay || |
456 | clip_x2 <= 0 || clip_y2 <= 0) | 516 | clip.x2 <= 0 || clip.y2 <= 0) |
457 | continue; | 517 | continue; |
458 | 518 | ||
519 | /* | ||
520 | * In order for the clip rects to be correctly scaled | ||
521 | * the src and dest rects needs to be the same size. | ||
522 | */ | ||
523 | cmd->body.destRect.left = clip.x1; | ||
524 | cmd->body.destRect.right = clip.x2; | ||
525 | cmd->body.destRect.top = clip.y1; | ||
526 | cmd->body.destRect.bottom = clip.y2; | ||
527 | |||
528 | /* create a clip rect of the crtc in dest coords */ | ||
529 | clip.x2 = unit->crtc.mode.hdisplay - clip.x1; | ||
530 | clip.y2 = unit->crtc.mode.vdisplay - clip.y1; | ||
531 | clip.x1 = 0 - clip.x1; | ||
532 | clip.y1 = 0 - clip.y1; | ||
533 | |||
459 | /* need to reset sid as it is changed by execbuf */ | 534 | /* need to reset sid as it is changed by execbuf */ |
460 | cmd->body.srcImage.sid = cpu_to_le32(framebuffer->user_handle); | 535 | cmd->body.srcImage.sid = cpu_to_le32(framebuffer->user_handle); |
461 | |||
462 | cmd->body.destScreenId = unit->unit; | 536 | cmd->body.destScreenId = unit->unit; |
463 | 537 | ||
464 | /* | 538 | /* clip and write blits to cmd stream */ |
465 | * The blit command is a lot more resilient then the | 539 | vmw_clip_cliprects(tmp, num_clips, clip, blits, &num); |
466 | * readback command when it comes to clip rects. So its | ||
467 | * okay to go out of bounds. | ||
468 | */ | ||
469 | 540 | ||
470 | cmd->body.destRect.left = clip_x1; | 541 | /* if no cliprects hit skip this */ |
471 | cmd->body.destRect.right = clip_x2; | 542 | if (num == 0) |
472 | cmd->body.destRect.top = clip_y1; | 543 | continue; |
473 | cmd->body.destRect.bottom = clip_y2; | ||
474 | 544 | ||
475 | 545 | ||
546 | /* recalculate package length */ | ||
547 | fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num; | ||
548 | cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); | ||
476 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, | 549 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, |
477 | fifo_size, 0, NULL); | 550 | fifo_size, 0, NULL); |
478 | 551 | ||
@@ -480,7 +553,10 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, | |||
480 | break; | 553 | break; |
481 | } | 554 | } |
482 | 555 | ||
556 | |||
483 | kfree(cmd); | 557 | kfree(cmd); |
558 | out_free_tmp: | ||
559 | kfree(tmp); | ||
484 | 560 | ||
485 | return ret; | 561 | return ret; |
486 | } | 562 | } |
@@ -556,6 +632,10 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, | |||
556 | * Sanity checks. | 632 | * Sanity checks. |
557 | */ | 633 | */ |
558 | 634 | ||
635 | /* Surface must be marked as a scanout. */ | ||
636 | if (unlikely(!surface->scanout)) | ||
637 | return -EINVAL; | ||
638 | |||
559 | if (unlikely(surface->mip_levels[0] != 1 || | 639 | if (unlikely(surface->mip_levels[0] != 1 || |
560 | surface->num_sizes != 1 || | 640 | surface->num_sizes != 1 || |
561 | surface->sizes[0].width < mode_cmd->width || | 641 | surface->sizes[0].width < mode_cmd->width || |
@@ -782,6 +862,7 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv, | |||
782 | int clip_y1 = clips_ptr->y1 - unit->crtc.y; | 862 | int clip_y1 = clips_ptr->y1 - unit->crtc.y; |
783 | int clip_x2 = clips_ptr->x2 - unit->crtc.x; | 863 | int clip_x2 = clips_ptr->x2 - unit->crtc.x; |
784 | int clip_y2 = clips_ptr->y2 - unit->crtc.y; | 864 | int clip_y2 = clips_ptr->y2 - unit->crtc.y; |
865 | int move_x, move_y; | ||
785 | 866 | ||
786 | /* skip any crtcs that misses the clip region */ | 867 | /* skip any crtcs that misses the clip region */ |
787 | if (clip_x1 >= unit->crtc.mode.hdisplay || | 868 | if (clip_x1 >= unit->crtc.mode.hdisplay || |
@@ -789,12 +870,21 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv, | |||
789 | clip_x2 <= 0 || clip_y2 <= 0) | 870 | clip_x2 <= 0 || clip_y2 <= 0) |
790 | continue; | 871 | continue; |
791 | 872 | ||
873 | /* clip size to crtc size */ | ||
874 | clip_x2 = min_t(int, clip_x2, unit->crtc.mode.hdisplay); | ||
875 | clip_y2 = min_t(int, clip_y2, unit->crtc.mode.vdisplay); | ||
876 | |||
877 | /* translate both src and dest to bring clip into screen */ | ||
878 | move_x = min_t(int, clip_x1, 0); | ||
879 | move_y = min_t(int, clip_y1, 0); | ||
880 | |||
881 | /* actual translate done here */ | ||
792 | blits[hit_num].header = SVGA_CMD_BLIT_GMRFB_TO_SCREEN; | 882 | blits[hit_num].header = SVGA_CMD_BLIT_GMRFB_TO_SCREEN; |
793 | blits[hit_num].body.destScreenId = unit->unit; | 883 | blits[hit_num].body.destScreenId = unit->unit; |
794 | blits[hit_num].body.srcOrigin.x = clips_ptr->x1; | 884 | blits[hit_num].body.srcOrigin.x = clips_ptr->x1 - move_x; |
795 | blits[hit_num].body.srcOrigin.y = clips_ptr->y1; | 885 | blits[hit_num].body.srcOrigin.y = clips_ptr->y1 - move_y; |
796 | blits[hit_num].body.destRect.left = clip_x1; | 886 | blits[hit_num].body.destRect.left = clip_x1 - move_x; |
797 | blits[hit_num].body.destRect.top = clip_y1; | 887 | blits[hit_num].body.destRect.top = clip_y1 - move_y; |
798 | blits[hit_num].body.destRect.right = clip_x2; | 888 | blits[hit_num].body.destRect.right = clip_x2; |
799 | blits[hit_num].body.destRect.bottom = clip_y2; | 889 | blits[hit_num].body.destRect.bottom = clip_y2; |
800 | hit_num++; | 890 | hit_num++; |
@@ -1033,46 +1123,29 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, | |||
1033 | return ERR_PTR(-ENOENT); | 1123 | return ERR_PTR(-ENOENT); |
1034 | } | 1124 | } |
1035 | 1125 | ||
1036 | /** | 1126 | /* returns either a dmabuf or surface */ |
1037 | * End conditioned code. | 1127 | ret = vmw_user_lookup_handle(dev_priv, tfile, |
1038 | */ | 1128 | mode_cmd->handle, |
1039 | 1129 | &surface, &bo); | |
1040 | ret = vmw_user_surface_lookup_handle(dev_priv, tfile, | ||
1041 | mode_cmd->handle, &surface); | ||
1042 | if (ret) | 1130 | if (ret) |
1043 | goto try_dmabuf; | 1131 | goto err_out; |
1044 | 1132 | ||
1045 | if (!surface->scanout) | 1133 | /* Create the new framebuffer depending one what we got back */ |
1046 | goto err_not_scanout; | 1134 | if (bo) |
1047 | 1135 | ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, bo, &vfb, | |
1048 | ret = vmw_kms_new_framebuffer_surface(dev_priv, file_priv, surface, | 1136 | mode_cmd); |
1049 | &vfb, mode_cmd); | 1137 | else if (surface) |
1050 | 1138 | ret = vmw_kms_new_framebuffer_surface(dev_priv, file_priv, | |
1051 | /* vmw_user_surface_lookup takes one ref so does new_fb */ | 1139 | surface, &vfb, mode_cmd); |
1052 | vmw_surface_unreference(&surface); | 1140 | else |
1053 | 1141 | BUG(); | |
1054 | if (ret) { | ||
1055 | DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret); | ||
1056 | ttm_base_object_unref(&user_obj); | ||
1057 | return ERR_PTR(ret); | ||
1058 | } else | ||
1059 | vfb->user_obj = user_obj; | ||
1060 | return &vfb->base; | ||
1061 | |||
1062 | try_dmabuf: | ||
1063 | DRM_INFO("%s: trying buffer\n", __func__); | ||
1064 | |||
1065 | ret = vmw_user_dmabuf_lookup(tfile, mode_cmd->handle, &bo); | ||
1066 | if (ret) { | ||
1067 | DRM_ERROR("failed to find buffer: %i\n", ret); | ||
1068 | return ERR_PTR(-ENOENT); | ||
1069 | } | ||
1070 | |||
1071 | ret = vmw_kms_new_framebuffer_dmabuf(dev_priv, bo, &vfb, | ||
1072 | mode_cmd); | ||
1073 | 1142 | ||
1074 | /* vmw_user_dmabuf_lookup takes one ref so does new_fb */ | 1143 | err_out: |
1075 | vmw_dmabuf_unreference(&bo); | 1144 | /* vmw_user_lookup_handle takes one ref so does new_fb */ |
1145 | if (bo) | ||
1146 | vmw_dmabuf_unreference(&bo); | ||
1147 | if (surface) | ||
1148 | vmw_surface_unreference(&surface); | ||
1076 | 1149 | ||
1077 | if (ret) { | 1150 | if (ret) { |
1078 | DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret); | 1151 | DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret); |
@@ -1082,14 +1155,6 @@ try_dmabuf: | |||
1082 | vfb->user_obj = user_obj; | 1155 | vfb->user_obj = user_obj; |
1083 | 1156 | ||
1084 | return &vfb->base; | 1157 | return &vfb->base; |
1085 | |||
1086 | err_not_scanout: | ||
1087 | DRM_ERROR("surface not marked as scanout\n"); | ||
1088 | /* vmw_user_surface_lookup takes one ref */ | ||
1089 | vmw_surface_unreference(&surface); | ||
1090 | ttm_base_object_unref(&user_obj); | ||
1091 | |||
1092 | return ERR_PTR(-EINVAL); | ||
1093 | } | 1158 | } |
1094 | 1159 | ||
1095 | static struct drm_mode_config_funcs vmw_kms_funcs = { | 1160 | static struct drm_mode_config_funcs vmw_kms_funcs = { |
@@ -1106,10 +1171,12 @@ int vmw_kms_present(struct vmw_private *dev_priv, | |||
1106 | uint32_t num_clips) | 1171 | uint32_t num_clips) |
1107 | { | 1172 | { |
1108 | struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; | 1173 | struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; |
1174 | struct drm_clip_rect *tmp; | ||
1109 | struct drm_crtc *crtc; | 1175 | struct drm_crtc *crtc; |
1110 | size_t fifo_size; | 1176 | size_t fifo_size; |
1111 | int i, k, num_units; | 1177 | int i, k, num_units; |
1112 | int ret = 0; /* silence warning */ | 1178 | int ret = 0; /* silence warning */ |
1179 | int left, right, top, bottom; | ||
1113 | 1180 | ||
1114 | struct { | 1181 | struct { |
1115 | SVGA3dCmdHeader header; | 1182 | SVGA3dCmdHeader header; |
@@ -1127,60 +1194,95 @@ int vmw_kms_present(struct vmw_private *dev_priv, | |||
1127 | BUG_ON(surface == NULL); | 1194 | BUG_ON(surface == NULL); |
1128 | BUG_ON(!clips || !num_clips); | 1195 | BUG_ON(!clips || !num_clips); |
1129 | 1196 | ||
1197 | tmp = kzalloc(sizeof(*tmp) * num_clips, GFP_KERNEL); | ||
1198 | if (unlikely(tmp == NULL)) { | ||
1199 | DRM_ERROR("Temporary cliprect memory alloc failed.\n"); | ||
1200 | return -ENOMEM; | ||
1201 | } | ||
1202 | |||
1130 | fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips; | 1203 | fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num_clips; |
1131 | cmd = kmalloc(fifo_size, GFP_KERNEL); | 1204 | cmd = kmalloc(fifo_size, GFP_KERNEL); |
1132 | if (unlikely(cmd == NULL)) { | 1205 | if (unlikely(cmd == NULL)) { |
1133 | DRM_ERROR("Failed to allocate temporary fifo memory.\n"); | 1206 | DRM_ERROR("Failed to allocate temporary fifo memory.\n"); |
1134 | return -ENOMEM; | 1207 | ret = -ENOMEM; |
1208 | goto out_free_tmp; | ||
1209 | } | ||
1210 | |||
1211 | left = clips->x; | ||
1212 | right = clips->x + clips->w; | ||
1213 | top = clips->y; | ||
1214 | bottom = clips->y + clips->h; | ||
1215 | |||
1216 | for (i = 1; i < num_clips; i++) { | ||
1217 | left = min_t(int, left, (int)clips[i].x); | ||
1218 | right = max_t(int, right, (int)clips[i].x + clips[i].w); | ||
1219 | top = min_t(int, top, (int)clips[i].y); | ||
1220 | bottom = max_t(int, bottom, (int)clips[i].y + clips[i].h); | ||
1135 | } | 1221 | } |
1136 | 1222 | ||
1137 | /* only need to do this once */ | 1223 | /* only need to do this once */ |
1138 | memset(cmd, 0, fifo_size); | 1224 | memset(cmd, 0, fifo_size); |
1139 | cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN); | 1225 | cmd->header.id = cpu_to_le32(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN); |
1140 | cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); | ||
1141 | |||
1142 | cmd->body.srcRect.left = 0; | ||
1143 | cmd->body.srcRect.right = surface->sizes[0].width; | ||
1144 | cmd->body.srcRect.top = 0; | ||
1145 | cmd->body.srcRect.bottom = surface->sizes[0].height; | ||
1146 | 1226 | ||
1147 | blits = (SVGASignedRect *)&cmd[1]; | 1227 | blits = (SVGASignedRect *)&cmd[1]; |
1228 | |||
1229 | cmd->body.srcRect.left = left; | ||
1230 | cmd->body.srcRect.right = right; | ||
1231 | cmd->body.srcRect.top = top; | ||
1232 | cmd->body.srcRect.bottom = bottom; | ||
1233 | |||
1148 | for (i = 0; i < num_clips; i++) { | 1234 | for (i = 0; i < num_clips; i++) { |
1149 | blits[i].left = clips[i].x; | 1235 | tmp[i].x1 = clips[i].x - left; |
1150 | blits[i].right = clips[i].x + clips[i].w; | 1236 | tmp[i].x2 = clips[i].x + clips[i].w - left; |
1151 | blits[i].top = clips[i].y; | 1237 | tmp[i].y1 = clips[i].y - top; |
1152 | blits[i].bottom = clips[i].y + clips[i].h; | 1238 | tmp[i].y2 = clips[i].y + clips[i].h - top; |
1153 | } | 1239 | } |
1154 | 1240 | ||
1155 | for (k = 0; k < num_units; k++) { | 1241 | for (k = 0; k < num_units; k++) { |
1156 | struct vmw_display_unit *unit = units[k]; | 1242 | struct vmw_display_unit *unit = units[k]; |
1157 | int clip_x1 = destX - unit->crtc.x; | 1243 | struct vmw_clip_rect clip; |
1158 | int clip_y1 = destY - unit->crtc.y; | 1244 | int num; |
1159 | int clip_x2 = clip_x1 + surface->sizes[0].width; | 1245 | |
1160 | int clip_y2 = clip_y1 + surface->sizes[0].height; | 1246 | clip.x1 = left + destX - unit->crtc.x; |
1247 | clip.y1 = top + destY - unit->crtc.y; | ||
1248 | clip.x2 = right + destX - unit->crtc.x; | ||
1249 | clip.y2 = bottom + destY - unit->crtc.y; | ||
1161 | 1250 | ||
1162 | /* skip any crtcs that misses the clip region */ | 1251 | /* skip any crtcs that misses the clip region */ |
1163 | if (clip_x1 >= unit->crtc.mode.hdisplay || | 1252 | if (clip.x1 >= unit->crtc.mode.hdisplay || |
1164 | clip_y1 >= unit->crtc.mode.vdisplay || | 1253 | clip.y1 >= unit->crtc.mode.vdisplay || |
1165 | clip_x2 <= 0 || clip_y2 <= 0) | 1254 | clip.x2 <= 0 || clip.y2 <= 0) |
1166 | continue; | 1255 | continue; |
1167 | 1256 | ||
1257 | /* | ||
1258 | * In order for the clip rects to be correctly scaled | ||
1259 | * the src and dest rects needs to be the same size. | ||
1260 | */ | ||
1261 | cmd->body.destRect.left = clip.x1; | ||
1262 | cmd->body.destRect.right = clip.x2; | ||
1263 | cmd->body.destRect.top = clip.y1; | ||
1264 | cmd->body.destRect.bottom = clip.y2; | ||
1265 | |||
1266 | /* create a clip rect of the crtc in dest coords */ | ||
1267 | clip.x2 = unit->crtc.mode.hdisplay - clip.x1; | ||
1268 | clip.y2 = unit->crtc.mode.vdisplay - clip.y1; | ||
1269 | clip.x1 = 0 - clip.x1; | ||
1270 | clip.y1 = 0 - clip.y1; | ||
1271 | |||
1168 | /* need to reset sid as it is changed by execbuf */ | 1272 | /* need to reset sid as it is changed by execbuf */ |
1169 | cmd->body.srcImage.sid = sid; | 1273 | cmd->body.srcImage.sid = sid; |
1170 | |||
1171 | cmd->body.destScreenId = unit->unit; | 1274 | cmd->body.destScreenId = unit->unit; |
1172 | 1275 | ||
1173 | /* | 1276 | /* clip and write blits to cmd stream */ |
1174 | * The blit command is a lot more resilient then the | 1277 | vmw_clip_cliprects(tmp, num_clips, clip, blits, &num); |
1175 | * readback command when it comes to clip rects. So its | ||
1176 | * okay to go out of bounds. | ||
1177 | */ | ||
1178 | 1278 | ||
1179 | cmd->body.destRect.left = clip_x1; | 1279 | /* if no cliprects hit skip this */ |
1180 | cmd->body.destRect.right = clip_x2; | 1280 | if (num == 0) |
1181 | cmd->body.destRect.top = clip_y1; | 1281 | continue; |
1182 | cmd->body.destRect.bottom = clip_y2; | ||
1183 | 1282 | ||
1283 | /* recalculate package length */ | ||
1284 | fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num; | ||
1285 | cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); | ||
1184 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, | 1286 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, |
1185 | fifo_size, 0, NULL); | 1287 | fifo_size, 0, NULL); |
1186 | 1288 | ||
@@ -1189,6 +1291,8 @@ int vmw_kms_present(struct vmw_private *dev_priv, | |||
1189 | } | 1291 | } |
1190 | 1292 | ||
1191 | kfree(cmd); | 1293 | kfree(cmd); |
1294 | out_free_tmp: | ||
1295 | kfree(tmp); | ||
1192 | 1296 | ||
1193 | return ret; | 1297 | return ret; |
1194 | } | 1298 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index af8e6e5bd964..e1cb8556355f 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | |||
@@ -62,9 +62,14 @@ struct vmw_framebuffer { | |||
62 | int vmw_cursor_update_image(struct vmw_private *dev_priv, | 62 | int vmw_cursor_update_image(struct vmw_private *dev_priv, |
63 | u32 *image, u32 width, u32 height, | 63 | u32 *image, u32 width, u32 height, |
64 | u32 hotspotX, u32 hotspotY); | 64 | u32 hotspotX, u32 hotspotY); |
65 | int vmw_cursor_update_dmabuf(struct vmw_private *dev_priv, | ||
66 | struct vmw_dma_buffer *dmabuf, | ||
67 | u32 width, u32 height, | ||
68 | u32 hotspotX, u32 hotspotY); | ||
65 | void vmw_cursor_update_position(struct vmw_private *dev_priv, | 69 | void vmw_cursor_update_position(struct vmw_private *dev_priv, |
66 | bool show, int x, int y); | 70 | bool show, int x, int y); |
67 | 71 | ||
72 | |||
68 | /** | 73 | /** |
69 | * Base class display unit. | 74 | * Base class display unit. |
70 | * | 75 | * |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 90c5e3928491..8f8dbd43c33d 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
@@ -74,9 +74,10 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) | |||
74 | { | 74 | { |
75 | struct vmw_legacy_display *lds = dev_priv->ldu_priv; | 75 | struct vmw_legacy_display *lds = dev_priv->ldu_priv; |
76 | struct vmw_legacy_display_unit *entry; | 76 | struct vmw_legacy_display_unit *entry; |
77 | struct vmw_display_unit *du = NULL; | ||
77 | struct drm_framebuffer *fb = NULL; | 78 | struct drm_framebuffer *fb = NULL; |
78 | struct drm_crtc *crtc = NULL; | 79 | struct drm_crtc *crtc = NULL; |
79 | int i = 0; | 80 | int i = 0, ret; |
80 | 81 | ||
81 | /* If there is no display topology the host just assumes | 82 | /* If there is no display topology the host just assumes |
82 | * that the guest will set the same layout as the host. | 83 | * that the guest will set the same layout as the host. |
@@ -129,6 +130,25 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv) | |||
129 | 130 | ||
130 | lds->last_num_active = lds->num_active; | 131 | lds->last_num_active = lds->num_active; |
131 | 132 | ||
133 | |||
134 | /* Find the first du with a cursor. */ | ||
135 | list_for_each_entry(entry, &lds->active, active) { | ||
136 | du = &entry->base; | ||
137 | |||
138 | if (!du->cursor_dmabuf) | ||
139 | continue; | ||
140 | |||
141 | ret = vmw_cursor_update_dmabuf(dev_priv, | ||
142 | du->cursor_dmabuf, | ||
143 | 64, 64, | ||
144 | du->hotspot_x, | ||
145 | du->hotspot_y); | ||
146 | if (ret == 0) | ||
147 | break; | ||
148 | |||
149 | DRM_ERROR("Could not update cursor image\n"); | ||
150 | } | ||
151 | |||
132 | return 0; | 152 | return 0; |
133 | } | 153 | } |
134 | 154 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 86c5e4cceb31..1c7f09e26819 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -1190,6 +1190,29 @@ void vmw_resource_unreserve(struct list_head *list) | |||
1190 | write_unlock(lock); | 1190 | write_unlock(lock); |
1191 | } | 1191 | } |
1192 | 1192 | ||
1193 | /** | ||
1194 | * Helper function that looks either a surface or dmabuf. | ||
1195 | * | ||
1196 | * The pointer this pointed at by out_surf and out_buf needs to be null. | ||
1197 | */ | ||
1198 | int vmw_user_lookup_handle(struct vmw_private *dev_priv, | ||
1199 | struct ttm_object_file *tfile, | ||
1200 | uint32_t handle, | ||
1201 | struct vmw_surface **out_surf, | ||
1202 | struct vmw_dma_buffer **out_buf) | ||
1203 | { | ||
1204 | int ret; | ||
1205 | |||
1206 | BUG_ON(*out_surf || *out_buf); | ||
1207 | |||
1208 | ret = vmw_user_surface_lookup_handle(dev_priv, tfile, handle, out_surf); | ||
1209 | if (!ret) | ||
1210 | return 0; | ||
1211 | |||
1212 | ret = vmw_user_dmabuf_lookup(tfile, handle, out_buf); | ||
1213 | return ret; | ||
1214 | } | ||
1215 | |||
1193 | 1216 | ||
1194 | int vmw_user_surface_lookup_handle(struct vmw_private *dev_priv, | 1217 | int vmw_user_surface_lookup_handle(struct vmw_private *dev_priv, |
1195 | struct ttm_object_file *tfile, | 1218 | struct ttm_object_file *tfile, |
diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c index 7a48b1eb4233..5253d23361d9 100644 --- a/drivers/hwmon/jz4740-hwmon.c +++ b/drivers/hwmon/jz4740-hwmon.c | |||
@@ -59,7 +59,7 @@ static ssize_t jz4740_hwmon_read_adcin(struct device *dev, | |||
59 | { | 59 | { |
60 | struct jz4740_hwmon *hwmon = dev_get_drvdata(dev); | 60 | struct jz4740_hwmon *hwmon = dev_get_drvdata(dev); |
61 | struct completion *completion = &hwmon->read_completion; | 61 | struct completion *completion = &hwmon->read_completion; |
62 | unsigned long t; | 62 | long t; |
63 | unsigned long val; | 63 | unsigned long val; |
64 | int ret; | 64 | int ret; |
65 | 65 | ||
@@ -203,7 +203,7 @@ static int __devexit jz4740_hwmon_remove(struct platform_device *pdev) | |||
203 | return 0; | 203 | return 0; |
204 | } | 204 | } |
205 | 205 | ||
206 | struct platform_driver jz4740_hwmon_driver = { | 206 | static struct platform_driver jz4740_hwmon_driver = { |
207 | .probe = jz4740_hwmon_probe, | 207 | .probe = jz4740_hwmon_probe, |
208 | .remove = __devexit_p(jz4740_hwmon_remove), | 208 | .remove = __devexit_p(jz4740_hwmon_remove), |
209 | .driver = { | 209 | .driver = { |
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 8cebef49aeac..18936ac9d51c 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c | |||
@@ -893,6 +893,13 @@ static int __devinit pch_i2c_probe(struct pci_dev *pdev, | |||
893 | /* Set the number of I2C channel instance */ | 893 | /* Set the number of I2C channel instance */ |
894 | adap_info->ch_num = id->driver_data; | 894 | adap_info->ch_num = id->driver_data; |
895 | 895 | ||
896 | ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED, | ||
897 | KBUILD_MODNAME, adap_info); | ||
898 | if (ret) { | ||
899 | pch_pci_err(pdev, "request_irq FAILED\n"); | ||
900 | goto err_request_irq; | ||
901 | } | ||
902 | |||
896 | for (i = 0; i < adap_info->ch_num; i++) { | 903 | for (i = 0; i < adap_info->ch_num; i++) { |
897 | pch_adap = &adap_info->pch_data[i].pch_adapter; | 904 | pch_adap = &adap_info->pch_data[i].pch_adapter; |
898 | adap_info->pch_i2c_suspended = false; | 905 | adap_info->pch_i2c_suspended = false; |
@@ -910,28 +917,23 @@ static int __devinit pch_i2c_probe(struct pci_dev *pdev, | |||
910 | 917 | ||
911 | pch_adap->dev.parent = &pdev->dev; | 918 | pch_adap->dev.parent = &pdev->dev; |
912 | 919 | ||
920 | pch_i2c_init(&adap_info->pch_data[i]); | ||
913 | ret = i2c_add_adapter(pch_adap); | 921 | ret = i2c_add_adapter(pch_adap); |
914 | if (ret) { | 922 | if (ret) { |
915 | pch_pci_err(pdev, "i2c_add_adapter[ch:%d] FAILED\n", i); | 923 | pch_pci_err(pdev, "i2c_add_adapter[ch:%d] FAILED\n", i); |
916 | goto err_i2c_add_adapter; | 924 | goto err_add_adapter; |
917 | } | 925 | } |
918 | |||
919 | pch_i2c_init(&adap_info->pch_data[i]); | ||
920 | } | ||
921 | ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED, | ||
922 | KBUILD_MODNAME, adap_info); | ||
923 | if (ret) { | ||
924 | pch_pci_err(pdev, "request_irq FAILED\n"); | ||
925 | goto err_i2c_add_adapter; | ||
926 | } | 926 | } |
927 | 927 | ||
928 | pci_set_drvdata(pdev, adap_info); | 928 | pci_set_drvdata(pdev, adap_info); |
929 | pch_pci_dbg(pdev, "returns %d.\n", ret); | 929 | pch_pci_dbg(pdev, "returns %d.\n", ret); |
930 | return 0; | 930 | return 0; |
931 | 931 | ||
932 | err_i2c_add_adapter: | 932 | err_add_adapter: |
933 | for (j = 0; j < i; j++) | 933 | for (j = 0; j < i; j++) |
934 | i2c_del_adapter(&adap_info->pch_data[j].pch_adapter); | 934 | i2c_del_adapter(&adap_info->pch_data[j].pch_adapter); |
935 | free_irq(pdev->irq, adap_info); | ||
936 | err_request_irq: | ||
935 | pci_iounmap(pdev, base_addr); | 937 | pci_iounmap(pdev, base_addr); |
936 | err_pci_iomap: | 938 | err_pci_iomap: |
937 | pci_release_regions(pdev); | 939 | pci_release_regions(pdev); |
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index a43d0023446a..fa23faa20f0e 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -1047,13 +1047,14 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1047 | * size. This is to ensure that we can handle the status on int | 1047 | * size. This is to ensure that we can handle the status on int |
1048 | * call back latencies. | 1048 | * call back latencies. |
1049 | */ | 1049 | */ |
1050 | if (dev->rev >= OMAP_I2C_REV_ON_3530_4430) { | 1050 | |
1051 | dev->fifo_size = 0; | 1051 | dev->fifo_size = (dev->fifo_size / 2); |
1052 | |||
1053 | if (dev->rev >= OMAP_I2C_REV_ON_3530_4430) | ||
1052 | dev->b_hw = 0; /* Disable hardware fixes */ | 1054 | dev->b_hw = 0; /* Disable hardware fixes */ |
1053 | } else { | 1055 | else |
1054 | dev->fifo_size = (dev->fifo_size / 2); | ||
1055 | dev->b_hw = 1; /* Enable hardware fixes */ | 1056 | dev->b_hw = 1; /* Enable hardware fixes */ |
1056 | } | 1057 | |
1057 | /* calculate wakeup latency constraint for MPU */ | 1058 | /* calculate wakeup latency constraint for MPU */ |
1058 | if (dev->set_mpu_wkup_lat != NULL) | 1059 | if (dev->set_mpu_wkup_lat != NULL) |
1059 | dev->latency = (1000000 * dev->fifo_size) / | 1060 | dev->latency = (1000000 * dev->fifo_size) / |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 2754cef86a06..4c1718081685 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -534,6 +534,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, | |||
534 | 534 | ||
535 | /* first, try busy waiting briefly */ | 535 | /* first, try busy waiting briefly */ |
536 | do { | 536 | do { |
537 | cpu_relax(); | ||
537 | iicstat = readl(i2c->regs + S3C2410_IICSTAT); | 538 | iicstat = readl(i2c->regs + S3C2410_IICSTAT); |
538 | } while ((iicstat & S3C2410_IICSTAT_START) && --spins); | 539 | } while ((iicstat & S3C2410_IICSTAT_START) && --spins); |
539 | 540 | ||
@@ -786,7 +787,7 @@ static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c) | |||
786 | #else | 787 | #else |
787 | static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c) | 788 | static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c) |
788 | { | 789 | { |
789 | return -EINVAL; | 790 | return 0; |
790 | } | 791 | } |
791 | 792 | ||
792 | static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c) | 793 | static void s3c24xx_i2c_dt_gpio_free(struct s3c24xx_i2c *i2c) |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 09e66cce05d3..236a88c1ca87 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -2513,6 +2513,9 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv, | |||
2513 | 2513 | ||
2514 | req.private_data_len = sizeof(struct cma_hdr) + | 2514 | req.private_data_len = sizeof(struct cma_hdr) + |
2515 | conn_param->private_data_len; | 2515 | conn_param->private_data_len; |
2516 | if (req.private_data_len < conn_param->private_data_len) | ||
2517 | return -EINVAL; | ||
2518 | |||
2516 | req.private_data = kzalloc(req.private_data_len, GFP_ATOMIC); | 2519 | req.private_data = kzalloc(req.private_data_len, GFP_ATOMIC); |
2517 | if (!req.private_data) | 2520 | if (!req.private_data) |
2518 | return -ENOMEM; | 2521 | return -ENOMEM; |
@@ -2562,6 +2565,9 @@ static int cma_connect_ib(struct rdma_id_private *id_priv, | |||
2562 | memset(&req, 0, sizeof req); | 2565 | memset(&req, 0, sizeof req); |
2563 | offset = cma_user_data_offset(id_priv->id.ps); | 2566 | offset = cma_user_data_offset(id_priv->id.ps); |
2564 | req.private_data_len = offset + conn_param->private_data_len; | 2567 | req.private_data_len = offset + conn_param->private_data_len; |
2568 | if (req.private_data_len < conn_param->private_data_len) | ||
2569 | return -EINVAL; | ||
2570 | |||
2565 | private_data = kzalloc(req.private_data_len, GFP_ATOMIC); | 2571 | private_data = kzalloc(req.private_data_len, GFP_ATOMIC); |
2566 | if (!private_data) | 2572 | if (!private_data) |
2567 | return -ENOMEM; | 2573 | return -ENOMEM; |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index b8279deb614d..7b445df6a667 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -1250,7 +1250,8 @@ err_reg: | |||
1250 | 1250 | ||
1251 | err_counter: | 1251 | err_counter: |
1252 | for (; i; --i) | 1252 | for (; i; --i) |
1253 | mlx4_counter_free(ibdev->dev, ibdev->counters[i - 1]); | 1253 | if (ibdev->counters[i - 1] != -1) |
1254 | mlx4_counter_free(ibdev->dev, ibdev->counters[i - 1]); | ||
1254 | 1255 | ||
1255 | err_map: | 1256 | err_map: |
1256 | iounmap(ibdev->uar_map); | 1257 | iounmap(ibdev->uar_map); |
@@ -1281,7 +1282,8 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr) | |||
1281 | } | 1282 | } |
1282 | iounmap(ibdev->uar_map); | 1283 | iounmap(ibdev->uar_map); |
1283 | for (p = 0; p < ibdev->num_ports; ++p) | 1284 | for (p = 0; p < ibdev->num_ports; ++p) |
1284 | mlx4_counter_free(ibdev->dev, ibdev->counters[p]); | 1285 | if (ibdev->counters[p] != -1) |
1286 | mlx4_counter_free(ibdev->dev, ibdev->counters[p]); | ||
1285 | mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB) | 1287 | mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB) |
1286 | mlx4_CLOSE_PORT(dev, p); | 1288 | mlx4_CLOSE_PORT(dev, p); |
1287 | 1289 | ||
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c index 574600ef5b42..a7403248d83d 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c | |||
@@ -1285,7 +1285,7 @@ static int setup_ctxt(struct qib_pportdata *ppd, int ctxt, | |||
1285 | strlcpy(rcd->comm, current->comm, sizeof(rcd->comm)); | 1285 | strlcpy(rcd->comm, current->comm, sizeof(rcd->comm)); |
1286 | ctxt_fp(fp) = rcd; | 1286 | ctxt_fp(fp) = rcd; |
1287 | qib_stats.sps_ctxts++; | 1287 | qib_stats.sps_ctxts++; |
1288 | dd->freectxts++; | 1288 | dd->freectxts--; |
1289 | ret = 0; | 1289 | ret = 0; |
1290 | goto bail; | 1290 | goto bail; |
1291 | 1291 | ||
@@ -1794,7 +1794,7 @@ static int qib_close(struct inode *in, struct file *fp) | |||
1794 | if (dd->pageshadow) | 1794 | if (dd->pageshadow) |
1795 | unlock_expected_tids(rcd); | 1795 | unlock_expected_tids(rcd); |
1796 | qib_stats.sps_ctxts--; | 1796 | qib_stats.sps_ctxts--; |
1797 | dd->freectxts--; | 1797 | dd->freectxts++; |
1798 | } | 1798 | } |
1799 | 1799 | ||
1800 | mutex_unlock(&qib_mutex); | 1800 | mutex_unlock(&qib_mutex); |
diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c index 80793f1608eb..06517e60e50c 100644 --- a/drivers/input/misc/cma3000_d0x.c +++ b/drivers/input/misc/cma3000_d0x.c | |||
@@ -115,8 +115,8 @@ static void decode_mg(struct cma3000_accl_data *data, int *datax, | |||
115 | static irqreturn_t cma3000_thread_irq(int irq, void *dev_id) | 115 | static irqreturn_t cma3000_thread_irq(int irq, void *dev_id) |
116 | { | 116 | { |
117 | struct cma3000_accl_data *data = dev_id; | 117 | struct cma3000_accl_data *data = dev_id; |
118 | int datax, datay, dataz; | 118 | int datax, datay, dataz, intr_status; |
119 | u8 ctrl, mode, range, intr_status; | 119 | u8 ctrl, mode, range; |
120 | 120 | ||
121 | intr_status = CMA3000_READ(data, CMA3000_INTSTATUS, "interrupt status"); | 121 | intr_status = CMA3000_READ(data, CMA3000_INTSTATUS, "interrupt status"); |
122 | if (intr_status < 0) | 122 | if (intr_status < 0) |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index c080b828e5dc..a6dcd18e9adf 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -24,6 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/delay.h> | ||
27 | #include <linux/dmi.h> | 28 | #include <linux/dmi.h> |
28 | #include <linux/input/mt.h> | 29 | #include <linux/input/mt.h> |
29 | #include <linux/serio.h> | 30 | #include <linux/serio.h> |
@@ -1220,6 +1221,16 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
1220 | 1221 | ||
1221 | do { | 1222 | do { |
1222 | psmouse_reset(psmouse); | 1223 | psmouse_reset(psmouse); |
1224 | if (retry) { | ||
1225 | /* | ||
1226 | * On some boxes, right after resuming, the touchpad | ||
1227 | * needs some time to finish initializing (I assume | ||
1228 | * it needs time to calibrate) and start responding | ||
1229 | * to Synaptics-specific queries, so let's wait a | ||
1230 | * bit. | ||
1231 | */ | ||
1232 | ssleep(1); | ||
1233 | } | ||
1223 | error = synaptics_detect(psmouse, 0); | 1234 | error = synaptics_detect(psmouse, 0); |
1224 | } while (error && ++retry < 3); | 1235 | } while (error && ++retry < 3); |
1225 | 1236 | ||
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index da0d8761e778..2ee47d01a3b4 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -1470,6 +1470,9 @@ static const struct wacom_features wacom_features_0xE3 = | |||
1470 | static const struct wacom_features wacom_features_0xE6 = | 1470 | static const struct wacom_features wacom_features_0xE6 = |
1471 | { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, | 1471 | { "Wacom ISDv4 E6", WACOM_PKGLEN_TPC2FG, 27760, 15694, 255, |
1472 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1472 | 0, TABLETPC2FG, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
1473 | static const struct wacom_features wacom_features_0xEC = | ||
1474 | { "Wacom ISDv4 EC", WACOM_PKGLEN_GRAPHIRE, 25710, 14500, 255, | ||
1475 | 0, TABLETPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | ||
1473 | static const struct wacom_features wacom_features_0x47 = | 1476 | static const struct wacom_features wacom_features_0x47 = |
1474 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, | 1477 | { "Wacom Intuos2 6x8", WACOM_PKGLEN_INTUOS, 20320, 16240, 1023, |
1475 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; | 1478 | 31, INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; |
@@ -1611,6 +1614,7 @@ const struct usb_device_id wacom_ids[] = { | |||
1611 | { USB_DEVICE_WACOM(0xE2) }, | 1614 | { USB_DEVICE_WACOM(0xE2) }, |
1612 | { USB_DEVICE_WACOM(0xE3) }, | 1615 | { USB_DEVICE_WACOM(0xE3) }, |
1613 | { USB_DEVICE_WACOM(0xE6) }, | 1616 | { USB_DEVICE_WACOM(0xE6) }, |
1617 | { USB_DEVICE_WACOM(0xEC) }, | ||
1614 | { USB_DEVICE_WACOM(0x47) }, | 1618 | { USB_DEVICE_WACOM(0x47) }, |
1615 | { USB_DEVICE_LENOVO(0x6004) }, | 1619 | { USB_DEVICE_LENOVO(0x6004) }, |
1616 | { } | 1620 | { } |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index a004c3945c67..bdc447fd4766 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -405,6 +405,9 @@ int dmar_disabled = 0; | |||
405 | int dmar_disabled = 1; | 405 | int dmar_disabled = 1; |
406 | #endif /*CONFIG_INTEL_IOMMU_DEFAULT_ON*/ | 406 | #endif /*CONFIG_INTEL_IOMMU_DEFAULT_ON*/ |
407 | 407 | ||
408 | int intel_iommu_enabled = 0; | ||
409 | EXPORT_SYMBOL_GPL(intel_iommu_enabled); | ||
410 | |||
408 | static int dmar_map_gfx = 1; | 411 | static int dmar_map_gfx = 1; |
409 | static int dmar_forcedac; | 412 | static int dmar_forcedac; |
410 | static int intel_iommu_strict; | 413 | static int intel_iommu_strict; |
@@ -3647,6 +3650,8 @@ int __init intel_iommu_init(void) | |||
3647 | 3650 | ||
3648 | bus_register_notifier(&pci_bus_type, &device_nb); | 3651 | bus_register_notifier(&pci_bus_type, &device_nb); |
3649 | 3652 | ||
3653 | intel_iommu_enabled = 1; | ||
3654 | |||
3650 | return 0; | 3655 | return 0; |
3651 | } | 3656 | } |
3652 | 3657 | ||
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 7878712721bf..b6907118283a 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1106,10 +1106,12 @@ void bitmap_write_all(struct bitmap *bitmap) | |||
1106 | */ | 1106 | */ |
1107 | int i; | 1107 | int i; |
1108 | 1108 | ||
1109 | spin_lock_irq(&bitmap->lock); | ||
1109 | for (i = 0; i < bitmap->file_pages; i++) | 1110 | for (i = 0; i < bitmap->file_pages; i++) |
1110 | set_page_attr(bitmap, bitmap->filemap[i], | 1111 | set_page_attr(bitmap, bitmap->filemap[i], |
1111 | BITMAP_PAGE_NEEDWRITE); | 1112 | BITMAP_PAGE_NEEDWRITE); |
1112 | bitmap->allclean = 0; | 1113 | bitmap->allclean = 0; |
1114 | spin_unlock_irq(&bitmap->lock); | ||
1113 | } | 1115 | } |
1114 | 1116 | ||
1115 | static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc) | 1117 | static void bitmap_count_page(struct bitmap *bitmap, sector_t offset, int inc) |
@@ -1605,7 +1607,9 @@ void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e) | |||
1605 | for (chunk = s; chunk <= e; chunk++) { | 1607 | for (chunk = s; chunk <= e; chunk++) { |
1606 | sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap); | 1608 | sector_t sec = (sector_t)chunk << CHUNK_BLOCK_SHIFT(bitmap); |
1607 | bitmap_set_memory_bits(bitmap, sec, 1); | 1609 | bitmap_set_memory_bits(bitmap, sec, 1); |
1610 | spin_lock_irq(&bitmap->lock); | ||
1608 | bitmap_file_set_bit(bitmap, sec); | 1611 | bitmap_file_set_bit(bitmap, sec); |
1612 | spin_unlock_irq(&bitmap->lock); | ||
1609 | if (sec < bitmap->mddev->recovery_cp) | 1613 | if (sec < bitmap->mddev->recovery_cp) |
1610 | /* We are asserting that the array is dirty, | 1614 | /* We are asserting that the array is dirty, |
1611 | * so move the recovery_cp address back so | 1615 | * so move the recovery_cp address back so |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 84acfe7d10e4..ee981737edfc 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -570,7 +570,7 @@ static void mddev_put(struct mddev *mddev) | |||
570 | mddev->ctime == 0 && !mddev->hold_active) { | 570 | mddev->ctime == 0 && !mddev->hold_active) { |
571 | /* Array is not configured at all, and not held active, | 571 | /* Array is not configured at all, and not held active, |
572 | * so destroy it */ | 572 | * so destroy it */ |
573 | list_del(&mddev->all_mddevs); | 573 | list_del_init(&mddev->all_mddevs); |
574 | bs = mddev->bio_set; | 574 | bs = mddev->bio_set; |
575 | mddev->bio_set = NULL; | 575 | mddev->bio_set = NULL; |
576 | if (mddev->gendisk) { | 576 | if (mddev->gendisk) { |
@@ -2546,7 +2546,8 @@ state_show(struct md_rdev *rdev, char *page) | |||
2546 | sep = ","; | 2546 | sep = ","; |
2547 | } | 2547 | } |
2548 | if (test_bit(Blocked, &rdev->flags) || | 2548 | if (test_bit(Blocked, &rdev->flags) || |
2549 | rdev->badblocks.unacked_exist) { | 2549 | (rdev->badblocks.unacked_exist |
2550 | && !test_bit(Faulty, &rdev->flags))) { | ||
2550 | len += sprintf(page+len, "%sblocked", sep); | 2551 | len += sprintf(page+len, "%sblocked", sep); |
2551 | sep = ","; | 2552 | sep = ","; |
2552 | } | 2553 | } |
@@ -3788,6 +3789,8 @@ array_state_store(struct mddev *mddev, const char *buf, size_t len) | |||
3788 | if (err) | 3789 | if (err) |
3789 | return err; | 3790 | return err; |
3790 | else { | 3791 | else { |
3792 | if (mddev->hold_active == UNTIL_IOCTL) | ||
3793 | mddev->hold_active = 0; | ||
3791 | sysfs_notify_dirent_safe(mddev->sysfs_state); | 3794 | sysfs_notify_dirent_safe(mddev->sysfs_state); |
3792 | return len; | 3795 | return len; |
3793 | } | 3796 | } |
@@ -4487,11 +4490,20 @@ md_attr_show(struct kobject *kobj, struct attribute *attr, char *page) | |||
4487 | 4490 | ||
4488 | if (!entry->show) | 4491 | if (!entry->show) |
4489 | return -EIO; | 4492 | return -EIO; |
4493 | spin_lock(&all_mddevs_lock); | ||
4494 | if (list_empty(&mddev->all_mddevs)) { | ||
4495 | spin_unlock(&all_mddevs_lock); | ||
4496 | return -EBUSY; | ||
4497 | } | ||
4498 | mddev_get(mddev); | ||
4499 | spin_unlock(&all_mddevs_lock); | ||
4500 | |||
4490 | rv = mddev_lock(mddev); | 4501 | rv = mddev_lock(mddev); |
4491 | if (!rv) { | 4502 | if (!rv) { |
4492 | rv = entry->show(mddev, page); | 4503 | rv = entry->show(mddev, page); |
4493 | mddev_unlock(mddev); | 4504 | mddev_unlock(mddev); |
4494 | } | 4505 | } |
4506 | mddev_put(mddev); | ||
4495 | return rv; | 4507 | return rv; |
4496 | } | 4508 | } |
4497 | 4509 | ||
@@ -4507,13 +4519,19 @@ md_attr_store(struct kobject *kobj, struct attribute *attr, | |||
4507 | return -EIO; | 4519 | return -EIO; |
4508 | if (!capable(CAP_SYS_ADMIN)) | 4520 | if (!capable(CAP_SYS_ADMIN)) |
4509 | return -EACCES; | 4521 | return -EACCES; |
4522 | spin_lock(&all_mddevs_lock); | ||
4523 | if (list_empty(&mddev->all_mddevs)) { | ||
4524 | spin_unlock(&all_mddevs_lock); | ||
4525 | return -EBUSY; | ||
4526 | } | ||
4527 | mddev_get(mddev); | ||
4528 | spin_unlock(&all_mddevs_lock); | ||
4510 | rv = mddev_lock(mddev); | 4529 | rv = mddev_lock(mddev); |
4511 | if (mddev->hold_active == UNTIL_IOCTL) | ||
4512 | mddev->hold_active = 0; | ||
4513 | if (!rv) { | 4530 | if (!rv) { |
4514 | rv = entry->store(mddev, page, length); | 4531 | rv = entry->store(mddev, page, length); |
4515 | mddev_unlock(mddev); | 4532 | mddev_unlock(mddev); |
4516 | } | 4533 | } |
4534 | mddev_put(mddev); | ||
4517 | return rv; | 4535 | return rv; |
4518 | } | 4536 | } |
4519 | 4537 | ||
@@ -7840,6 +7858,7 @@ int rdev_set_badblocks(struct md_rdev *rdev, sector_t s, int sectors, | |||
7840 | s + rdev->data_offset, sectors, acknowledged); | 7858 | s + rdev->data_offset, sectors, acknowledged); |
7841 | if (rv) { | 7859 | if (rv) { |
7842 | /* Make sure they get written out promptly */ | 7860 | /* Make sure they get written out promptly */ |
7861 | sysfs_notify_dirent_safe(rdev->sysfs_state); | ||
7843 | set_bit(MD_CHANGE_CLEAN, &rdev->mddev->flags); | 7862 | set_bit(MD_CHANGE_CLEAN, &rdev->mddev->flags); |
7844 | md_wakeup_thread(rdev->mddev->thread); | 7863 | md_wakeup_thread(rdev->mddev->thread); |
7845 | } | 7864 | } |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 297e26092178..31670f8d6b65 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3036,6 +3036,8 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) | |||
3036 | if (dev->written) | 3036 | if (dev->written) |
3037 | s->written++; | 3037 | s->written++; |
3038 | rdev = rcu_dereference(conf->disks[i].rdev); | 3038 | rdev = rcu_dereference(conf->disks[i].rdev); |
3039 | if (rdev && test_bit(Faulty, &rdev->flags)) | ||
3040 | rdev = NULL; | ||
3039 | if (rdev) { | 3041 | if (rdev) { |
3040 | is_bad = is_badblock(rdev, sh->sector, STRIPE_SECTORS, | 3042 | is_bad = is_badblock(rdev, sh->sector, STRIPE_SECTORS, |
3041 | &first_bad, &bad_sectors); | 3043 | &first_bad, &bad_sectors); |
@@ -3063,12 +3065,12 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) | |||
3063 | } | 3065 | } |
3064 | } else if (test_bit(In_sync, &rdev->flags)) | 3066 | } else if (test_bit(In_sync, &rdev->flags)) |
3065 | set_bit(R5_Insync, &dev->flags); | 3067 | set_bit(R5_Insync, &dev->flags); |
3066 | else if (!test_bit(Faulty, &rdev->flags)) { | 3068 | else { |
3067 | /* in sync if before recovery_offset */ | 3069 | /* in sync if before recovery_offset */ |
3068 | if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) | 3070 | if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) |
3069 | set_bit(R5_Insync, &dev->flags); | 3071 | set_bit(R5_Insync, &dev->flags); |
3070 | } | 3072 | } |
3071 | if (test_bit(R5_WriteError, &dev->flags)) { | 3073 | if (rdev && test_bit(R5_WriteError, &dev->flags)) { |
3072 | clear_bit(R5_Insync, &dev->flags); | 3074 | clear_bit(R5_Insync, &dev->flags); |
3073 | if (!test_bit(Faulty, &rdev->flags)) { | 3075 | if (!test_bit(Faulty, &rdev->flags)) { |
3074 | s->handle_bad_blocks = 1; | 3076 | s->handle_bad_blocks = 1; |
@@ -3076,7 +3078,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) | |||
3076 | } else | 3078 | } else |
3077 | clear_bit(R5_WriteError, &dev->flags); | 3079 | clear_bit(R5_WriteError, &dev->flags); |
3078 | } | 3080 | } |
3079 | if (test_bit(R5_MadeGood, &dev->flags)) { | 3081 | if (rdev && test_bit(R5_MadeGood, &dev->flags)) { |
3080 | if (!test_bit(Faulty, &rdev->flags)) { | 3082 | if (!test_bit(Faulty, &rdev->flags)) { |
3081 | s->handle_bad_blocks = 1; | 3083 | s->handle_bad_blocks = 1; |
3082 | atomic_inc(&rdev->nr_pending); | 3084 | atomic_inc(&rdev->nr_pending); |
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c index 7eb1bf75cd07..5d02221e99dd 100644 --- a/drivers/media/common/tuners/mxl5007t.c +++ b/drivers/media/common/tuners/mxl5007t.c | |||
@@ -488,9 +488,10 @@ static int mxl5007t_write_regs(struct mxl5007t_state *state, | |||
488 | 488 | ||
489 | static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val) | 489 | static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val) |
490 | { | 490 | { |
491 | u8 buf[2] = { 0xfb, reg }; | ||
491 | struct i2c_msg msg[] = { | 492 | struct i2c_msg msg[] = { |
492 | { .addr = state->i2c_props.addr, .flags = 0, | 493 | { .addr = state->i2c_props.addr, .flags = 0, |
493 | .buf = ®, .len = 1 }, | 494 | .buf = buf, .len = 2 }, |
494 | { .addr = state->i2c_props.addr, .flags = I2C_M_RD, | 495 | { .addr = state->i2c_props.addr, .flags = I2C_M_RD, |
495 | .buf = val, .len = 1 }, | 496 | .buf = val, .len = 1 }, |
496 | }; | 497 | }; |
diff --git a/drivers/media/common/tuners/tda18218.c b/drivers/media/common/tuners/tda18218.c index aacfe2387e28..4fc29730a12c 100644 --- a/drivers/media/common/tuners/tda18218.c +++ b/drivers/media/common/tuners/tda18218.c | |||
@@ -141,7 +141,7 @@ static int tda18218_set_params(struct dvb_frontend *fe, | |||
141 | switch (params->u.ofdm.bandwidth) { | 141 | switch (params->u.ofdm.bandwidth) { |
142 | case BANDWIDTH_6_MHZ: | 142 | case BANDWIDTH_6_MHZ: |
143 | LP_Fc = 0; | 143 | LP_Fc = 0; |
144 | LO_Frac = params->frequency + 4000000; | 144 | LO_Frac = params->frequency + 3000000; |
145 | break; | 145 | break; |
146 | case BANDWIDTH_7_MHZ: | 146 | case BANDWIDTH_7_MHZ: |
147 | LP_Fc = 1; | 147 | LP_Fc = 1; |
diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index 303f22ea04c0..01bb8daf4b09 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c | |||
@@ -189,7 +189,7 @@ struct ati_remote { | |||
189 | dma_addr_t inbuf_dma; | 189 | dma_addr_t inbuf_dma; |
190 | dma_addr_t outbuf_dma; | 190 | dma_addr_t outbuf_dma; |
191 | 191 | ||
192 | unsigned char old_data[2]; /* Detect duplicate events */ | 192 | unsigned char old_data; /* Detect duplicate events */ |
193 | unsigned long old_jiffies; | 193 | unsigned long old_jiffies; |
194 | unsigned long acc_jiffies; /* handle acceleration */ | 194 | unsigned long acc_jiffies; /* handle acceleration */ |
195 | unsigned long first_jiffies; | 195 | unsigned long first_jiffies; |
@@ -221,35 +221,35 @@ struct ati_remote { | |||
221 | /* Translation table from hardware messages to input events. */ | 221 | /* Translation table from hardware messages to input events. */ |
222 | static const struct { | 222 | static const struct { |
223 | short kind; | 223 | short kind; |
224 | unsigned char data1, data2; | 224 | unsigned char data; |
225 | int type; | 225 | int type; |
226 | unsigned int code; | 226 | unsigned int code; |
227 | int value; | 227 | int value; |
228 | } ati_remote_tbl[] = { | 228 | } ati_remote_tbl[] = { |
229 | /* Directional control pad axes */ | 229 | /* Directional control pad axes */ |
230 | {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */ | 230 | {KIND_ACCEL, 0x70, EV_REL, REL_X, -1}, /* left */ |
231 | {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */ | 231 | {KIND_ACCEL, 0x71, EV_REL, REL_X, 1}, /* right */ |
232 | {KIND_ACCEL, 0x37, 0x72, EV_REL, REL_Y, -1}, /* up */ | 232 | {KIND_ACCEL, 0x72, EV_REL, REL_Y, -1}, /* up */ |
233 | {KIND_ACCEL, 0x38, 0x73, EV_REL, REL_Y, 1}, /* down */ | 233 | {KIND_ACCEL, 0x73, EV_REL, REL_Y, 1}, /* down */ |
234 | /* Directional control pad diagonals */ | 234 | /* Directional control pad diagonals */ |
235 | {KIND_LU, 0x39, 0x74, EV_REL, 0, 0}, /* left up */ | 235 | {KIND_LU, 0x74, EV_REL, 0, 0}, /* left up */ |
236 | {KIND_RU, 0x3a, 0x75, EV_REL, 0, 0}, /* right up */ | 236 | {KIND_RU, 0x75, EV_REL, 0, 0}, /* right up */ |
237 | {KIND_LD, 0x3c, 0x77, EV_REL, 0, 0}, /* left down */ | 237 | {KIND_LD, 0x77, EV_REL, 0, 0}, /* left down */ |
238 | {KIND_RD, 0x3b, 0x76, EV_REL, 0, 0}, /* right down */ | 238 | {KIND_RD, 0x76, EV_REL, 0, 0}, /* right down */ |
239 | 239 | ||
240 | /* "Mouse button" buttons */ | 240 | /* "Mouse button" buttons */ |
241 | {KIND_LITERAL, 0x3d, 0x78, EV_KEY, BTN_LEFT, 1}, /* left btn down */ | 241 | {KIND_LITERAL, 0x78, EV_KEY, BTN_LEFT, 1}, /* left btn down */ |
242 | {KIND_LITERAL, 0x3e, 0x79, EV_KEY, BTN_LEFT, 0}, /* left btn up */ | 242 | {KIND_LITERAL, 0x79, EV_KEY, BTN_LEFT, 0}, /* left btn up */ |
243 | {KIND_LITERAL, 0x41, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */ | 243 | {KIND_LITERAL, 0x7c, EV_KEY, BTN_RIGHT, 1},/* right btn down */ |
244 | {KIND_LITERAL, 0x42, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */ | 244 | {KIND_LITERAL, 0x7d, EV_KEY, BTN_RIGHT, 0},/* right btn up */ |
245 | 245 | ||
246 | /* Artificial "doubleclick" events are generated by the hardware. | 246 | /* Artificial "doubleclick" events are generated by the hardware. |
247 | * They are mapped to the "side" and "extra" mouse buttons here. */ | 247 | * They are mapped to the "side" and "extra" mouse buttons here. */ |
248 | {KIND_FILTERED, 0x3f, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */ | 248 | {KIND_FILTERED, 0x7a, EV_KEY, BTN_SIDE, 1}, /* left dblclick */ |
249 | {KIND_FILTERED, 0x43, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */ | 249 | {KIND_FILTERED, 0x7e, EV_KEY, BTN_EXTRA, 1},/* right dblclick */ |
250 | 250 | ||
251 | /* Non-mouse events are handled by rc-core */ | 251 | /* Non-mouse events are handled by rc-core */ |
252 | {KIND_END, 0x00, 0x00, EV_MAX + 1, 0, 0} | 252 | {KIND_END, 0x00, EV_MAX + 1, 0, 0} |
253 | }; | 253 | }; |
254 | 254 | ||
255 | /* Local function prototypes */ | 255 | /* Local function prototypes */ |
@@ -397,25 +397,6 @@ static int ati_remote_sendpacket(struct ati_remote *ati_remote, u16 cmd, unsigne | |||
397 | } | 397 | } |
398 | 398 | ||
399 | /* | 399 | /* |
400 | * ati_remote_event_lookup | ||
401 | */ | ||
402 | static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2) | ||
403 | { | ||
404 | int i; | ||
405 | |||
406 | for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { | ||
407 | /* | ||
408 | * Decide if the table entry matches the remote input. | ||
409 | */ | ||
410 | if (ati_remote_tbl[i].data1 == d1 && | ||
411 | ati_remote_tbl[i].data2 == d2) | ||
412 | return i; | ||
413 | |||
414 | } | ||
415 | return -1; | ||
416 | } | ||
417 | |||
418 | /* | ||
419 | * ati_remote_compute_accel | 400 | * ati_remote_compute_accel |
420 | * | 401 | * |
421 | * Implements acceleration curve for directional control pad | 402 | * Implements acceleration curve for directional control pad |
@@ -463,7 +444,15 @@ static void ati_remote_input_report(struct urb *urb) | |||
463 | int index = -1; | 444 | int index = -1; |
464 | int acc; | 445 | int acc; |
465 | int remote_num; | 446 | int remote_num; |
466 | unsigned char scancode[2]; | 447 | unsigned char scancode; |
448 | int i; | ||
449 | |||
450 | /* | ||
451 | * data[0] = 0x14 | ||
452 | * data[1] = data[2] + data[3] + 0xd5 (a checksum byte) | ||
453 | * data[2] = the key code (with toggle bit in MSB with some models) | ||
454 | * data[3] = channel << 4 (the low 4 bits must be zero) | ||
455 | */ | ||
467 | 456 | ||
468 | /* Deal with strange looking inputs */ | 457 | /* Deal with strange looking inputs */ |
469 | if ( (urb->actual_length != 4) || (data[0] != 0x14) || | 458 | if ( (urb->actual_length != 4) || (data[0] != 0x14) || |
@@ -472,6 +461,13 @@ static void ati_remote_input_report(struct urb *urb) | |||
472 | return; | 461 | return; |
473 | } | 462 | } |
474 | 463 | ||
464 | if (data[1] != ((data[2] + data[3] + 0xd5) & 0xff)) { | ||
465 | dbginfo(&ati_remote->interface->dev, | ||
466 | "wrong checksum in input: %02x %02x %02x %02x\n", | ||
467 | data[0], data[1], data[2], data[3]); | ||
468 | return; | ||
469 | } | ||
470 | |||
475 | /* Mask unwanted remote channels. */ | 471 | /* Mask unwanted remote channels. */ |
476 | /* note: remote_num is 0-based, channel 1 on remote == 0 here */ | 472 | /* note: remote_num is 0-based, channel 1 on remote == 0 here */ |
477 | remote_num = (data[3] >> 4) & 0x0f; | 473 | remote_num = (data[3] >> 4) & 0x0f; |
@@ -482,31 +478,30 @@ static void ati_remote_input_report(struct urb *urb) | |||
482 | return; | 478 | return; |
483 | } | 479 | } |
484 | 480 | ||
485 | scancode[0] = (((data[1] - ((remote_num + 1) << 4)) & 0xf0) | (data[1] & 0x0f)); | ||
486 | |||
487 | /* | 481 | /* |
488 | * Some devices (e.g. SnapStream Firefly) use 8080 as toggle code, | 482 | * MSB is a toggle code, though only used by some devices |
489 | * so we have to clear them. The first bit is a bit tricky as the | 483 | * (e.g. SnapStream Firefly) |
490 | * "non-toggled" state depends on remote_num, so we xor it with the | ||
491 | * second bit which is only used for toggle. | ||
492 | */ | 484 | */ |
493 | scancode[0] ^= (data[2] & 0x80); | 485 | scancode = data[2] & 0x7f; |
494 | |||
495 | scancode[1] = data[2] & ~0x80; | ||
496 | 486 | ||
497 | /* Look up event code index in mouse translation table. */ | 487 | /* Look up event code index in the mouse translation table. */ |
498 | index = ati_remote_event_lookup(remote_num, scancode[0], scancode[1]); | 488 | for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) { |
489 | if (scancode == ati_remote_tbl[i].data) { | ||
490 | index = i; | ||
491 | break; | ||
492 | } | ||
493 | } | ||
499 | 494 | ||
500 | if (index >= 0) { | 495 | if (index >= 0) { |
501 | dbginfo(&ati_remote->interface->dev, | 496 | dbginfo(&ati_remote->interface->dev, |
502 | "channel 0x%02x; mouse data %02x,%02x; index %d; keycode %d\n", | 497 | "channel 0x%02x; mouse data %02x; index %d; keycode %d\n", |
503 | remote_num, data[1], data[2], index, ati_remote_tbl[index].code); | 498 | remote_num, data[2], index, ati_remote_tbl[index].code); |
504 | if (!dev) | 499 | if (!dev) |
505 | return; /* no mouse device */ | 500 | return; /* no mouse device */ |
506 | } else | 501 | } else |
507 | dbginfo(&ati_remote->interface->dev, | 502 | dbginfo(&ati_remote->interface->dev, |
508 | "channel 0x%02x; key data %02x,%02x, scancode %02x,%02x\n", | 503 | "channel 0x%02x; key data %02x, scancode %02x\n", |
509 | remote_num, data[1], data[2], scancode[0], scancode[1]); | 504 | remote_num, data[2], scancode); |
510 | 505 | ||
511 | 506 | ||
512 | if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) { | 507 | if (index >= 0 && ati_remote_tbl[index].kind == KIND_LITERAL) { |
@@ -523,8 +518,7 @@ static void ati_remote_input_report(struct urb *urb) | |||
523 | unsigned long now = jiffies; | 518 | unsigned long now = jiffies; |
524 | 519 | ||
525 | /* Filter duplicate events which happen "too close" together. */ | 520 | /* Filter duplicate events which happen "too close" together. */ |
526 | if (ati_remote->old_data[0] == data[1] && | 521 | if (ati_remote->old_data == data[2] && |
527 | ati_remote->old_data[1] == data[2] && | ||
528 | time_before(now, ati_remote->old_jiffies + | 522 | time_before(now, ati_remote->old_jiffies + |
529 | msecs_to_jiffies(repeat_filter))) { | 523 | msecs_to_jiffies(repeat_filter))) { |
530 | ati_remote->repeat_count++; | 524 | ati_remote->repeat_count++; |
@@ -533,8 +527,7 @@ static void ati_remote_input_report(struct urb *urb) | |||
533 | ati_remote->first_jiffies = now; | 527 | ati_remote->first_jiffies = now; |
534 | } | 528 | } |
535 | 529 | ||
536 | ati_remote->old_data[0] = data[1]; | 530 | ati_remote->old_data = data[2]; |
537 | ati_remote->old_data[1] = data[2]; | ||
538 | ati_remote->old_jiffies = now; | 531 | ati_remote->old_jiffies = now; |
539 | 532 | ||
540 | /* Ensure we skip at least the 4 first duplicate events (generated | 533 | /* Ensure we skip at least the 4 first duplicate events (generated |
@@ -549,14 +542,13 @@ static void ati_remote_input_report(struct urb *urb) | |||
549 | 542 | ||
550 | if (index < 0) { | 543 | if (index < 0) { |
551 | /* Not a mouse event, hand it to rc-core. */ | 544 | /* Not a mouse event, hand it to rc-core. */ |
552 | u32 rc_code = (scancode[0] << 8) | scancode[1]; | ||
553 | 545 | ||
554 | /* | 546 | /* |
555 | * We don't use the rc-core repeat handling yet as | 547 | * We don't use the rc-core repeat handling yet as |
556 | * it would cause ghost repeats which would be a | 548 | * it would cause ghost repeats which would be a |
557 | * regression for this driver. | 549 | * regression for this driver. |
558 | */ | 550 | */ |
559 | rc_keydown_notimeout(ati_remote->rdev, rc_code, | 551 | rc_keydown_notimeout(ati_remote->rdev, scancode, |
560 | data[2]); | 552 | data[2]); |
561 | rc_keyup(ati_remote->rdev); | 553 | rc_keyup(ati_remote->rdev); |
562 | return; | 554 | return; |
@@ -607,8 +599,7 @@ static void ati_remote_input_report(struct urb *urb) | |||
607 | input_sync(dev); | 599 | input_sync(dev); |
608 | 600 | ||
609 | ati_remote->old_jiffies = jiffies; | 601 | ati_remote->old_jiffies = jiffies; |
610 | ati_remote->old_data[0] = data[1]; | 602 | ati_remote->old_data = data[2]; |
611 | ati_remote->old_data[1] = data[2]; | ||
612 | } | 603 | } |
613 | } | 604 | } |
614 | 605 | ||
diff --git a/drivers/media/rc/keymaps/rc-ati-x10.c b/drivers/media/rc/keymaps/rc-ati-x10.c index e1b8b2605c48..81506440eded 100644 --- a/drivers/media/rc/keymaps/rc-ati-x10.c +++ b/drivers/media/rc/keymaps/rc-ati-x10.c | |||
@@ -27,55 +27,55 @@ | |||
27 | #include <media/rc-map.h> | 27 | #include <media/rc-map.h> |
28 | 28 | ||
29 | static struct rc_map_table ati_x10[] = { | 29 | static struct rc_map_table ati_x10[] = { |
30 | { 0xd20d, KEY_1 }, | 30 | { 0x0d, KEY_1 }, |
31 | { 0xd30e, KEY_2 }, | 31 | { 0x0e, KEY_2 }, |
32 | { 0xd40f, KEY_3 }, | 32 | { 0x0f, KEY_3 }, |
33 | { 0xd510, KEY_4 }, | 33 | { 0x10, KEY_4 }, |
34 | { 0xd611, KEY_5 }, | 34 | { 0x11, KEY_5 }, |
35 | { 0xd712, KEY_6 }, | 35 | { 0x12, KEY_6 }, |
36 | { 0xd813, KEY_7 }, | 36 | { 0x13, KEY_7 }, |
37 | { 0xd914, KEY_8 }, | 37 | { 0x14, KEY_8 }, |
38 | { 0xda15, KEY_9 }, | 38 | { 0x15, KEY_9 }, |
39 | { 0xdc17, KEY_0 }, | 39 | { 0x17, KEY_0 }, |
40 | { 0xc500, KEY_A }, | 40 | { 0x00, KEY_A }, |
41 | { 0xc601, KEY_B }, | 41 | { 0x01, KEY_B }, |
42 | { 0xde19, KEY_C }, | 42 | { 0x19, KEY_C }, |
43 | { 0xe01b, KEY_D }, | 43 | { 0x1b, KEY_D }, |
44 | { 0xe621, KEY_E }, | 44 | { 0x21, KEY_E }, |
45 | { 0xe823, KEY_F }, | 45 | { 0x23, KEY_F }, |
46 | 46 | ||
47 | { 0xdd18, KEY_KPENTER }, /* "check" */ | 47 | { 0x18, KEY_KPENTER }, /* "check" */ |
48 | { 0xdb16, KEY_MENU }, /* "menu" */ | 48 | { 0x16, KEY_MENU }, /* "menu" */ |
49 | { 0xc702, KEY_POWER }, /* Power */ | 49 | { 0x02, KEY_POWER }, /* Power */ |
50 | { 0xc803, KEY_TV }, /* TV */ | 50 | { 0x03, KEY_TV }, /* TV */ |
51 | { 0xc904, KEY_DVD }, /* DVD */ | 51 | { 0x04, KEY_DVD }, /* DVD */ |
52 | { 0xca05, KEY_WWW }, /* WEB */ | 52 | { 0x05, KEY_WWW }, /* WEB */ |
53 | { 0xcb06, KEY_BOOKMARKS }, /* "book" */ | 53 | { 0x06, KEY_BOOKMARKS }, /* "book" */ |
54 | { 0xcc07, KEY_EDIT }, /* "hand" */ | 54 | { 0x07, KEY_EDIT }, /* "hand" */ |
55 | { 0xe11c, KEY_COFFEE }, /* "timer" */ | 55 | { 0x1c, KEY_COFFEE }, /* "timer" */ |
56 | { 0xe520, KEY_FRONT }, /* "max" */ | 56 | { 0x20, KEY_FRONT }, /* "max" */ |
57 | { 0xe21d, KEY_LEFT }, /* left */ | 57 | { 0x1d, KEY_LEFT }, /* left */ |
58 | { 0xe41f, KEY_RIGHT }, /* right */ | 58 | { 0x1f, KEY_RIGHT }, /* right */ |
59 | { 0xe722, KEY_DOWN }, /* down */ | 59 | { 0x22, KEY_DOWN }, /* down */ |
60 | { 0xdf1a, KEY_UP }, /* up */ | 60 | { 0x1a, KEY_UP }, /* up */ |
61 | { 0xe31e, KEY_OK }, /* "OK" */ | 61 | { 0x1e, KEY_OK }, /* "OK" */ |
62 | { 0xce09, KEY_VOLUMEDOWN }, /* VOL + */ | 62 | { 0x09, KEY_VOLUMEDOWN }, /* VOL + */ |
63 | { 0xcd08, KEY_VOLUMEUP }, /* VOL - */ | 63 | { 0x08, KEY_VOLUMEUP }, /* VOL - */ |
64 | { 0xcf0a, KEY_MUTE }, /* MUTE */ | 64 | { 0x0a, KEY_MUTE }, /* MUTE */ |
65 | { 0xd00b, KEY_CHANNELUP }, /* CH + */ | 65 | { 0x0b, KEY_CHANNELUP }, /* CH + */ |
66 | { 0xd10c, KEY_CHANNELDOWN },/* CH - */ | 66 | { 0x0c, KEY_CHANNELDOWN },/* CH - */ |
67 | { 0xec27, KEY_RECORD }, /* ( o) red */ | 67 | { 0x27, KEY_RECORD }, /* ( o) red */ |
68 | { 0xea25, KEY_PLAY }, /* ( >) */ | 68 | { 0x25, KEY_PLAY }, /* ( >) */ |
69 | { 0xe924, KEY_REWIND }, /* (<<) */ | 69 | { 0x24, KEY_REWIND }, /* (<<) */ |
70 | { 0xeb26, KEY_FORWARD }, /* (>>) */ | 70 | { 0x26, KEY_FORWARD }, /* (>>) */ |
71 | { 0xed28, KEY_STOP }, /* ([]) */ | 71 | { 0x28, KEY_STOP }, /* ([]) */ |
72 | { 0xee29, KEY_PAUSE }, /* ('') */ | 72 | { 0x29, KEY_PAUSE }, /* ('') */ |
73 | { 0xf02b, KEY_PREVIOUS }, /* (<-) */ | 73 | { 0x2b, KEY_PREVIOUS }, /* (<-) */ |
74 | { 0xef2a, KEY_NEXT }, /* (>+) */ | 74 | { 0x2a, KEY_NEXT }, /* (>+) */ |
75 | { 0xf22d, KEY_INFO }, /* PLAYING */ | 75 | { 0x2d, KEY_INFO }, /* PLAYING */ |
76 | { 0xf32e, KEY_HOME }, /* TOP */ | 76 | { 0x2e, KEY_HOME }, /* TOP */ |
77 | { 0xf42f, KEY_END }, /* END */ | 77 | { 0x2f, KEY_END }, /* END */ |
78 | { 0xf530, KEY_SELECT }, /* SELECT */ | 78 | { 0x30, KEY_SELECT }, /* SELECT */ |
79 | }; | 79 | }; |
80 | 80 | ||
81 | static struct rc_map_list ati_x10_map = { | 81 | static struct rc_map_list ati_x10_map = { |
diff --git a/drivers/media/rc/keymaps/rc-medion-x10.c b/drivers/media/rc/keymaps/rc-medion-x10.c index 09e2cc01d110..479cdb897810 100644 --- a/drivers/media/rc/keymaps/rc-medion-x10.c +++ b/drivers/media/rc/keymaps/rc-medion-x10.c | |||
@@ -25,70 +25,70 @@ | |||
25 | #include <media/rc-map.h> | 25 | #include <media/rc-map.h> |
26 | 26 | ||
27 | static struct rc_map_table medion_x10[] = { | 27 | static struct rc_map_table medion_x10[] = { |
28 | { 0xf12c, KEY_TV }, /* TV */ | 28 | { 0x2c, KEY_TV }, /* TV */ |
29 | { 0xf22d, KEY_VCR }, /* VCR */ | 29 | { 0x2d, KEY_VCR }, /* VCR */ |
30 | { 0xc904, KEY_DVD }, /* DVD */ | 30 | { 0x04, KEY_DVD }, /* DVD */ |
31 | { 0xcb06, KEY_AUDIO }, /* MUSIC */ | 31 | { 0x06, KEY_AUDIO }, /* MUSIC */ |
32 | 32 | ||
33 | { 0xf32e, KEY_RADIO }, /* RADIO */ | 33 | { 0x2e, KEY_RADIO }, /* RADIO */ |
34 | { 0xca05, KEY_DIRECTORY }, /* PHOTO */ | 34 | { 0x05, KEY_DIRECTORY }, /* PHOTO */ |
35 | { 0xf42f, KEY_INFO }, /* TV-PREVIEW */ | 35 | { 0x2f, KEY_INFO }, /* TV-PREVIEW */ |
36 | { 0xf530, KEY_LIST }, /* CHANNEL-LST */ | 36 | { 0x30, KEY_LIST }, /* CHANNEL-LST */ |
37 | 37 | ||
38 | { 0xe01b, KEY_SETUP }, /* SETUP */ | 38 | { 0x1b, KEY_SETUP }, /* SETUP */ |
39 | { 0xf631, KEY_VIDEO }, /* VIDEO DESKTOP */ | 39 | { 0x31, KEY_VIDEO }, /* VIDEO DESKTOP */ |
40 | 40 | ||
41 | { 0xcd08, KEY_VOLUMEDOWN }, /* VOL - */ | 41 | { 0x08, KEY_VOLUMEDOWN }, /* VOL - */ |
42 | { 0xce09, KEY_VOLUMEUP }, /* VOL + */ | 42 | { 0x09, KEY_VOLUMEUP }, /* VOL + */ |
43 | { 0xd00b, KEY_CHANNELUP }, /* CHAN + */ | 43 | { 0x0b, KEY_CHANNELUP }, /* CHAN + */ |
44 | { 0xd10c, KEY_CHANNELDOWN }, /* CHAN - */ | 44 | { 0x0c, KEY_CHANNELDOWN }, /* CHAN - */ |
45 | { 0xc500, KEY_MUTE }, /* MUTE */ | 45 | { 0x00, KEY_MUTE }, /* MUTE */ |
46 | 46 | ||
47 | { 0xf732, KEY_RED }, /* red */ | 47 | { 0x32, KEY_RED }, /* red */ |
48 | { 0xf833, KEY_GREEN }, /* green */ | 48 | { 0x33, KEY_GREEN }, /* green */ |
49 | { 0xf934, KEY_YELLOW }, /* yellow */ | 49 | { 0x34, KEY_YELLOW }, /* yellow */ |
50 | { 0xfa35, KEY_BLUE }, /* blue */ | 50 | { 0x35, KEY_BLUE }, /* blue */ |
51 | { 0xdb16, KEY_TEXT }, /* TXT */ | 51 | { 0x16, KEY_TEXT }, /* TXT */ |
52 | 52 | ||
53 | { 0xd20d, KEY_1 }, | 53 | { 0x0d, KEY_1 }, |
54 | { 0xd30e, KEY_2 }, | 54 | { 0x0e, KEY_2 }, |
55 | { 0xd40f, KEY_3 }, | 55 | { 0x0f, KEY_3 }, |
56 | { 0xd510, KEY_4 }, | 56 | { 0x10, KEY_4 }, |
57 | { 0xd611, KEY_5 }, | 57 | { 0x11, KEY_5 }, |
58 | { 0xd712, KEY_6 }, | 58 | { 0x12, KEY_6 }, |
59 | { 0xd813, KEY_7 }, | 59 | { 0x13, KEY_7 }, |
60 | { 0xd914, KEY_8 }, | 60 | { 0x14, KEY_8 }, |
61 | { 0xda15, KEY_9 }, | 61 | { 0x15, KEY_9 }, |
62 | { 0xdc17, KEY_0 }, | 62 | { 0x17, KEY_0 }, |
63 | { 0xe11c, KEY_SEARCH }, /* TV/RAD, CH SRC */ | 63 | { 0x1c, KEY_SEARCH }, /* TV/RAD, CH SRC */ |
64 | { 0xe520, KEY_DELETE }, /* DELETE */ | 64 | { 0x20, KEY_DELETE }, /* DELETE */ |
65 | 65 | ||
66 | { 0xfb36, KEY_KEYBOARD }, /* RENAME */ | 66 | { 0x36, KEY_KEYBOARD }, /* RENAME */ |
67 | { 0xdd18, KEY_SCREEN }, /* SNAPSHOT */ | 67 | { 0x18, KEY_SCREEN }, /* SNAPSHOT */ |
68 | 68 | ||
69 | { 0xdf1a, KEY_UP }, /* up */ | 69 | { 0x1a, KEY_UP }, /* up */ |
70 | { 0xe722, KEY_DOWN }, /* down */ | 70 | { 0x22, KEY_DOWN }, /* down */ |
71 | { 0xe21d, KEY_LEFT }, /* left */ | 71 | { 0x1d, KEY_LEFT }, /* left */ |
72 | { 0xe41f, KEY_RIGHT }, /* right */ | 72 | { 0x1f, KEY_RIGHT }, /* right */ |
73 | { 0xe31e, KEY_OK }, /* OK */ | 73 | { 0x1e, KEY_OK }, /* OK */ |
74 | 74 | ||
75 | { 0xfc37, KEY_SELECT }, /* ACQUIRE IMAGE */ | 75 | { 0x37, KEY_SELECT }, /* ACQUIRE IMAGE */ |
76 | { 0xfd38, KEY_EDIT }, /* EDIT IMAGE */ | 76 | { 0x38, KEY_EDIT }, /* EDIT IMAGE */ |
77 | 77 | ||
78 | { 0xe924, KEY_REWIND }, /* rewind (<<) */ | 78 | { 0x24, KEY_REWIND }, /* rewind (<<) */ |
79 | { 0xea25, KEY_PLAY }, /* play ( >) */ | 79 | { 0x25, KEY_PLAY }, /* play ( >) */ |
80 | { 0xeb26, KEY_FORWARD }, /* forward (>>) */ | 80 | { 0x26, KEY_FORWARD }, /* forward (>>) */ |
81 | { 0xec27, KEY_RECORD }, /* record ( o) */ | 81 | { 0x27, KEY_RECORD }, /* record ( o) */ |
82 | { 0xed28, KEY_STOP }, /* stop ([]) */ | 82 | { 0x28, KEY_STOP }, /* stop ([]) */ |
83 | { 0xee29, KEY_PAUSE }, /* pause ('') */ | 83 | { 0x29, KEY_PAUSE }, /* pause ('') */ |
84 | 84 | ||
85 | { 0xe621, KEY_PREVIOUS }, /* prev */ | 85 | { 0x21, KEY_PREVIOUS }, /* prev */ |
86 | { 0xfe39, KEY_SWITCHVIDEOMODE }, /* F SCR */ | 86 | { 0x39, KEY_SWITCHVIDEOMODE }, /* F SCR */ |
87 | { 0xe823, KEY_NEXT }, /* next */ | 87 | { 0x23, KEY_NEXT }, /* next */ |
88 | { 0xde19, KEY_MENU }, /* MENU */ | 88 | { 0x19, KEY_MENU }, /* MENU */ |
89 | { 0xff3a, KEY_LANGUAGE }, /* AUDIO */ | 89 | { 0x3a, KEY_LANGUAGE }, /* AUDIO */ |
90 | 90 | ||
91 | { 0xc702, KEY_POWER }, /* POWER */ | 91 | { 0x02, KEY_POWER }, /* POWER */ |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static struct rc_map_list medion_x10_map = { | 94 | static struct rc_map_list medion_x10_map = { |
diff --git a/drivers/media/rc/keymaps/rc-snapstream-firefly.c b/drivers/media/rc/keymaps/rc-snapstream-firefly.c index ef146520931c..c7f33ec719b4 100644 --- a/drivers/media/rc/keymaps/rc-snapstream-firefly.c +++ b/drivers/media/rc/keymaps/rc-snapstream-firefly.c | |||
@@ -22,63 +22,63 @@ | |||
22 | #include <media/rc-map.h> | 22 | #include <media/rc-map.h> |
23 | 23 | ||
24 | static struct rc_map_table snapstream_firefly[] = { | 24 | static struct rc_map_table snapstream_firefly[] = { |
25 | { 0xf12c, KEY_ZOOM }, /* Maximize */ | 25 | { 0x2c, KEY_ZOOM }, /* Maximize */ |
26 | { 0xc702, KEY_CLOSE }, | 26 | { 0x02, KEY_CLOSE }, |
27 | 27 | ||
28 | { 0xd20d, KEY_1 }, | 28 | { 0x0d, KEY_1 }, |
29 | { 0xd30e, KEY_2 }, | 29 | { 0x0e, KEY_2 }, |
30 | { 0xd40f, KEY_3 }, | 30 | { 0x0f, KEY_3 }, |
31 | { 0xd510, KEY_4 }, | 31 | { 0x10, KEY_4 }, |
32 | { 0xd611, KEY_5 }, | 32 | { 0x11, KEY_5 }, |
33 | { 0xd712, KEY_6 }, | 33 | { 0x12, KEY_6 }, |
34 | { 0xd813, KEY_7 }, | 34 | { 0x13, KEY_7 }, |
35 | { 0xd914, KEY_8 }, | 35 | { 0x14, KEY_8 }, |
36 | { 0xda15, KEY_9 }, | 36 | { 0x15, KEY_9 }, |
37 | { 0xdc17, KEY_0 }, | 37 | { 0x17, KEY_0 }, |
38 | { 0xdb16, KEY_BACK }, | 38 | { 0x16, KEY_BACK }, |
39 | { 0xdd18, KEY_KPENTER }, /* ent */ | 39 | { 0x18, KEY_KPENTER }, /* ent */ |
40 | 40 | ||
41 | { 0xce09, KEY_VOLUMEUP }, | 41 | { 0x09, KEY_VOLUMEUP }, |
42 | { 0xcd08, KEY_VOLUMEDOWN }, | 42 | { 0x08, KEY_VOLUMEDOWN }, |
43 | { 0xcf0a, KEY_MUTE }, | 43 | { 0x0a, KEY_MUTE }, |
44 | { 0xd00b, KEY_CHANNELUP }, | 44 | { 0x0b, KEY_CHANNELUP }, |
45 | { 0xd10c, KEY_CHANNELDOWN }, | 45 | { 0x0c, KEY_CHANNELDOWN }, |
46 | { 0xc500, KEY_VENDOR }, /* firefly */ | 46 | { 0x00, KEY_VENDOR }, /* firefly */ |
47 | 47 | ||
48 | { 0xf32e, KEY_INFO }, | 48 | { 0x2e, KEY_INFO }, |
49 | { 0xf42f, KEY_OPTION }, | 49 | { 0x2f, KEY_OPTION }, |
50 | 50 | ||
51 | { 0xe21d, KEY_LEFT }, | 51 | { 0x1d, KEY_LEFT }, |
52 | { 0xe41f, KEY_RIGHT }, | 52 | { 0x1f, KEY_RIGHT }, |
53 | { 0xe722, KEY_DOWN }, | 53 | { 0x22, KEY_DOWN }, |
54 | { 0xdf1a, KEY_UP }, | 54 | { 0x1a, KEY_UP }, |
55 | { 0xe31e, KEY_OK }, | 55 | { 0x1e, KEY_OK }, |
56 | 56 | ||
57 | { 0xe11c, KEY_MENU }, | 57 | { 0x1c, KEY_MENU }, |
58 | { 0xe520, KEY_EXIT }, | 58 | { 0x20, KEY_EXIT }, |
59 | 59 | ||
60 | { 0xec27, KEY_RECORD }, | 60 | { 0x27, KEY_RECORD }, |
61 | { 0xea25, KEY_PLAY }, | 61 | { 0x25, KEY_PLAY }, |
62 | { 0xed28, KEY_STOP }, | 62 | { 0x28, KEY_STOP }, |
63 | { 0xe924, KEY_REWIND }, | 63 | { 0x24, KEY_REWIND }, |
64 | { 0xeb26, KEY_FORWARD }, | 64 | { 0x26, KEY_FORWARD }, |
65 | { 0xee29, KEY_PAUSE }, | 65 | { 0x29, KEY_PAUSE }, |
66 | { 0xf02b, KEY_PREVIOUS }, | 66 | { 0x2b, KEY_PREVIOUS }, |
67 | { 0xef2a, KEY_NEXT }, | 67 | { 0x2a, KEY_NEXT }, |
68 | 68 | ||
69 | { 0xcb06, KEY_AUDIO }, /* Music */ | 69 | { 0x06, KEY_AUDIO }, /* Music */ |
70 | { 0xca05, KEY_IMAGES }, /* Photos */ | 70 | { 0x05, KEY_IMAGES }, /* Photos */ |
71 | { 0xc904, KEY_DVD }, | 71 | { 0x04, KEY_DVD }, |
72 | { 0xc803, KEY_TV }, | 72 | { 0x03, KEY_TV }, |
73 | { 0xcc07, KEY_VIDEO }, | 73 | { 0x07, KEY_VIDEO }, |
74 | 74 | ||
75 | { 0xc601, KEY_HELP }, | 75 | { 0x01, KEY_HELP }, |
76 | { 0xf22d, KEY_MODE }, /* Mouse */ | 76 | { 0x2d, KEY_MODE }, /* Mouse */ |
77 | 77 | ||
78 | { 0xde19, KEY_A }, | 78 | { 0x19, KEY_A }, |
79 | { 0xe01b, KEY_B }, | 79 | { 0x1b, KEY_B }, |
80 | { 0xe621, KEY_C }, | 80 | { 0x21, KEY_C }, |
81 | { 0xe823, KEY_D }, | 81 | { 0x23, KEY_D }, |
82 | }; | 82 | }; |
83 | 83 | ||
84 | static struct rc_map_list snapstream_firefly_map = { | 84 | static struct rc_map_list snapstream_firefly_map = { |
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 39fc923fc46b..1c6015a04f96 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c | |||
@@ -162,11 +162,14 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data) | |||
162 | switch (tv.model) { | 162 | switch (tv.model) { |
163 | case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */ | 163 | case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */ |
164 | case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */ | 164 | case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */ |
165 | case 72101: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */ | ||
166 | case 72201: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ | ||
165 | case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ | 167 | case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ |
166 | case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ | 168 | case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ |
167 | case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ | 169 | case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ |
168 | case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and analog video */ | 170 | case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and analog video */ |
169 | case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */ | 171 | case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */ |
172 | case 72261: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */ | ||
170 | case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and analog video */ | 173 | case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and analog video */ |
171 | case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */ | 174 | case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */ |
172 | break; | 175 | break; |
@@ -324,6 +327,10 @@ struct usb_device_id au0828_usb_id_table[] = { | |||
324 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, | 327 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, |
325 | { USB_DEVICE(0x2040, 0x8200), | 328 | { USB_DEVICE(0x2040, 0x8200), |
326 | .driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY }, | 329 | .driver_info = AU0828_BOARD_HAUPPAUGE_WOODBURY }, |
330 | { USB_DEVICE(0x2040, 0x7260), | ||
331 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, | ||
332 | { USB_DEVICE(0x2040, 0x7213), | ||
333 | .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, | ||
327 | { }, | 334 | { }, |
328 | }; | 335 | }; |
329 | 336 | ||
diff --git a/drivers/media/video/m5mols/m5mols.h b/drivers/media/video/m5mols/m5mols.h index 89d09a8914f8..82c8817bd32d 100644 --- a/drivers/media/video/m5mols/m5mols.h +++ b/drivers/media/video/m5mols/m5mols.h | |||
@@ -162,7 +162,6 @@ struct m5mols_version { | |||
162 | * @pad: media pad | 162 | * @pad: media pad |
163 | * @ffmt: current fmt according to resolution type | 163 | * @ffmt: current fmt according to resolution type |
164 | * @res_type: current resolution type | 164 | * @res_type: current resolution type |
165 | * @code: current code | ||
166 | * @irq_waitq: waitqueue for the capture | 165 | * @irq_waitq: waitqueue for the capture |
167 | * @work_irq: workqueue for the IRQ | 166 | * @work_irq: workqueue for the IRQ |
168 | * @flags: state variable for the interrupt handler | 167 | * @flags: state variable for the interrupt handler |
@@ -192,7 +191,6 @@ struct m5mols_info { | |||
192 | struct media_pad pad; | 191 | struct media_pad pad; |
193 | struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX]; | 192 | struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX]; |
194 | int res_type; | 193 | int res_type; |
195 | enum v4l2_mbus_pixelcode code; | ||
196 | wait_queue_head_t irq_waitq; | 194 | wait_queue_head_t irq_waitq; |
197 | struct work_struct work_irq; | 195 | struct work_struct work_irq; |
198 | unsigned long flags; | 196 | unsigned long flags; |
diff --git a/drivers/media/video/m5mols/m5mols_core.c b/drivers/media/video/m5mols/m5mols_core.c index 05ab3700647e..e0f09e531800 100644 --- a/drivers/media/video/m5mols/m5mols_core.c +++ b/drivers/media/video/m5mols/m5mols_core.c | |||
@@ -334,7 +334,7 @@ int m5mols_mode(struct m5mols_info *info, u8 mode) | |||
334 | int ret = -EINVAL; | 334 | int ret = -EINVAL; |
335 | u8 reg; | 335 | u8 reg; |
336 | 336 | ||
337 | if (mode < REG_PARAMETER && mode > REG_CAPTURE) | 337 | if (mode < REG_PARAMETER || mode > REG_CAPTURE) |
338 | return ret; | 338 | return ret; |
339 | 339 | ||
340 | ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, ®); | 340 | ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, ®); |
@@ -511,9 +511,6 @@ static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
511 | struct m5mols_info *info = to_m5mols(sd); | 511 | struct m5mols_info *info = to_m5mols(sd); |
512 | struct v4l2_mbus_framefmt *format; | 512 | struct v4l2_mbus_framefmt *format; |
513 | 513 | ||
514 | if (fmt->pad != 0) | ||
515 | return -EINVAL; | ||
516 | |||
517 | format = __find_format(info, fh, fmt->which, info->res_type); | 514 | format = __find_format(info, fh, fmt->which, info->res_type); |
518 | if (!format) | 515 | if (!format) |
519 | return -EINVAL; | 516 | return -EINVAL; |
@@ -532,9 +529,6 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
532 | u32 resolution = 0; | 529 | u32 resolution = 0; |
533 | int ret; | 530 | int ret; |
534 | 531 | ||
535 | if (fmt->pad != 0) | ||
536 | return -EINVAL; | ||
537 | |||
538 | ret = __find_resolution(sd, format, &type, &resolution); | 532 | ret = __find_resolution(sd, format, &type, &resolution); |
539 | if (ret < 0) | 533 | if (ret < 0) |
540 | return ret; | 534 | return ret; |
@@ -543,13 +537,14 @@ static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, | |||
543 | if (!sfmt) | 537 | if (!sfmt) |
544 | return 0; | 538 | return 0; |
545 | 539 | ||
546 | *sfmt = m5mols_default_ffmt[type]; | 540 | |
547 | sfmt->width = format->width; | 541 | format->code = m5mols_default_ffmt[type].code; |
548 | sfmt->height = format->height; | 542 | format->colorspace = V4L2_COLORSPACE_JPEG; |
543 | format->field = V4L2_FIELD_NONE; | ||
549 | 544 | ||
550 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { | 545 | if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { |
546 | *sfmt = *format; | ||
551 | info->resolution = resolution; | 547 | info->resolution = resolution; |
552 | info->code = format->code; | ||
553 | info->res_type = type; | 548 | info->res_type = type; |
554 | } | 549 | } |
555 | 550 | ||
@@ -626,13 +621,14 @@ static int m5mols_start_monitor(struct m5mols_info *info) | |||
626 | static int m5mols_s_stream(struct v4l2_subdev *sd, int enable) | 621 | static int m5mols_s_stream(struct v4l2_subdev *sd, int enable) |
627 | { | 622 | { |
628 | struct m5mols_info *info = to_m5mols(sd); | 623 | struct m5mols_info *info = to_m5mols(sd); |
624 | u32 code = info->ffmt[info->res_type].code; | ||
629 | 625 | ||
630 | if (enable) { | 626 | if (enable) { |
631 | int ret = -EINVAL; | 627 | int ret = -EINVAL; |
632 | 628 | ||
633 | if (is_code(info->code, M5MOLS_RESTYPE_MONITOR)) | 629 | if (is_code(code, M5MOLS_RESTYPE_MONITOR)) |
634 | ret = m5mols_start_monitor(info); | 630 | ret = m5mols_start_monitor(info); |
635 | if (is_code(info->code, M5MOLS_RESTYPE_CAPTURE)) | 631 | if (is_code(code, M5MOLS_RESTYPE_CAPTURE)) |
636 | ret = m5mols_start_capture(info); | 632 | ret = m5mols_start_capture(info); |
637 | 633 | ||
638 | return ret; | 634 | return ret; |
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c index cf2c0fb95f2f..398f96ffd35e 100644 --- a/drivers/media/video/mt9m111.c +++ b/drivers/media/video/mt9m111.c | |||
@@ -955,6 +955,7 @@ static int mt9m111_probe(struct i2c_client *client, | |||
955 | mt9m111->rect.height = MT9M111_MAX_HEIGHT; | 955 | mt9m111->rect.height = MT9M111_MAX_HEIGHT; |
956 | mt9m111->fmt = &mt9m111_colour_fmts[0]; | 956 | mt9m111->fmt = &mt9m111_colour_fmts[0]; |
957 | mt9m111->lastpage = -1; | 957 | mt9m111->lastpage = -1; |
958 | mutex_init(&mt9m111->power_lock); | ||
958 | 959 | ||
959 | ret = mt9m111_video_probe(client); | 960 | ret = mt9m111_video_probe(client); |
960 | if (ret) { | 961 | if (ret) { |
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c index 32114a3c0ca7..7b34b11daf24 100644 --- a/drivers/media/video/mt9t112.c +++ b/drivers/media/video/mt9t112.c | |||
@@ -1083,8 +1083,10 @@ static int mt9t112_probe(struct i2c_client *client, | |||
1083 | v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); | 1083 | v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); |
1084 | 1084 | ||
1085 | ret = mt9t112_camera_probe(client); | 1085 | ret = mt9t112_camera_probe(client); |
1086 | if (ret) | 1086 | if (ret) { |
1087 | kfree(priv); | 1087 | kfree(priv); |
1088 | return ret; | ||
1089 | } | ||
1088 | 1090 | ||
1089 | /* Cannot fail: using the default supported pixel code */ | 1091 | /* Cannot fail: using the default supported pixel code */ |
1090 | mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8); | 1092 | mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8); |
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 9c5c19f142de..ee0d0b39cd17 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/irq.h> | 38 | #include <linux/irq.h> |
39 | #include <linux/videodev2.h> | 39 | #include <linux/videodev2.h> |
40 | #include <linux/dma-mapping.h> | 40 | #include <linux/dma-mapping.h> |
41 | #include <linux/slab.h> | ||
41 | 42 | ||
42 | #include <media/videobuf-dma-contig.h> | 43 | #include <media/videobuf-dma-contig.h> |
43 | #include <media/v4l2-device.h> | 44 | #include <media/v4l2-device.h> |
@@ -2169,6 +2170,14 @@ static int __init omap_vout_probe(struct platform_device *pdev) | |||
2169 | vid_dev->num_displays = 0; | 2170 | vid_dev->num_displays = 0; |
2170 | for_each_dss_dev(dssdev) { | 2171 | for_each_dss_dev(dssdev) { |
2171 | omap_dss_get_device(dssdev); | 2172 | omap_dss_get_device(dssdev); |
2173 | |||
2174 | if (!dssdev->driver) { | ||
2175 | dev_warn(&pdev->dev, "no driver for display: %s\n", | ||
2176 | dssdev->name); | ||
2177 | omap_dss_put_device(dssdev); | ||
2178 | continue; | ||
2179 | } | ||
2180 | |||
2172 | vid_dev->displays[vid_dev->num_displays++] = dssdev; | 2181 | vid_dev->displays[vid_dev->num_displays++] = dssdev; |
2173 | } | 2182 | } |
2174 | 2183 | ||
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c index e87ae2f634b2..6a6cf388bae4 100644 --- a/drivers/media/video/omap1_camera.c +++ b/drivers/media/video/omap1_camera.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/module.h> | ||
27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
29 | 30 | ||
diff --git a/drivers/media/video/omap24xxcam-dma.c b/drivers/media/video/omap24xxcam-dma.c index 1d54b86c936b..3ea38a8def8e 100644 --- a/drivers/media/video/omap24xxcam-dma.c +++ b/drivers/media/video/omap24xxcam-dma.c | |||
@@ -506,7 +506,7 @@ int omap24xxcam_sgdma_queue(struct omap24xxcam_sgdma *sgdma, | |||
506 | unsigned long flags; | 506 | unsigned long flags; |
507 | struct sgdma_state *sg_state; | 507 | struct sgdma_state *sg_state; |
508 | 508 | ||
509 | if ((sglen < 0) || ((sglen > 0) & !sglist)) | 509 | if ((sglen < 0) || ((sglen > 0) && !sglist)) |
510 | return -EINVAL; | 510 | return -EINVAL; |
511 | 511 | ||
512 | spin_lock_irqsave(&sgdma->lock, flags); | 512 | spin_lock_irqsave(&sgdma->lock, flags); |
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c index d1000723c5ae..f2290578448c 100644 --- a/drivers/media/video/omap3isp/ispvideo.c +++ b/drivers/media/video/omap3isp/ispvideo.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/module.h> | ||
29 | #include <linux/pagemap.h> | 30 | #include <linux/pagemap.h> |
30 | #include <linux/scatterlist.h> | 31 | #include <linux/scatterlist.h> |
31 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c index 9f2d26b1d4cb..6806345ec2f0 100644 --- a/drivers/media/video/ov6650.c +++ b/drivers/media/video/ov6650.c | |||
@@ -540,7 +540,7 @@ static u8 to_clkrc(struct v4l2_fract *timeperframe, | |||
540 | static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) | 540 | static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) |
541 | { | 541 | { |
542 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 542 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
543 | struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id; | 543 | struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); |
544 | struct soc_camera_sense *sense = icd->sense; | 544 | struct soc_camera_sense *sense = icd->sense; |
545 | struct ov6650 *priv = to_ov6650(client); | 545 | struct ov6650 *priv = to_ov6650(client); |
546 | bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); | 546 | bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); |
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index c8d91b0cd9bd..2cc3b9166724 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -98,6 +98,10 @@ static int fimc_capture_state_cleanup(struct fimc_dev *fimc, bool suspend) | |||
98 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); | 98 | vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR); |
99 | } | 99 | } |
100 | set_bit(ST_CAPT_SUSPENDED, &fimc->state); | 100 | set_bit(ST_CAPT_SUSPENDED, &fimc->state); |
101 | |||
102 | fimc_hw_reset(fimc); | ||
103 | cap->buf_index = 0; | ||
104 | |||
101 | spin_unlock_irqrestore(&fimc->slock, flags); | 105 | spin_unlock_irqrestore(&fimc->slock, flags); |
102 | 106 | ||
103 | if (streaming) | 107 | if (streaming) |
@@ -137,7 +141,7 @@ int fimc_capture_config_update(struct fimc_ctx *ctx) | |||
137 | struct fimc_dev *fimc = ctx->fimc_dev; | 141 | struct fimc_dev *fimc = ctx->fimc_dev; |
138 | int ret; | 142 | int ret; |
139 | 143 | ||
140 | if (test_bit(ST_CAPT_APPLY_CFG, &fimc->state)) | 144 | if (!test_bit(ST_CAPT_APPLY_CFG, &fimc->state)) |
141 | return 0; | 145 | return 0; |
142 | 146 | ||
143 | spin_lock(&ctx->slock); | 147 | spin_lock(&ctx->slock); |
@@ -150,7 +154,7 @@ int fimc_capture_config_update(struct fimc_ctx *ctx) | |||
150 | fimc_hw_set_rotation(ctx); | 154 | fimc_hw_set_rotation(ctx); |
151 | fimc_prepare_dma_offset(ctx, &ctx->d_frame); | 155 | fimc_prepare_dma_offset(ctx, &ctx->d_frame); |
152 | fimc_hw_set_out_dma(ctx); | 156 | fimc_hw_set_out_dma(ctx); |
153 | set_bit(ST_CAPT_APPLY_CFG, &fimc->state); | 157 | clear_bit(ST_CAPT_APPLY_CFG, &fimc->state); |
154 | } | 158 | } |
155 | spin_unlock(&ctx->slock); | 159 | spin_unlock(&ctx->slock); |
156 | return ret; | 160 | return ret; |
@@ -164,7 +168,6 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) | |||
164 | int min_bufs; | 168 | int min_bufs; |
165 | int ret; | 169 | int ret; |
166 | 170 | ||
167 | fimc_hw_reset(fimc); | ||
168 | vid_cap->frame_count = 0; | 171 | vid_cap->frame_count = 0; |
169 | 172 | ||
170 | ret = fimc_init_capture(fimc); | 173 | ret = fimc_init_capture(fimc); |
@@ -523,7 +526,7 @@ static struct fimc_fmt *fimc_capture_try_format(struct fimc_ctx *ctx, | |||
523 | max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w; | 526 | max_w = rotation ? pl->out_rot_en_w : pl->out_rot_dis_w; |
524 | min_w = ctx->state & FIMC_DST_CROP ? dst->width : var->min_out_pixsize; | 527 | min_w = ctx->state & FIMC_DST_CROP ? dst->width : var->min_out_pixsize; |
525 | min_h = ctx->state & FIMC_DST_CROP ? dst->height : var->min_out_pixsize; | 528 | min_h = ctx->state & FIMC_DST_CROP ? dst->height : var->min_out_pixsize; |
526 | if (fimc->id == 1 && var->pix_hoff) | 529 | if (var->min_vsize_align == 1 && !rotation) |
527 | align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1; | 530 | align_h = fimc_fmt_is_rgb(ffmt->color) ? 0 : 1; |
528 | 531 | ||
529 | depth = fimc_get_format_depth(ffmt); | 532 | depth = fimc_get_format_depth(ffmt); |
@@ -1239,6 +1242,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, | |||
1239 | 1242 | ||
1240 | mutex_lock(&fimc->lock); | 1243 | mutex_lock(&fimc->lock); |
1241 | set_frame_bounds(ff, mf->width, mf->height); | 1244 | set_frame_bounds(ff, mf->width, mf->height); |
1245 | fimc->vid_cap.mf = *mf; | ||
1242 | ff->fmt = ffmt; | 1246 | ff->fmt = ffmt; |
1243 | 1247 | ||
1244 | /* Reset the crop rectangle if required. */ | 1248 | /* Reset the crop rectangle if required. */ |
@@ -1375,7 +1379,7 @@ static void fimc_destroy_capture_subdev(struct fimc_dev *fimc) | |||
1375 | media_entity_cleanup(&sd->entity); | 1379 | media_entity_cleanup(&sd->entity); |
1376 | v4l2_device_unregister_subdev(sd); | 1380 | v4l2_device_unregister_subdev(sd); |
1377 | kfree(sd); | 1381 | kfree(sd); |
1378 | sd = NULL; | 1382 | fimc->vid_cap.subdev = NULL; |
1379 | } | 1383 | } |
1380 | 1384 | ||
1381 | /* Set default format at the sensor and host interface */ | 1385 | /* Set default format at the sensor and host interface */ |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 19ca6db38b2f..07c6254faee3 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -37,7 +37,7 @@ static char *fimc_clocks[MAX_FIMC_CLOCKS] = { | |||
37 | static struct fimc_fmt fimc_formats[] = { | 37 | static struct fimc_fmt fimc_formats[] = { |
38 | { | 38 | { |
39 | .name = "RGB565", | 39 | .name = "RGB565", |
40 | .fourcc = V4L2_PIX_FMT_RGB565X, | 40 | .fourcc = V4L2_PIX_FMT_RGB565, |
41 | .depth = { 16 }, | 41 | .depth = { 16 }, |
42 | .color = S5P_FIMC_RGB565, | 42 | .color = S5P_FIMC_RGB565, |
43 | .memplanes = 1, | 43 | .memplanes = 1, |
@@ -1038,12 +1038,11 @@ static int fimc_try_fmt_mplane(struct fimc_ctx *ctx, struct v4l2_format *f) | |||
1038 | mod_x = 6; /* 64 x 32 pixels tile */ | 1038 | mod_x = 6; /* 64 x 32 pixels tile */ |
1039 | mod_y = 5; | 1039 | mod_y = 5; |
1040 | } else { | 1040 | } else { |
1041 | if (fimc->id == 1 && variant->pix_hoff) | 1041 | if (variant->min_vsize_align == 1) |
1042 | mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1; | 1042 | mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1; |
1043 | else | 1043 | else |
1044 | mod_y = mod_x; | 1044 | mod_y = ffs(variant->min_vsize_align) - 1; |
1045 | } | 1045 | } |
1046 | dbg("mod_x: %d, mod_y: %d, max_w: %d", mod_x, mod_y, max_w); | ||
1047 | 1046 | ||
1048 | v4l_bound_align_image(&pix->width, 16, max_w, mod_x, | 1047 | v4l_bound_align_image(&pix->width, 16, max_w, mod_x, |
1049 | &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0); | 1048 | &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0); |
@@ -1226,10 +1225,10 @@ static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr) | |||
1226 | fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize; | 1225 | fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize; |
1227 | 1226 | ||
1228 | /* Get pixel alignment constraints. */ | 1227 | /* Get pixel alignment constraints. */ |
1229 | if (fimc->id == 1 && fimc->variant->pix_hoff) | 1228 | if (fimc->variant->min_vsize_align == 1) |
1230 | halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1; | 1229 | halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1; |
1231 | else | 1230 | else |
1232 | halign = ffs(min_size) - 1; | 1231 | halign = ffs(fimc->variant->min_vsize_align) - 1; |
1233 | 1232 | ||
1234 | for (i = 0; i < f->fmt->colplanes; i++) | 1233 | for (i = 0; i < f->fmt->colplanes; i++) |
1235 | depth += f->fmt->depth[i]; | 1234 | depth += f->fmt->depth[i]; |
@@ -1615,7 +1614,6 @@ static int fimc_probe(struct platform_device *pdev) | |||
1615 | pdata = pdev->dev.platform_data; | 1614 | pdata = pdev->dev.platform_data; |
1616 | fimc->pdata = pdata; | 1615 | fimc->pdata = pdata; |
1617 | 1616 | ||
1618 | set_bit(ST_LPM, &fimc->state); | ||
1619 | 1617 | ||
1620 | init_waitqueue_head(&fimc->irq_queue); | 1618 | init_waitqueue_head(&fimc->irq_queue); |
1621 | spin_lock_init(&fimc->slock); | 1619 | spin_lock_init(&fimc->slock); |
@@ -1707,8 +1705,6 @@ static int fimc_runtime_resume(struct device *dev) | |||
1707 | /* Enable clocks and perform basic initalization */ | 1705 | /* Enable clocks and perform basic initalization */ |
1708 | clk_enable(fimc->clock[CLK_GATE]); | 1706 | clk_enable(fimc->clock[CLK_GATE]); |
1709 | fimc_hw_reset(fimc); | 1707 | fimc_hw_reset(fimc); |
1710 | if (fimc->variant->out_buf_count > 4) | ||
1711 | fimc_hw_set_dma_seq(fimc, 0xF); | ||
1712 | 1708 | ||
1713 | /* Resume the capture or mem-to-mem device */ | 1709 | /* Resume the capture or mem-to-mem device */ |
1714 | if (fimc_capture_busy(fimc)) | 1710 | if (fimc_capture_busy(fimc)) |
@@ -1750,8 +1746,6 @@ static int fimc_resume(struct device *dev) | |||
1750 | return 0; | 1746 | return 0; |
1751 | } | 1747 | } |
1752 | fimc_hw_reset(fimc); | 1748 | fimc_hw_reset(fimc); |
1753 | if (fimc->variant->out_buf_count > 4) | ||
1754 | fimc_hw_set_dma_seq(fimc, 0xF); | ||
1755 | spin_unlock_irqrestore(&fimc->slock, flags); | 1749 | spin_unlock_irqrestore(&fimc->slock, flags); |
1756 | 1750 | ||
1757 | if (fimc_capture_busy(fimc)) | 1751 | if (fimc_capture_busy(fimc)) |
@@ -1780,7 +1774,6 @@ static int __devexit fimc_remove(struct platform_device *pdev) | |||
1780 | struct fimc_dev *fimc = platform_get_drvdata(pdev); | 1774 | struct fimc_dev *fimc = platform_get_drvdata(pdev); |
1781 | 1775 | ||
1782 | pm_runtime_disable(&pdev->dev); | 1776 | pm_runtime_disable(&pdev->dev); |
1783 | fimc_runtime_suspend(&pdev->dev); | ||
1784 | pm_runtime_set_suspended(&pdev->dev); | 1777 | pm_runtime_set_suspended(&pdev->dev); |
1785 | 1778 | ||
1786 | vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); | 1779 | vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx); |
@@ -1840,6 +1833,7 @@ static struct samsung_fimc_variant fimc0_variant_s5p = { | |||
1840 | .min_inp_pixsize = 16, | 1833 | .min_inp_pixsize = 16, |
1841 | .min_out_pixsize = 16, | 1834 | .min_out_pixsize = 16, |
1842 | .hor_offs_align = 8, | 1835 | .hor_offs_align = 8, |
1836 | .min_vsize_align = 16, | ||
1843 | .out_buf_count = 4, | 1837 | .out_buf_count = 4, |
1844 | .pix_limit = &s5p_pix_limit[0], | 1838 | .pix_limit = &s5p_pix_limit[0], |
1845 | }; | 1839 | }; |
@@ -1849,6 +1843,7 @@ static struct samsung_fimc_variant fimc2_variant_s5p = { | |||
1849 | .min_inp_pixsize = 16, | 1843 | .min_inp_pixsize = 16, |
1850 | .min_out_pixsize = 16, | 1844 | .min_out_pixsize = 16, |
1851 | .hor_offs_align = 8, | 1845 | .hor_offs_align = 8, |
1846 | .min_vsize_align = 16, | ||
1852 | .out_buf_count = 4, | 1847 | .out_buf_count = 4, |
1853 | .pix_limit = &s5p_pix_limit[1], | 1848 | .pix_limit = &s5p_pix_limit[1], |
1854 | }; | 1849 | }; |
@@ -1861,6 +1856,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv210 = { | |||
1861 | .min_inp_pixsize = 16, | 1856 | .min_inp_pixsize = 16, |
1862 | .min_out_pixsize = 16, | 1857 | .min_out_pixsize = 16, |
1863 | .hor_offs_align = 8, | 1858 | .hor_offs_align = 8, |
1859 | .min_vsize_align = 16, | ||
1864 | .out_buf_count = 4, | 1860 | .out_buf_count = 4, |
1865 | .pix_limit = &s5p_pix_limit[1], | 1861 | .pix_limit = &s5p_pix_limit[1], |
1866 | }; | 1862 | }; |
@@ -1874,6 +1870,7 @@ static struct samsung_fimc_variant fimc1_variant_s5pv210 = { | |||
1874 | .min_inp_pixsize = 16, | 1870 | .min_inp_pixsize = 16, |
1875 | .min_out_pixsize = 16, | 1871 | .min_out_pixsize = 16, |
1876 | .hor_offs_align = 1, | 1872 | .hor_offs_align = 1, |
1873 | .min_vsize_align = 1, | ||
1877 | .out_buf_count = 4, | 1874 | .out_buf_count = 4, |
1878 | .pix_limit = &s5p_pix_limit[2], | 1875 | .pix_limit = &s5p_pix_limit[2], |
1879 | }; | 1876 | }; |
@@ -1884,6 +1881,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv210 = { | |||
1884 | .min_inp_pixsize = 16, | 1881 | .min_inp_pixsize = 16, |
1885 | .min_out_pixsize = 16, | 1882 | .min_out_pixsize = 16, |
1886 | .hor_offs_align = 8, | 1883 | .hor_offs_align = 8, |
1884 | .min_vsize_align = 16, | ||
1887 | .out_buf_count = 4, | 1885 | .out_buf_count = 4, |
1888 | .pix_limit = &s5p_pix_limit[2], | 1886 | .pix_limit = &s5p_pix_limit[2], |
1889 | }; | 1887 | }; |
@@ -1898,6 +1896,7 @@ static struct samsung_fimc_variant fimc0_variant_exynos4 = { | |||
1898 | .min_inp_pixsize = 16, | 1896 | .min_inp_pixsize = 16, |
1899 | .min_out_pixsize = 16, | 1897 | .min_out_pixsize = 16, |
1900 | .hor_offs_align = 2, | 1898 | .hor_offs_align = 2, |
1899 | .min_vsize_align = 1, | ||
1901 | .out_buf_count = 32, | 1900 | .out_buf_count = 32, |
1902 | .pix_limit = &s5p_pix_limit[1], | 1901 | .pix_limit = &s5p_pix_limit[1], |
1903 | }; | 1902 | }; |
@@ -1910,6 +1909,7 @@ static struct samsung_fimc_variant fimc3_variant_exynos4 = { | |||
1910 | .min_inp_pixsize = 16, | 1909 | .min_inp_pixsize = 16, |
1911 | .min_out_pixsize = 16, | 1910 | .min_out_pixsize = 16, |
1912 | .hor_offs_align = 2, | 1911 | .hor_offs_align = 2, |
1912 | .min_vsize_align = 1, | ||
1913 | .out_buf_count = 32, | 1913 | .out_buf_count = 32, |
1914 | .pix_limit = &s5p_pix_limit[3], | 1914 | .pix_limit = &s5p_pix_limit[3], |
1915 | }; | 1915 | }; |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index a6936dad5b10..c7f01c47b20f 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h | |||
@@ -377,6 +377,7 @@ struct fimc_pix_limit { | |||
377 | * @min_inp_pixsize: minimum input pixel size | 377 | * @min_inp_pixsize: minimum input pixel size |
378 | * @min_out_pixsize: minimum output pixel size | 378 | * @min_out_pixsize: minimum output pixel size |
379 | * @hor_offs_align: horizontal pixel offset aligment | 379 | * @hor_offs_align: horizontal pixel offset aligment |
380 | * @min_vsize_align: minimum vertical pixel size alignment | ||
380 | * @out_buf_count: the number of buffers in output DMA sequence | 381 | * @out_buf_count: the number of buffers in output DMA sequence |
381 | */ | 382 | */ |
382 | struct samsung_fimc_variant { | 383 | struct samsung_fimc_variant { |
@@ -390,6 +391,7 @@ struct samsung_fimc_variant { | |||
390 | u16 min_inp_pixsize; | 391 | u16 min_inp_pixsize; |
391 | u16 min_out_pixsize; | 392 | u16 min_out_pixsize; |
392 | u16 hor_offs_align; | 393 | u16 hor_offs_align; |
394 | u16 min_vsize_align; | ||
393 | u16 out_buf_count; | 395 | u16 out_buf_count; |
394 | }; | 396 | }; |
395 | 397 | ||
diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index cc337b1de913..615c862f0360 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c | |||
@@ -220,6 +220,7 @@ static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd, | |||
220 | sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter, | 220 | sd = v4l2_i2c_new_subdev_board(&fmd->v4l2_dev, adapter, |
221 | s_info->pdata->board_info, NULL); | 221 | s_info->pdata->board_info, NULL); |
222 | if (IS_ERR_OR_NULL(sd)) { | 222 | if (IS_ERR_OR_NULL(sd)) { |
223 | i2c_put_adapter(adapter); | ||
223 | v4l2_err(&fmd->v4l2_dev, "Failed to acquire subdev\n"); | 224 | v4l2_err(&fmd->v4l2_dev, "Failed to acquire subdev\n"); |
224 | return NULL; | 225 | return NULL; |
225 | } | 226 | } |
@@ -234,12 +235,15 @@ static struct v4l2_subdev *fimc_md_register_sensor(struct fimc_md *fmd, | |||
234 | static void fimc_md_unregister_sensor(struct v4l2_subdev *sd) | 235 | static void fimc_md_unregister_sensor(struct v4l2_subdev *sd) |
235 | { | 236 | { |
236 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 237 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
238 | struct i2c_adapter *adapter; | ||
237 | 239 | ||
238 | if (!client) | 240 | if (!client) |
239 | return; | 241 | return; |
240 | v4l2_device_unregister_subdev(sd); | 242 | v4l2_device_unregister_subdev(sd); |
243 | adapter = client->adapter; | ||
241 | i2c_unregister_device(client); | 244 | i2c_unregister_device(client); |
242 | i2c_put_adapter(client->adapter); | 245 | if (adapter) |
246 | i2c_put_adapter(adapter); | ||
243 | } | 247 | } |
244 | 248 | ||
245 | static int fimc_md_register_sensor_entities(struct fimc_md *fmd) | 249 | static int fimc_md_register_sensor_entities(struct fimc_md *fmd) |
@@ -381,20 +385,28 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) | |||
381 | 385 | ||
382 | static int fimc_md_register_video_nodes(struct fimc_md *fmd) | 386 | static int fimc_md_register_video_nodes(struct fimc_md *fmd) |
383 | { | 387 | { |
388 | struct video_device *vdev; | ||
384 | int i, ret = 0; | 389 | int i, ret = 0; |
385 | 390 | ||
386 | for (i = 0; i < FIMC_MAX_DEVS && !ret; i++) { | 391 | for (i = 0; i < FIMC_MAX_DEVS && !ret; i++) { |
387 | if (!fmd->fimc[i]) | 392 | if (!fmd->fimc[i]) |
388 | continue; | 393 | continue; |
389 | 394 | ||
390 | if (fmd->fimc[i]->m2m.vfd) | 395 | vdev = fmd->fimc[i]->m2m.vfd; |
391 | ret = video_register_device(fmd->fimc[i]->m2m.vfd, | 396 | if (vdev) { |
392 | VFL_TYPE_GRABBER, -1); | 397 | ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); |
393 | if (ret) | 398 | if (ret) |
394 | break; | 399 | break; |
395 | if (fmd->fimc[i]->vid_cap.vfd) | 400 | v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n", |
396 | ret = video_register_device(fmd->fimc[i]->vid_cap.vfd, | 401 | vdev->name, video_device_node_name(vdev)); |
397 | VFL_TYPE_GRABBER, -1); | 402 | } |
403 | |||
404 | vdev = fmd->fimc[i]->vid_cap.vfd; | ||
405 | if (vdev == NULL) | ||
406 | continue; | ||
407 | ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); | ||
408 | v4l2_info(&fmd->v4l2_dev, "Registered %s as /dev/%s\n", | ||
409 | vdev->name, video_device_node_name(vdev)); | ||
398 | } | 410 | } |
399 | 411 | ||
400 | return ret; | 412 | return ret; |
@@ -502,7 +514,7 @@ static int fimc_md_create_links(struct fimc_md *fmd) | |||
502 | if (WARN(csis == NULL, | 514 | if (WARN(csis == NULL, |
503 | "MIPI-CSI interface specified " | 515 | "MIPI-CSI interface specified " |
504 | "but s5p-csis module is not loaded!\n")) | 516 | "but s5p-csis module is not loaded!\n")) |
505 | continue; | 517 | return -EINVAL; |
506 | 518 | ||
507 | ret = media_entity_create_link(&sensor->entity, 0, | 519 | ret = media_entity_create_link(&sensor->entity, 0, |
508 | &csis->entity, CSIS_PAD_SINK, | 520 | &csis->entity, CSIS_PAD_SINK, |
@@ -742,9 +754,6 @@ static int __devinit fimc_md_probe(struct platform_device *pdev) | |||
742 | struct fimc_md *fmd; | 754 | struct fimc_md *fmd; |
743 | int ret; | 755 | int ret; |
744 | 756 | ||
745 | if (WARN(!pdev->dev.platform_data, "Platform data not specified!\n")) | ||
746 | return -EINVAL; | ||
747 | |||
748 | fmd = kzalloc(sizeof(struct fimc_md), GFP_KERNEL); | 757 | fmd = kzalloc(sizeof(struct fimc_md), GFP_KERNEL); |
749 | if (!fmd) | 758 | if (!fmd) |
750 | return -ENOMEM; | 759 | return -ENOMEM; |
@@ -782,9 +791,11 @@ static int __devinit fimc_md_probe(struct platform_device *pdev) | |||
782 | if (ret) | 791 | if (ret) |
783 | goto err3; | 792 | goto err3; |
784 | 793 | ||
785 | ret = fimc_md_register_sensor_entities(fmd); | 794 | if (pdev->dev.platform_data) { |
786 | if (ret) | 795 | ret = fimc_md_register_sensor_entities(fmd); |
787 | goto err3; | 796 | if (ret) |
797 | goto err3; | ||
798 | } | ||
788 | ret = fimc_md_create_links(fmd); | 799 | ret = fimc_md_create_links(fmd); |
789 | if (ret) | 800 | if (ret) |
790 | goto err3; | 801 | goto err3; |
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c index 20e664e34163..44f5c2d1920b 100644 --- a/drivers/media/video/s5p-fimc/fimc-reg.c +++ b/drivers/media/video/s5p-fimc/fimc-reg.c | |||
@@ -35,6 +35,9 @@ void fimc_hw_reset(struct fimc_dev *dev) | |||
35 | cfg = readl(dev->regs + S5P_CIGCTRL); | 35 | cfg = readl(dev->regs + S5P_CIGCTRL); |
36 | cfg &= ~S5P_CIGCTRL_SWRST; | 36 | cfg &= ~S5P_CIGCTRL_SWRST; |
37 | writel(cfg, dev->regs + S5P_CIGCTRL); | 37 | writel(cfg, dev->regs + S5P_CIGCTRL); |
38 | |||
39 | if (dev->variant->out_buf_count > 4) | ||
40 | fimc_hw_set_dma_seq(dev, 0xF); | ||
38 | } | 41 | } |
39 | 42 | ||
40 | static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx) | 43 | static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx) |
@@ -251,7 +254,14 @@ static void fimc_hw_set_scaler(struct fimc_ctx *ctx) | |||
251 | struct fimc_scaler *sc = &ctx->scaler; | 254 | struct fimc_scaler *sc = &ctx->scaler; |
252 | struct fimc_frame *src_frame = &ctx->s_frame; | 255 | struct fimc_frame *src_frame = &ctx->s_frame; |
253 | struct fimc_frame *dst_frame = &ctx->d_frame; | 256 | struct fimc_frame *dst_frame = &ctx->d_frame; |
254 | u32 cfg = 0; | 257 | |
258 | u32 cfg = readl(dev->regs + S5P_CISCCTRL); | ||
259 | |||
260 | cfg &= ~(S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE | | ||
261 | S5P_CISCCTRL_SCALEUP_H | S5P_CISCCTRL_SCALEUP_V | | ||
262 | S5P_CISCCTRL_SCALERBYPASS | S5P_CISCCTRL_ONE2ONE | | ||
263 | S5P_CISCCTRL_INRGB_FMT_MASK | S5P_CISCCTRL_OUTRGB_FMT_MASK | | ||
264 | S5P_CISCCTRL_INTERLACE | S5P_CISCCTRL_RGB_EXT); | ||
255 | 265 | ||
256 | if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW)) | 266 | if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW)) |
257 | cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE); | 267 | cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE); |
@@ -308,9 +318,9 @@ void fimc_hw_set_mainscaler(struct fimc_ctx *ctx) | |||
308 | fimc_hw_set_scaler(ctx); | 318 | fimc_hw_set_scaler(ctx); |
309 | 319 | ||
310 | cfg = readl(dev->regs + S5P_CISCCTRL); | 320 | cfg = readl(dev->regs + S5P_CISCCTRL); |
321 | cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK); | ||
311 | 322 | ||
312 | if (variant->has_mainscaler_ext) { | 323 | if (variant->has_mainscaler_ext) { |
313 | cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK); | ||
314 | cfg |= S5P_CISCCTRL_MHRATIO_EXT(sc->main_hratio); | 324 | cfg |= S5P_CISCCTRL_MHRATIO_EXT(sc->main_hratio); |
315 | cfg |= S5P_CISCCTRL_MVRATIO_EXT(sc->main_vratio); | 325 | cfg |= S5P_CISCCTRL_MVRATIO_EXT(sc->main_vratio); |
316 | writel(cfg, dev->regs + S5P_CISCCTRL); | 326 | writel(cfg, dev->regs + S5P_CISCCTRL); |
@@ -323,7 +333,6 @@ void fimc_hw_set_mainscaler(struct fimc_ctx *ctx) | |||
323 | cfg |= S5P_CIEXTEN_MVRATIO_EXT(sc->main_vratio); | 333 | cfg |= S5P_CIEXTEN_MVRATIO_EXT(sc->main_vratio); |
324 | writel(cfg, dev->regs + S5P_CIEXTEN); | 334 | writel(cfg, dev->regs + S5P_CIEXTEN); |
325 | } else { | 335 | } else { |
326 | cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK); | ||
327 | cfg |= S5P_CISCCTRL_MHRATIO(sc->main_hratio); | 336 | cfg |= S5P_CISCCTRL_MHRATIO(sc->main_hratio); |
328 | cfg |= S5P_CISCCTRL_MVRATIO(sc->main_vratio); | 337 | cfg |= S5P_CISCCTRL_MVRATIO(sc->main_vratio); |
329 | writel(cfg, dev->regs + S5P_CISCCTRL); | 338 | writel(cfg, dev->regs + S5P_CISCCTRL); |
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index 1e8cdb77d4b8..dff9dc798795 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c | |||
@@ -61,7 +61,7 @@ static struct s5p_mfc_fmt formats[] = { | |||
61 | .num_planes = 1, | 61 | .num_planes = 1, |
62 | }, | 62 | }, |
63 | { | 63 | { |
64 | .name = "H264 Encoded Stream", | 64 | .name = "H263 Encoded Stream", |
65 | .fourcc = V4L2_PIX_FMT_H263, | 65 | .fourcc = V4L2_PIX_FMT_H263, |
66 | .codec_mode = S5P_FIMV_CODEC_H263_ENC, | 66 | .codec_mode = S5P_FIMV_CODEC_H263_ENC, |
67 | .type = MFC_FMT_ENC, | 67 | .type = MFC_FMT_ENC, |
diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c index e16d3a4bc1dc..b47d0c06ecf5 100644 --- a/drivers/media/video/s5p-tv/mixer_video.c +++ b/drivers/media/video/s5p-tv/mixer_video.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <media/v4l2-ioctl.h> | 16 | #include <media/v4l2-ioctl.h> |
17 | #include <linux/videodev2.h> | 17 | #include <linux/videodev2.h> |
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <linux/module.h> | ||
19 | #include <linux/version.h> | 20 | #include <linux/version.h> |
20 | #include <linux/timer.h> | 21 | #include <linux/timer.h> |
21 | #include <media/videobuf2-dma-contig.h> | 22 | #include <media/videobuf2-dma-contig.h> |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index f390682629cf..c51decfcae19 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -566,8 +566,10 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) | |||
566 | ret = sh_mobile_ceu_soft_reset(pcdev); | 566 | ret = sh_mobile_ceu_soft_reset(pcdev); |
567 | 567 | ||
568 | csi2_sd = find_csi2(pcdev); | 568 | csi2_sd = find_csi2(pcdev); |
569 | if (csi2_sd) | 569 | if (csi2_sd) { |
570 | csi2_sd->grp_id = (long)icd; | 570 | csi2_sd->grp_id = soc_camera_grp_id(icd); |
571 | v4l2_set_subdev_hostdata(csi2_sd, icd); | ||
572 | } | ||
571 | 573 | ||
572 | ret = v4l2_subdev_call(csi2_sd, core, s_power, 1); | 574 | ret = v4l2_subdev_call(csi2_sd, core, s_power, 1); |
573 | if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) { | 575 | if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) { |
@@ -768,7 +770,7 @@ static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev, | |||
768 | { | 770 | { |
769 | if (pcdev->csi2_pdev) { | 771 | if (pcdev->csi2_pdev) { |
770 | struct v4l2_subdev *csi2_sd = find_csi2(pcdev); | 772 | struct v4l2_subdev *csi2_sd = find_csi2(pcdev); |
771 | if (csi2_sd && csi2_sd->grp_id == (u32)icd) | 773 | if (csi2_sd && csi2_sd->grp_id == soc_camera_grp_id(icd)) |
772 | return csi2_sd; | 774 | return csi2_sd; |
773 | } | 775 | } |
774 | 776 | ||
@@ -1089,8 +1091,9 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int | |||
1089 | /* Try 2560x1920, 1280x960, 640x480, 320x240 */ | 1091 | /* Try 2560x1920, 1280x960, 640x480, 320x240 */ |
1090 | mf.width = 2560 >> shift; | 1092 | mf.width = 2560 >> shift; |
1091 | mf.height = 1920 >> shift; | 1093 | mf.height = 1920 >> shift; |
1092 | ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, | 1094 | ret = v4l2_device_call_until_err(sd->v4l2_dev, |
1093 | s_mbus_fmt, &mf); | 1095 | soc_camera_grp_id(icd), video, |
1096 | s_mbus_fmt, &mf); | ||
1094 | if (ret < 0) | 1097 | if (ret < 0) |
1095 | return ret; | 1098 | return ret; |
1096 | shift++; | 1099 | shift++; |
@@ -1389,7 +1392,8 @@ static int client_s_fmt(struct soc_camera_device *icd, | |||
1389 | bool ceu_1to1; | 1392 | bool ceu_1to1; |
1390 | int ret; | 1393 | int ret; |
1391 | 1394 | ||
1392 | ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, | 1395 | ret = v4l2_device_call_until_err(sd->v4l2_dev, |
1396 | soc_camera_grp_id(icd), video, | ||
1393 | s_mbus_fmt, mf); | 1397 | s_mbus_fmt, mf); |
1394 | if (ret < 0) | 1398 | if (ret < 0) |
1395 | return ret; | 1399 | return ret; |
@@ -1426,8 +1430,9 @@ static int client_s_fmt(struct soc_camera_device *icd, | |||
1426 | tmp_h = min(2 * tmp_h, max_height); | 1430 | tmp_h = min(2 * tmp_h, max_height); |
1427 | mf->width = tmp_w; | 1431 | mf->width = tmp_w; |
1428 | mf->height = tmp_h; | 1432 | mf->height = tmp_h; |
1429 | ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, | 1433 | ret = v4l2_device_call_until_err(sd->v4l2_dev, |
1430 | s_mbus_fmt, mf); | 1434 | soc_camera_grp_id(icd), video, |
1435 | s_mbus_fmt, mf); | ||
1431 | dev_geo(dev, "Camera scaled to %ux%u\n", | 1436 | dev_geo(dev, "Camera scaled to %ux%u\n", |
1432 | mf->width, mf->height); | 1437 | mf->width, mf->height); |
1433 | if (ret < 0) { | 1438 | if (ret < 0) { |
@@ -1580,8 +1585,9 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, | |||
1580 | } | 1585 | } |
1581 | 1586 | ||
1582 | if (interm_width < icd->user_width || interm_height < icd->user_height) { | 1587 | if (interm_width < icd->user_width || interm_height < icd->user_height) { |
1583 | ret = v4l2_device_call_until_err(sd->v4l2_dev, (int)icd, video, | 1588 | ret = v4l2_device_call_until_err(sd->v4l2_dev, |
1584 | s_mbus_fmt, &mf); | 1589 | soc_camera_grp_id(icd), video, |
1590 | s_mbus_fmt, &mf); | ||
1585 | if (ret < 0) | 1591 | if (ret < 0) |
1586 | return ret; | 1592 | return ret; |
1587 | 1593 | ||
@@ -1867,7 +1873,8 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, | |||
1867 | mf.code = xlate->code; | 1873 | mf.code = xlate->code; |
1868 | mf.colorspace = pix->colorspace; | 1874 | mf.colorspace = pix->colorspace; |
1869 | 1875 | ||
1870 | ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, try_mbus_fmt, &mf); | 1876 | ret = v4l2_device_call_until_err(sd->v4l2_dev, soc_camera_grp_id(icd), |
1877 | video, try_mbus_fmt, &mf); | ||
1871 | if (ret < 0) | 1878 | if (ret < 0) |
1872 | return ret; | 1879 | return ret; |
1873 | 1880 | ||
@@ -1891,8 +1898,9 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, | |||
1891 | */ | 1898 | */ |
1892 | mf.width = 2560; | 1899 | mf.width = 2560; |
1893 | mf.height = 1920; | 1900 | mf.height = 1920; |
1894 | ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, | 1901 | ret = v4l2_device_call_until_err(sd->v4l2_dev, |
1895 | try_mbus_fmt, &mf); | 1902 | soc_camera_grp_id(icd), video, |
1903 | try_mbus_fmt, &mf); | ||
1896 | if (ret < 0) { | 1904 | if (ret < 0) { |
1897 | /* Shouldn't actually happen... */ | 1905 | /* Shouldn't actually happen... */ |
1898 | dev_err(icd->parent, | 1906 | dev_err(icd->parent, |
diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/video/sh_mobile_csi2.c index ea4f0473ed3b..8a652b53ff7e 100644 --- a/drivers/media/video/sh_mobile_csi2.c +++ b/drivers/media/video/sh_mobile_csi2.c | |||
@@ -143,7 +143,7 @@ static int sh_csi2_s_mbus_config(struct v4l2_subdev *sd, | |||
143 | const struct v4l2_mbus_config *cfg) | 143 | const struct v4l2_mbus_config *cfg) |
144 | { | 144 | { |
145 | struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); | 145 | struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); |
146 | struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id; | 146 | struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); |
147 | struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); | 147 | struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); |
148 | struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2, | 148 | struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2, |
149 | .flags = priv->mipi_flags}; | 149 | .flags = priv->mipi_flags}; |
@@ -202,7 +202,7 @@ static void sh_csi2_hwinit(struct sh_csi2 *priv) | |||
202 | static int sh_csi2_client_connect(struct sh_csi2 *priv) | 202 | static int sh_csi2_client_connect(struct sh_csi2 *priv) |
203 | { | 203 | { |
204 | struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; | 204 | struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; |
205 | struct soc_camera_device *icd = (struct soc_camera_device *)priv->subdev.grp_id; | 205 | struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev); |
206 | struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); | 206 | struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); |
207 | struct device *dev = v4l2_get_subdevdata(&priv->subdev); | 207 | struct device *dev = v4l2_get_subdevdata(&priv->subdev); |
208 | struct v4l2_mbus_config cfg; | 208 | struct v4l2_mbus_config cfg; |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index b72580c38957..62e4312515cb 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -1103,7 +1103,8 @@ static int soc_camera_probe(struct soc_camera_device *icd) | |||
1103 | } | 1103 | } |
1104 | 1104 | ||
1105 | sd = soc_camera_to_subdev(icd); | 1105 | sd = soc_camera_to_subdev(icd); |
1106 | sd->grp_id = (long)icd; | 1106 | sd->grp_id = soc_camera_grp_id(icd); |
1107 | v4l2_set_subdev_hostdata(sd, icd); | ||
1107 | 1108 | ||
1108 | if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler)) | 1109 | if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler)) |
1109 | goto ectrl; | 1110 | goto ectrl; |
diff --git a/drivers/mfd/ab5500-debugfs.c b/drivers/mfd/ab5500-debugfs.c index 43c0ebb81956..b7b2d3483fd4 100644 --- a/drivers/mfd/ab5500-debugfs.c +++ b/drivers/mfd/ab5500-debugfs.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Debugfs support for the AB5500 MFD driver | 4 | * Debugfs support for the AB5500 MFD driver |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/export.h> | 7 | #include <linux/module.h> |
8 | #include <linux/debugfs.h> | 8 | #include <linux/debugfs.h> |
9 | #include <linux/seq_file.h> | 9 | #include <linux/seq_file.h> |
10 | #include <linux/mfd/ab5500/ab5500.h> | 10 | #include <linux/mfd/ab5500/ab5500.h> |
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 1e9173804ede..d3d572b2317b 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -620,6 +620,7 @@ static struct resource __devinitdata ab8500_fg_resources[] = { | |||
620 | 620 | ||
621 | static struct resource __devinitdata ab8500_chargalg_resources[] = {}; | 621 | static struct resource __devinitdata ab8500_chargalg_resources[] = {}; |
622 | 622 | ||
623 | #ifdef CONFIG_DEBUG_FS | ||
623 | static struct resource __devinitdata ab8500_debug_resources[] = { | 624 | static struct resource __devinitdata ab8500_debug_resources[] = { |
624 | { | 625 | { |
625 | .name = "IRQ_FIRST", | 626 | .name = "IRQ_FIRST", |
@@ -634,6 +635,7 @@ static struct resource __devinitdata ab8500_debug_resources[] = { | |||
634 | .flags = IORESOURCE_IRQ, | 635 | .flags = IORESOURCE_IRQ, |
635 | }, | 636 | }, |
636 | }; | 637 | }; |
638 | #endif | ||
637 | 639 | ||
638 | static struct resource __devinitdata ab8500_usb_resources[] = { | 640 | static struct resource __devinitdata ab8500_usb_resources[] = { |
639 | { | 641 | { |
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index f1d88483112c..8d816cce8322 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c | |||
@@ -109,7 +109,7 @@ int adp5520_set_bits(struct device *dev, int reg, uint8_t bit_mask) | |||
109 | 109 | ||
110 | ret = __adp5520_read(chip->client, reg, ®_val); | 110 | ret = __adp5520_read(chip->client, reg, ®_val); |
111 | 111 | ||
112 | if (!ret && ((reg_val & bit_mask) == 0)) { | 112 | if (!ret && ((reg_val & bit_mask) != bit_mask)) { |
113 | reg_val |= bit_mask; | 113 | reg_val |= bit_mask; |
114 | ret = __adp5520_write(chip->client, reg, reg_val); | 114 | ret = __adp5520_write(chip->client, reg, reg_val); |
115 | } | 115 | } |
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index 1b79c37fd599..1924b857a0fb 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c | |||
@@ -182,7 +182,7 @@ int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask) | |||
182 | if (ret) | 182 | if (ret) |
183 | goto out; | 183 | goto out; |
184 | 184 | ||
185 | if ((reg_val & bit_mask) == 0) { | 185 | if ((reg_val & bit_mask) != bit_mask) { |
186 | reg_val |= bit_mask; | 186 | reg_val |= bit_mask; |
187 | ret = __da903x_write(chip->client, reg, reg_val); | 187 | ret = __da903x_write(chip->client, reg, reg_val); |
188 | } | 188 | } |
@@ -549,6 +549,7 @@ static int __devexit da903x_remove(struct i2c_client *client) | |||
549 | struct da903x_chip *chip = i2c_get_clientdata(client); | 549 | struct da903x_chip *chip = i2c_get_clientdata(client); |
550 | 550 | ||
551 | da903x_remove_subdevs(chip); | 551 | da903x_remove_subdevs(chip); |
552 | free_irq(client->irq, chip); | ||
552 | kfree(chip); | 553 | kfree(chip); |
553 | return 0; | 554 | return 0; |
554 | } | 555 | } |
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 1e9ee533eacb..ef39528088f2 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c | |||
@@ -16,6 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/io.h> | ||
19 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
20 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
21 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index bba26d96c240..a5ddf31b60ca 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c | |||
@@ -197,7 +197,7 @@ int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask) | |||
197 | if (ret) | 197 | if (ret) |
198 | goto out; | 198 | goto out; |
199 | 199 | ||
200 | if ((reg_val & bit_mask) == 0) { | 200 | if ((reg_val & bit_mask) != bit_mask) { |
201 | reg_val |= bit_mask; | 201 | reg_val |= bit_mask; |
202 | ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val); | 202 | ret = __tps6586x_write(to_i2c_client(dev), reg, reg_val); |
203 | } | 203 | } |
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 6f5b8cf2f652..c1da84bc1573 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c | |||
@@ -120,7 +120,7 @@ int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask) | |||
120 | goto out; | 120 | goto out; |
121 | } | 121 | } |
122 | 122 | ||
123 | data &= mask; | 123 | data &= ~mask; |
124 | err = tps65910_i2c_write(tps65910, reg, 1, &data); | 124 | err = tps65910_i2c_write(tps65910, reg, 1, &data); |
125 | if (err) | 125 | if (err) |
126 | dev_err(tps65910->dev, "write to reg %x failed\n", reg); | 126 | dev_err(tps65910->dev, "write to reg %x failed\n", reg); |
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index bfbd66021afd..61e70cfaa774 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -363,13 +363,13 @@ int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) | |||
363 | pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); | 363 | pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); |
364 | return -EPERM; | 364 | return -EPERM; |
365 | } | 365 | } |
366 | sid = twl_map[mod_no].sid; | ||
367 | twl = &twl_modules[sid]; | ||
368 | |||
369 | if (unlikely(!inuse)) { | 366 | if (unlikely(!inuse)) { |
370 | pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid); | 367 | pr_err("%s: not initialized\n", DRIVER_NAME); |
371 | return -EPERM; | 368 | return -EPERM; |
372 | } | 369 | } |
370 | sid = twl_map[mod_no].sid; | ||
371 | twl = &twl_modules[sid]; | ||
372 | |||
373 | mutex_lock(&twl->xfer_lock); | 373 | mutex_lock(&twl->xfer_lock); |
374 | /* | 374 | /* |
375 | * [MSG1]: fill the register address data | 375 | * [MSG1]: fill the register address data |
@@ -420,13 +420,13 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) | |||
420 | pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); | 420 | pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no); |
421 | return -EPERM; | 421 | return -EPERM; |
422 | } | 422 | } |
423 | sid = twl_map[mod_no].sid; | ||
424 | twl = &twl_modules[sid]; | ||
425 | |||
426 | if (unlikely(!inuse)) { | 423 | if (unlikely(!inuse)) { |
427 | pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid); | 424 | pr_err("%s: not initialized\n", DRIVER_NAME); |
428 | return -EPERM; | 425 | return -EPERM; |
429 | } | 426 | } |
427 | sid = twl_map[mod_no].sid; | ||
428 | twl = &twl_modules[sid]; | ||
429 | |||
430 | mutex_lock(&twl->xfer_lock); | 430 | mutex_lock(&twl->xfer_lock); |
431 | /* [MSG1] fill the register address data */ | 431 | /* [MSG1] fill the register address data */ |
432 | msg = &twl->xfer_msg[0]; | 432 | msg = &twl->xfer_msg[0]; |
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index f062c8cc6c38..29f11e0765fe 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c | |||
@@ -432,6 +432,7 @@ struct sih_agent { | |||
432 | u32 edge_change; | 432 | u32 edge_change; |
433 | 433 | ||
434 | struct mutex irq_lock; | 434 | struct mutex irq_lock; |
435 | char *irq_name; | ||
435 | }; | 436 | }; |
436 | 437 | ||
437 | /*----------------------------------------------------------------------*/ | 438 | /*----------------------------------------------------------------------*/ |
@@ -589,7 +590,7 @@ static inline int sih_read_isr(const struct sih *sih) | |||
589 | * Generic handler for SIH interrupts ... we "know" this is called | 590 | * Generic handler for SIH interrupts ... we "know" this is called |
590 | * in task context, with IRQs enabled. | 591 | * in task context, with IRQs enabled. |
591 | */ | 592 | */ |
592 | static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) | 593 | static irqreturn_t handle_twl4030_sih(int irq, void *data) |
593 | { | 594 | { |
594 | struct sih_agent *agent = irq_get_handler_data(irq); | 595 | struct sih_agent *agent = irq_get_handler_data(irq); |
595 | const struct sih *sih = agent->sih; | 596 | const struct sih *sih = agent->sih; |
@@ -602,7 +603,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) | |||
602 | pr_err("twl4030: %s SIH, read ISR error %d\n", | 603 | pr_err("twl4030: %s SIH, read ISR error %d\n", |
603 | sih->name, isr); | 604 | sih->name, isr); |
604 | /* REVISIT: recover; eventually mask it all, etc */ | 605 | /* REVISIT: recover; eventually mask it all, etc */ |
605 | return; | 606 | return IRQ_HANDLED; |
606 | } | 607 | } |
607 | 608 | ||
608 | while (isr) { | 609 | while (isr) { |
@@ -616,6 +617,7 @@ static void handle_twl4030_sih(unsigned irq, struct irq_desc *desc) | |||
616 | pr_err("twl4030: %s SIH, invalid ISR bit %d\n", | 617 | pr_err("twl4030: %s SIH, invalid ISR bit %d\n", |
617 | sih->name, irq); | 618 | sih->name, irq); |
618 | } | 619 | } |
620 | return IRQ_HANDLED; | ||
619 | } | 621 | } |
620 | 622 | ||
621 | static unsigned twl4030_irq_next; | 623 | static unsigned twl4030_irq_next; |
@@ -668,18 +670,19 @@ int twl4030_sih_setup(int module) | |||
668 | activate_irq(irq); | 670 | activate_irq(irq); |
669 | } | 671 | } |
670 | 672 | ||
671 | status = irq_base; | ||
672 | twl4030_irq_next += i; | 673 | twl4030_irq_next += i; |
673 | 674 | ||
674 | /* replace generic PIH handler (handle_simple_irq) */ | 675 | /* replace generic PIH handler (handle_simple_irq) */ |
675 | irq = sih_mod + twl4030_irq_base; | 676 | irq = sih_mod + twl4030_irq_base; |
676 | irq_set_handler_data(irq, agent); | 677 | irq_set_handler_data(irq, agent); |
677 | irq_set_chained_handler(irq, handle_twl4030_sih); | 678 | agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name); |
679 | status = request_threaded_irq(irq, NULL, handle_twl4030_sih, 0, | ||
680 | agent->irq_name ?: sih->name, NULL); | ||
678 | 681 | ||
679 | pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name, | 682 | pr_info("twl4030: %s (irq %d) chaining IRQs %d..%d\n", sih->name, |
680 | irq, irq_base, twl4030_irq_next - 1); | 683 | irq, irq_base, twl4030_irq_next - 1); |
681 | 684 | ||
682 | return status; | 685 | return status < 0 ? status : irq_base; |
683 | } | 686 | } |
684 | 687 | ||
685 | /* FIXME need a call to reverse twl4030_sih_setup() ... */ | 688 | /* FIXME need a call to reverse twl4030_sih_setup() ... */ |
@@ -733,8 +736,9 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end) | |||
733 | } | 736 | } |
734 | 737 | ||
735 | /* install an irq handler to demultiplex the TWL4030 interrupt */ | 738 | /* install an irq handler to demultiplex the TWL4030 interrupt */ |
736 | status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih, 0, | 739 | status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih, |
737 | "TWL4030-PIH", NULL); | 740 | IRQF_ONESHOT, |
741 | "TWL4030-PIH", NULL); | ||
738 | if (status < 0) { | 742 | if (status < 0) { |
739 | pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status); | 743 | pr_err("twl4030: could not claim irq%d: %d\n", irq_num, status); |
740 | goto fail_rqirq; | 744 | goto fail_rqirq; |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 5d6ba132837e..61894fced8ea 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -239,6 +239,7 @@ static int wm8994_suspend(struct device *dev) | |||
239 | 239 | ||
240 | switch (wm8994->type) { | 240 | switch (wm8994->type) { |
241 | case WM8958: | 241 | case WM8958: |
242 | case WM1811: | ||
242 | ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1); | 243 | ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1); |
243 | if (ret < 0) { | 244 | if (ret < 0) { |
244 | dev_err(dev, "Failed to read power status: %d\n", ret); | 245 | dev_err(dev, "Failed to read power status: %d\n", ret); |
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index a1cb21f95302..1e0e27cbe987 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -1606,6 +1606,14 @@ static const struct mmc_fixup blk_fixups[] = | |||
1606 | MMC_QUIRK_BLK_NO_CMD23), | 1606 | MMC_QUIRK_BLK_NO_CMD23), |
1607 | MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc, | 1607 | MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc, |
1608 | MMC_QUIRK_BLK_NO_CMD23), | 1608 | MMC_QUIRK_BLK_NO_CMD23), |
1609 | |||
1610 | /* | ||
1611 | * Some Micron MMC cards needs longer data read timeout than | ||
1612 | * indicated in CSD. | ||
1613 | */ | ||
1614 | MMC_FIXUP(CID_NAME_ANY, 0x13, 0x200, add_quirk_mmc, | ||
1615 | MMC_QUIRK_LONG_READ_TIME), | ||
1616 | |||
1609 | END_FIXUP | 1617 | END_FIXUP |
1610 | }; | 1618 | }; |
1611 | 1619 | ||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 5278ffb20e74..950b97d7412a 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -529,6 +529,18 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card) | |||
529 | data->timeout_clks = 0; | 529 | data->timeout_clks = 0; |
530 | } | 530 | } |
531 | } | 531 | } |
532 | |||
533 | /* | ||
534 | * Some cards require longer data read timeout than indicated in CSD. | ||
535 | * Address this by setting the read timeout to a "reasonably high" | ||
536 | * value. For the cards tested, 300ms has proven enough. If necessary, | ||
537 | * this value can be increased if other problematic cards require this. | ||
538 | */ | ||
539 | if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) { | ||
540 | data->timeout_ns = 300000000; | ||
541 | data->timeout_clks = 0; | ||
542 | } | ||
543 | |||
532 | /* | 544 | /* |
533 | * Some cards need very high timeouts if driven in SPI mode. | 545 | * Some cards need very high timeouts if driven in SPI mode. |
534 | * The worst observed timeout was 900ms after writing a | 546 | * The worst observed timeout was 900ms after writing a |
@@ -1213,6 +1225,46 @@ void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type) | |||
1213 | mmc_host_clk_release(host); | 1225 | mmc_host_clk_release(host); |
1214 | } | 1226 | } |
1215 | 1227 | ||
1228 | static void mmc_poweroff_notify(struct mmc_host *host) | ||
1229 | { | ||
1230 | struct mmc_card *card; | ||
1231 | unsigned int timeout; | ||
1232 | unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION; | ||
1233 | int err = 0; | ||
1234 | |||
1235 | card = host->card; | ||
1236 | |||
1237 | /* | ||
1238 | * Send power notify command only if card | ||
1239 | * is mmc and notify state is powered ON | ||
1240 | */ | ||
1241 | if (card && mmc_card_mmc(card) && | ||
1242 | (card->poweroff_notify_state == MMC_POWERED_ON)) { | ||
1243 | |||
1244 | if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) { | ||
1245 | notify_type = EXT_CSD_POWER_OFF_SHORT; | ||
1246 | timeout = card->ext_csd.generic_cmd6_time; | ||
1247 | card->poweroff_notify_state = MMC_POWEROFF_SHORT; | ||
1248 | } else { | ||
1249 | notify_type = EXT_CSD_POWER_OFF_LONG; | ||
1250 | timeout = card->ext_csd.power_off_longtime; | ||
1251 | card->poweroff_notify_state = MMC_POWEROFF_LONG; | ||
1252 | } | ||
1253 | |||
1254 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
1255 | EXT_CSD_POWER_OFF_NOTIFICATION, | ||
1256 | notify_type, timeout); | ||
1257 | |||
1258 | if (err && err != -EBADMSG) | ||
1259 | pr_err("Device failed to respond within %d poweroff " | ||
1260 | "time. Forcefully powering down the device\n", | ||
1261 | timeout); | ||
1262 | |||
1263 | /* Set the card state to no notification after the poweroff */ | ||
1264 | card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION; | ||
1265 | } | ||
1266 | } | ||
1267 | |||
1216 | /* | 1268 | /* |
1217 | * Apply power to the MMC stack. This is a two-stage process. | 1269 | * Apply power to the MMC stack. This is a two-stage process. |
1218 | * First, we enable power to the card without the clock running. | 1270 | * First, we enable power to the card without the clock running. |
@@ -1269,42 +1321,12 @@ static void mmc_power_up(struct mmc_host *host) | |||
1269 | 1321 | ||
1270 | void mmc_power_off(struct mmc_host *host) | 1322 | void mmc_power_off(struct mmc_host *host) |
1271 | { | 1323 | { |
1272 | struct mmc_card *card; | ||
1273 | unsigned int notify_type; | ||
1274 | unsigned int timeout; | ||
1275 | int err; | ||
1276 | |||
1277 | mmc_host_clk_hold(host); | 1324 | mmc_host_clk_hold(host); |
1278 | 1325 | ||
1279 | card = host->card; | ||
1280 | host->ios.clock = 0; | 1326 | host->ios.clock = 0; |
1281 | host->ios.vdd = 0; | 1327 | host->ios.vdd = 0; |
1282 | 1328 | ||
1283 | if (card && mmc_card_mmc(card) && | 1329 | mmc_poweroff_notify(host); |
1284 | (card->poweroff_notify_state == MMC_POWERED_ON)) { | ||
1285 | |||
1286 | if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) { | ||
1287 | notify_type = EXT_CSD_POWER_OFF_SHORT; | ||
1288 | timeout = card->ext_csd.generic_cmd6_time; | ||
1289 | card->poweroff_notify_state = MMC_POWEROFF_SHORT; | ||
1290 | } else { | ||
1291 | notify_type = EXT_CSD_POWER_OFF_LONG; | ||
1292 | timeout = card->ext_csd.power_off_longtime; | ||
1293 | card->poweroff_notify_state = MMC_POWEROFF_LONG; | ||
1294 | } | ||
1295 | |||
1296 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
1297 | EXT_CSD_POWER_OFF_NOTIFICATION, | ||
1298 | notify_type, timeout); | ||
1299 | |||
1300 | if (err && err != -EBADMSG) | ||
1301 | pr_err("Device failed to respond within %d poweroff " | ||
1302 | "time. Forcefully powering down the device\n", | ||
1303 | timeout); | ||
1304 | |||
1305 | /* Set the card state to no notification after the poweroff */ | ||
1306 | card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION; | ||
1307 | } | ||
1308 | 1330 | ||
1309 | /* | 1331 | /* |
1310 | * Reset ocr mask to be the highest possible voltage supported for | 1332 | * Reset ocr mask to be the highest possible voltage supported for |
@@ -2196,7 +2218,7 @@ int mmc_card_sleep(struct mmc_host *host) | |||
2196 | 2218 | ||
2197 | mmc_bus_get(host); | 2219 | mmc_bus_get(host); |
2198 | 2220 | ||
2199 | if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) | 2221 | if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep) |
2200 | err = host->bus_ops->sleep(host); | 2222 | err = host->bus_ops->sleep(host); |
2201 | 2223 | ||
2202 | mmc_bus_put(host); | 2224 | mmc_bus_put(host); |
@@ -2302,8 +2324,17 @@ int mmc_suspend_host(struct mmc_host *host) | |||
2302 | * pre-claim the host. | 2324 | * pre-claim the host. |
2303 | */ | 2325 | */ |
2304 | if (mmc_try_claim_host(host)) { | 2326 | if (mmc_try_claim_host(host)) { |
2305 | if (host->bus_ops->suspend) | 2327 | if (host->bus_ops->suspend) { |
2328 | /* | ||
2329 | * For eMMC 4.5 device send notify command | ||
2330 | * before sleep, because in sleep state eMMC 4.5 | ||
2331 | * devices respond to only RESET and AWAKE cmd | ||
2332 | */ | ||
2333 | mmc_poweroff_notify(host); | ||
2306 | err = host->bus_ops->suspend(host); | 2334 | err = host->bus_ops->suspend(host); |
2335 | } | ||
2336 | mmc_do_release_host(host); | ||
2337 | |||
2307 | if (err == -ENOSYS || !host->bus_ops->resume) { | 2338 | if (err == -ENOSYS || !host->bus_ops->resume) { |
2308 | /* | 2339 | /* |
2309 | * We simply "remove" the card in this case. | 2340 | * We simply "remove" the card in this case. |
@@ -2318,7 +2349,6 @@ int mmc_suspend_host(struct mmc_host *host) | |||
2318 | host->pm_flags = 0; | 2349 | host->pm_flags = 0; |
2319 | err = 0; | 2350 | err = 0; |
2320 | } | 2351 | } |
2321 | mmc_do_release_host(host); | ||
2322 | } else { | 2352 | } else { |
2323 | err = -EBUSY; | 2353 | err = -EBUSY; |
2324 | } | 2354 | } |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index e8a5eb38748b..d31c78b72b0f 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -302,17 +302,6 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
302 | host->max_blk_size = 512; | 302 | host->max_blk_size = 512; |
303 | host->max_blk_count = PAGE_CACHE_SIZE / 512; | 303 | host->max_blk_count = PAGE_CACHE_SIZE / 512; |
304 | 304 | ||
305 | /* | ||
306 | * Enable runtime power management by default. This flag was added due | ||
307 | * to runtime power management causing disruption for some users, but | ||
308 | * the power on/off code has been improved since then. | ||
309 | * | ||
310 | * We'll enable this flag by default as an experiment, and if no | ||
311 | * problems are reported, we will follow up later and remove the flag | ||
312 | * altogether. | ||
313 | */ | ||
314 | host->caps = MMC_CAP_POWER_OFF_CARD; | ||
315 | |||
316 | return host; | 305 | return host; |
317 | 306 | ||
318 | free: | 307 | free: |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index dbf421a6279c..d240427c1246 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -876,17 +876,21 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
876 | * set the notification byte in the ext_csd register of device | 876 | * set the notification byte in the ext_csd register of device |
877 | */ | 877 | */ |
878 | if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) && | 878 | if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) && |
879 | (card->poweroff_notify_state == MMC_NO_POWER_NOTIFICATION)) { | 879 | (card->ext_csd.rev >= 6)) { |
880 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 880 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
881 | EXT_CSD_POWER_OFF_NOTIFICATION, | 881 | EXT_CSD_POWER_OFF_NOTIFICATION, |
882 | EXT_CSD_POWER_ON, | 882 | EXT_CSD_POWER_ON, |
883 | card->ext_csd.generic_cmd6_time); | 883 | card->ext_csd.generic_cmd6_time); |
884 | if (err && err != -EBADMSG) | 884 | if (err && err != -EBADMSG) |
885 | goto free_card; | 885 | goto free_card; |
886 | } | ||
887 | 886 | ||
888 | if (!err) | 887 | /* |
889 | card->poweroff_notify_state = MMC_POWERED_ON; | 888 | * The err can be -EBADMSG or 0, |
889 | * so check for success and update the flag | ||
890 | */ | ||
891 | if (!err) | ||
892 | card->poweroff_notify_state = MMC_POWERED_ON; | ||
893 | } | ||
890 | 894 | ||
891 | /* | 895 | /* |
892 | * Activate high speed (if supported) | 896 | * Activate high speed (if supported) |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 325ea61e12d3..8e0fbe994047 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -732,6 +732,7 @@ static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
732 | "failed to config DMA channel. Falling back to PIO\n"); | 732 | "failed to config DMA channel. Falling back to PIO\n"); |
733 | dma_release_channel(host->dma); | 733 | dma_release_channel(host->dma); |
734 | host->do_dma = 0; | 734 | host->do_dma = 0; |
735 | host->dma = NULL; | ||
735 | } | 736 | } |
736 | } | 737 | } |
737 | 738 | ||
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 101cd31c8220..d5fe43d53c51 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -1010,6 +1010,7 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno) | |||
1010 | host->data->sg_len, | 1010 | host->data->sg_len, |
1011 | omap_hsmmc_get_dma_dir(host, host->data)); | 1011 | omap_hsmmc_get_dma_dir(host, host->data)); |
1012 | omap_free_dma(dma_ch); | 1012 | omap_free_dma(dma_ch); |
1013 | host->data->host_cookie = 0; | ||
1013 | } | 1014 | } |
1014 | host->data = NULL; | 1015 | host->data = NULL; |
1015 | } | 1016 | } |
@@ -1575,8 +1576,10 @@ static void omap_hsmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | |||
1575 | struct mmc_data *data = mrq->data; | 1576 | struct mmc_data *data = mrq->data; |
1576 | 1577 | ||
1577 | if (host->use_dma) { | 1578 | if (host->use_dma) { |
1578 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, | 1579 | if (data->host_cookie) |
1579 | omap_hsmmc_get_dma_dir(host, data)); | 1580 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, |
1581 | data->sg_len, | ||
1582 | omap_hsmmc_get_dma_dir(host, data)); | ||
1580 | data->host_cookie = 0; | 1583 | data->host_cookie = 0; |
1581 | } | 1584 | } |
1582 | } | 1585 | } |
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c index 4b920b7621cf..b4257e700617 100644 --- a/drivers/mmc/host/sdhci-cns3xxx.c +++ b/drivers/mmc/host/sdhci-cns3xxx.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/mmc/host.h> | 17 | #include <linux/mmc/host.h> |
18 | #include <linux/module.h> | ||
18 | #include <mach/cns3xxx.h> | 19 | #include <mach/cns3xxx.h> |
19 | #include "sdhci-pltfm.h" | 20 | #include "sdhci-pltfm.h" |
20 | 21 | ||
@@ -108,13 +109,10 @@ static struct platform_driver sdhci_cns3xxx_driver = { | |||
108 | .driver = { | 109 | .driver = { |
109 | .name = "sdhci-cns3xxx", | 110 | .name = "sdhci-cns3xxx", |
110 | .owner = THIS_MODULE, | 111 | .owner = THIS_MODULE, |
112 | .pm = SDHCI_PLTFM_PMOPS, | ||
111 | }, | 113 | }, |
112 | .probe = sdhci_cns3xxx_probe, | 114 | .probe = sdhci_cns3xxx_probe, |
113 | .remove = __devexit_p(sdhci_cns3xxx_remove), | 115 | .remove = __devexit_p(sdhci_cns3xxx_remove), |
114 | #ifdef CONFIG_PM | ||
115 | .suspend = sdhci_pltfm_suspend, | ||
116 | .resume = sdhci_pltfm_resume, | ||
117 | #endif | ||
118 | }; | 116 | }; |
119 | 117 | ||
120 | static int __init sdhci_cns3xxx_init(void) | 118 | static int __init sdhci_cns3xxx_init(void) |
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index f2d29dca4420..a81312c91f70 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c | |||
@@ -82,13 +82,10 @@ static struct platform_driver sdhci_dove_driver = { | |||
82 | .driver = { | 82 | .driver = { |
83 | .name = "sdhci-dove", | 83 | .name = "sdhci-dove", |
84 | .owner = THIS_MODULE, | 84 | .owner = THIS_MODULE, |
85 | .pm = SDHCI_PLTFM_PMOPS, | ||
85 | }, | 86 | }, |
86 | .probe = sdhci_dove_probe, | 87 | .probe = sdhci_dove_probe, |
87 | .remove = __devexit_p(sdhci_dove_remove), | 88 | .remove = __devexit_p(sdhci_dove_remove), |
88 | #ifdef CONFIG_PM | ||
89 | .suspend = sdhci_pltfm_suspend, | ||
90 | .resume = sdhci_pltfm_resume, | ||
91 | #endif | ||
92 | }; | 89 | }; |
93 | 90 | ||
94 | static int __init sdhci_dove_init(void) | 91 | static int __init sdhci_dove_init(void) |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 4b976f00ea85..38ebc4ea259f 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
@@ -599,14 +599,11 @@ static struct platform_driver sdhci_esdhc_imx_driver = { | |||
599 | .name = "sdhci-esdhc-imx", | 599 | .name = "sdhci-esdhc-imx", |
600 | .owner = THIS_MODULE, | 600 | .owner = THIS_MODULE, |
601 | .of_match_table = imx_esdhc_dt_ids, | 601 | .of_match_table = imx_esdhc_dt_ids, |
602 | .pm = SDHCI_PLTFM_PMOPS, | ||
602 | }, | 603 | }, |
603 | .id_table = imx_esdhc_devtype, | 604 | .id_table = imx_esdhc_devtype, |
604 | .probe = sdhci_esdhc_imx_probe, | 605 | .probe = sdhci_esdhc_imx_probe, |
605 | .remove = __devexit_p(sdhci_esdhc_imx_remove), | 606 | .remove = __devexit_p(sdhci_esdhc_imx_remove), |
606 | #ifdef CONFIG_PM | ||
607 | .suspend = sdhci_pltfm_suspend, | ||
608 | .resume = sdhci_pltfm_resume, | ||
609 | #endif | ||
610 | }; | 607 | }; |
611 | 608 | ||
612 | static int __init sdhci_esdhc_imx_init(void) | 609 | static int __init sdhci_esdhc_imx_init(void) |
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 59e9d003e589..01e5f627e0f0 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
@@ -125,13 +125,10 @@ static struct platform_driver sdhci_esdhc_driver = { | |||
125 | .name = "sdhci-esdhc", | 125 | .name = "sdhci-esdhc", |
126 | .owner = THIS_MODULE, | 126 | .owner = THIS_MODULE, |
127 | .of_match_table = sdhci_esdhc_of_match, | 127 | .of_match_table = sdhci_esdhc_of_match, |
128 | .pm = SDHCI_PLTFM_PMOPS, | ||
128 | }, | 129 | }, |
129 | .probe = sdhci_esdhc_probe, | 130 | .probe = sdhci_esdhc_probe, |
130 | .remove = __devexit_p(sdhci_esdhc_remove), | 131 | .remove = __devexit_p(sdhci_esdhc_remove), |
131 | #ifdef CONFIG_PM | ||
132 | .suspend = sdhci_pltfm_suspend, | ||
133 | .resume = sdhci_pltfm_resume, | ||
134 | #endif | ||
135 | }; | 132 | }; |
136 | 133 | ||
137 | static int __init sdhci_esdhc_init(void) | 134 | static int __init sdhci_esdhc_init(void) |
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c index 9b0d794a4f69..3619adc7d9fc 100644 --- a/drivers/mmc/host/sdhci-of-hlwd.c +++ b/drivers/mmc/host/sdhci-of-hlwd.c | |||
@@ -87,13 +87,10 @@ static struct platform_driver sdhci_hlwd_driver = { | |||
87 | .name = "sdhci-hlwd", | 87 | .name = "sdhci-hlwd", |
88 | .owner = THIS_MODULE, | 88 | .owner = THIS_MODULE, |
89 | .of_match_table = sdhci_hlwd_of_match, | 89 | .of_match_table = sdhci_hlwd_of_match, |
90 | .pm = SDHCI_PLTFM_PMOPS, | ||
90 | }, | 91 | }, |
91 | .probe = sdhci_hlwd_probe, | 92 | .probe = sdhci_hlwd_probe, |
92 | .remove = __devexit_p(sdhci_hlwd_remove), | 93 | .remove = __devexit_p(sdhci_hlwd_remove), |
93 | #ifdef CONFIG_PM | ||
94 | .suspend = sdhci_pltfm_suspend, | ||
95 | .resume = sdhci_pltfm_resume, | ||
96 | #endif | ||
97 | }; | 94 | }; |
98 | 95 | ||
99 | static int __init sdhci_hlwd_init(void) | 96 | static int __init sdhci_hlwd_init(void) |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index d833d9c2f7e3..6878a94626bc 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -54,8 +54,7 @@ struct sdhci_pci_fixes { | |||
54 | int (*probe_slot) (struct sdhci_pci_slot *); | 54 | int (*probe_slot) (struct sdhci_pci_slot *); |
55 | void (*remove_slot) (struct sdhci_pci_slot *, int); | 55 | void (*remove_slot) (struct sdhci_pci_slot *, int); |
56 | 56 | ||
57 | int (*suspend) (struct sdhci_pci_chip *, | 57 | int (*suspend) (struct sdhci_pci_chip *); |
58 | pm_message_t); | ||
59 | int (*resume) (struct sdhci_pci_chip *); | 58 | int (*resume) (struct sdhci_pci_chip *); |
60 | }; | 59 | }; |
61 | 60 | ||
@@ -549,7 +548,7 @@ static void jmicron_remove_slot(struct sdhci_pci_slot *slot, int dead) | |||
549 | jmicron_enable_mmc(slot->host, 0); | 548 | jmicron_enable_mmc(slot->host, 0); |
550 | } | 549 | } |
551 | 550 | ||
552 | static int jmicron_suspend(struct sdhci_pci_chip *chip, pm_message_t state) | 551 | static int jmicron_suspend(struct sdhci_pci_chip *chip) |
553 | { | 552 | { |
554 | int i; | 553 | int i; |
555 | 554 | ||
@@ -993,8 +992,9 @@ static struct sdhci_ops sdhci_pci_ops = { | |||
993 | 992 | ||
994 | #ifdef CONFIG_PM | 993 | #ifdef CONFIG_PM |
995 | 994 | ||
996 | static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 995 | static int sdhci_pci_suspend(struct device *dev) |
997 | { | 996 | { |
997 | struct pci_dev *pdev = to_pci_dev(dev); | ||
998 | struct sdhci_pci_chip *chip; | 998 | struct sdhci_pci_chip *chip; |
999 | struct sdhci_pci_slot *slot; | 999 | struct sdhci_pci_slot *slot; |
1000 | mmc_pm_flag_t slot_pm_flags; | 1000 | mmc_pm_flag_t slot_pm_flags; |
@@ -1010,7 +1010,7 @@ static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1010 | if (!slot) | 1010 | if (!slot) |
1011 | continue; | 1011 | continue; |
1012 | 1012 | ||
1013 | ret = sdhci_suspend_host(slot->host, state); | 1013 | ret = sdhci_suspend_host(slot->host); |
1014 | 1014 | ||
1015 | if (ret) { | 1015 | if (ret) { |
1016 | for (i--; i >= 0; i--) | 1016 | for (i--; i >= 0; i--) |
@@ -1026,7 +1026,7 @@ static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | if (chip->fixes && chip->fixes->suspend) { | 1028 | if (chip->fixes && chip->fixes->suspend) { |
1029 | ret = chip->fixes->suspend(chip, state); | 1029 | ret = chip->fixes->suspend(chip); |
1030 | if (ret) { | 1030 | if (ret) { |
1031 | for (i = chip->num_slots - 1; i >= 0; i--) | 1031 | for (i = chip->num_slots - 1; i >= 0; i--) |
1032 | sdhci_resume_host(chip->slots[i]->host); | 1032 | sdhci_resume_host(chip->slots[i]->host); |
@@ -1042,16 +1042,17 @@ static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1042 | } | 1042 | } |
1043 | pci_set_power_state(pdev, PCI_D3hot); | 1043 | pci_set_power_state(pdev, PCI_D3hot); |
1044 | } else { | 1044 | } else { |
1045 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | 1045 | pci_enable_wake(pdev, PCI_D3hot, 0); |
1046 | pci_disable_device(pdev); | 1046 | pci_disable_device(pdev); |
1047 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 1047 | pci_set_power_state(pdev, PCI_D3hot); |
1048 | } | 1048 | } |
1049 | 1049 | ||
1050 | return 0; | 1050 | return 0; |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | static int sdhci_pci_resume(struct pci_dev *pdev) | 1053 | static int sdhci_pci_resume(struct device *dev) |
1054 | { | 1054 | { |
1055 | struct pci_dev *pdev = to_pci_dev(dev); | ||
1055 | struct sdhci_pci_chip *chip; | 1056 | struct sdhci_pci_chip *chip; |
1056 | struct sdhci_pci_slot *slot; | 1057 | struct sdhci_pci_slot *slot; |
1057 | int i, ret; | 1058 | int i, ret; |
@@ -1099,7 +1100,6 @@ static int sdhci_pci_runtime_suspend(struct device *dev) | |||
1099 | struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); | 1100 | struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); |
1100 | struct sdhci_pci_chip *chip; | 1101 | struct sdhci_pci_chip *chip; |
1101 | struct sdhci_pci_slot *slot; | 1102 | struct sdhci_pci_slot *slot; |
1102 | pm_message_t state = { .event = PM_EVENT_SUSPEND }; | ||
1103 | int i, ret; | 1103 | int i, ret; |
1104 | 1104 | ||
1105 | chip = pci_get_drvdata(pdev); | 1105 | chip = pci_get_drvdata(pdev); |
@@ -1121,7 +1121,7 @@ static int sdhci_pci_runtime_suspend(struct device *dev) | |||
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | if (chip->fixes && chip->fixes->suspend) { | 1123 | if (chip->fixes && chip->fixes->suspend) { |
1124 | ret = chip->fixes->suspend(chip, state); | 1124 | ret = chip->fixes->suspend(chip); |
1125 | if (ret) { | 1125 | if (ret) { |
1126 | for (i = chip->num_slots - 1; i >= 0; i--) | 1126 | for (i = chip->num_slots - 1; i >= 0; i--) |
1127 | sdhci_runtime_resume_host(chip->slots[i]->host); | 1127 | sdhci_runtime_resume_host(chip->slots[i]->host); |
@@ -1176,6 +1176,8 @@ static int sdhci_pci_runtime_idle(struct device *dev) | |||
1176 | #endif | 1176 | #endif |
1177 | 1177 | ||
1178 | static const struct dev_pm_ops sdhci_pci_pm_ops = { | 1178 | static const struct dev_pm_ops sdhci_pci_pm_ops = { |
1179 | .suspend = sdhci_pci_suspend, | ||
1180 | .resume = sdhci_pci_resume, | ||
1179 | .runtime_suspend = sdhci_pci_runtime_suspend, | 1181 | .runtime_suspend = sdhci_pci_runtime_suspend, |
1180 | .runtime_resume = sdhci_pci_runtime_resume, | 1182 | .runtime_resume = sdhci_pci_runtime_resume, |
1181 | .runtime_idle = sdhci_pci_runtime_idle, | 1183 | .runtime_idle = sdhci_pci_runtime_idle, |
@@ -1428,8 +1430,6 @@ static struct pci_driver sdhci_driver = { | |||
1428 | .id_table = pci_ids, | 1430 | .id_table = pci_ids, |
1429 | .probe = sdhci_pci_probe, | 1431 | .probe = sdhci_pci_probe, |
1430 | .remove = __devexit_p(sdhci_pci_remove), | 1432 | .remove = __devexit_p(sdhci_pci_remove), |
1431 | .suspend = sdhci_pci_suspend, | ||
1432 | .resume = sdhci_pci_resume, | ||
1433 | .driver = { | 1433 | .driver = { |
1434 | .pm = &sdhci_pci_pm_ops | 1434 | .pm = &sdhci_pci_pm_ops |
1435 | }, | 1435 | }, |
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index a9e12ea05583..03970bcb3495 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c | |||
@@ -194,21 +194,25 @@ int sdhci_pltfm_unregister(struct platform_device *pdev) | |||
194 | EXPORT_SYMBOL_GPL(sdhci_pltfm_unregister); | 194 | EXPORT_SYMBOL_GPL(sdhci_pltfm_unregister); |
195 | 195 | ||
196 | #ifdef CONFIG_PM | 196 | #ifdef CONFIG_PM |
197 | int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state) | 197 | static int sdhci_pltfm_suspend(struct device *dev) |
198 | { | 198 | { |
199 | struct sdhci_host *host = platform_get_drvdata(dev); | 199 | struct sdhci_host *host = dev_get_drvdata(dev); |
200 | 200 | ||
201 | return sdhci_suspend_host(host, state); | 201 | return sdhci_suspend_host(host); |
202 | } | 202 | } |
203 | EXPORT_SYMBOL_GPL(sdhci_pltfm_suspend); | ||
204 | 203 | ||
205 | int sdhci_pltfm_resume(struct platform_device *dev) | 204 | static int sdhci_pltfm_resume(struct device *dev) |
206 | { | 205 | { |
207 | struct sdhci_host *host = platform_get_drvdata(dev); | 206 | struct sdhci_host *host = dev_get_drvdata(dev); |
208 | 207 | ||
209 | return sdhci_resume_host(host); | 208 | return sdhci_resume_host(host); |
210 | } | 209 | } |
211 | EXPORT_SYMBOL_GPL(sdhci_pltfm_resume); | 210 | |
211 | const struct dev_pm_ops sdhci_pltfm_pmops = { | ||
212 | .suspend = sdhci_pltfm_suspend, | ||
213 | .resume = sdhci_pltfm_resume, | ||
214 | }; | ||
215 | EXPORT_SYMBOL_GPL(sdhci_pltfm_pmops); | ||
212 | #endif /* CONFIG_PM */ | 216 | #endif /* CONFIG_PM */ |
213 | 217 | ||
214 | static int __init sdhci_pltfm_drv_init(void) | 218 | static int __init sdhci_pltfm_drv_init(void) |
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h index 3a9fc3f40840..37e0e184a0bb 100644 --- a/drivers/mmc/host/sdhci-pltfm.h +++ b/drivers/mmc/host/sdhci-pltfm.h | |||
@@ -99,8 +99,10 @@ extern int sdhci_pltfm_register(struct platform_device *pdev, | |||
99 | extern int sdhci_pltfm_unregister(struct platform_device *pdev); | 99 | extern int sdhci_pltfm_unregister(struct platform_device *pdev); |
100 | 100 | ||
101 | #ifdef CONFIG_PM | 101 | #ifdef CONFIG_PM |
102 | extern int sdhci_pltfm_suspend(struct platform_device *dev, pm_message_t state); | 102 | extern const struct dev_pm_ops sdhci_pltfm_pmops; |
103 | extern int sdhci_pltfm_resume(struct platform_device *dev); | 103 | #define SDHCI_PLTFM_PMOPS (&sdhci_pltfm_pmops) |
104 | #else | ||
105 | #define SDHCI_PLTFM_PMOPS NULL | ||
104 | #endif | 106 | #endif |
105 | 107 | ||
106 | #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */ | 108 | #endif /* _DRIVERS_MMC_SDHCI_PLTFM_H */ |
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index d4bf6d30c7ba..7a039c3cb1f1 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c | |||
@@ -218,13 +218,10 @@ static struct platform_driver sdhci_pxav2_driver = { | |||
218 | .driver = { | 218 | .driver = { |
219 | .name = "sdhci-pxav2", | 219 | .name = "sdhci-pxav2", |
220 | .owner = THIS_MODULE, | 220 | .owner = THIS_MODULE, |
221 | .pm = SDHCI_PLTFM_PMOPS, | ||
221 | }, | 222 | }, |
222 | .probe = sdhci_pxav2_probe, | 223 | .probe = sdhci_pxav2_probe, |
223 | .remove = __devexit_p(sdhci_pxav2_remove), | 224 | .remove = __devexit_p(sdhci_pxav2_remove), |
224 | #ifdef CONFIG_PM | ||
225 | .suspend = sdhci_pltfm_suspend, | ||
226 | .resume = sdhci_pltfm_resume, | ||
227 | #endif | ||
228 | }; | 225 | }; |
229 | static int __init sdhci_pxav2_init(void) | 226 | static int __init sdhci_pxav2_init(void) |
230 | { | 227 | { |
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index cff4ad3e7a59..15673a7ee6a5 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
@@ -264,13 +264,10 @@ static struct platform_driver sdhci_pxav3_driver = { | |||
264 | .driver = { | 264 | .driver = { |
265 | .name = "sdhci-pxav3", | 265 | .name = "sdhci-pxav3", |
266 | .owner = THIS_MODULE, | 266 | .owner = THIS_MODULE, |
267 | .pm = SDHCI_PLTFM_PMOPS, | ||
267 | }, | 268 | }, |
268 | .probe = sdhci_pxav3_probe, | 269 | .probe = sdhci_pxav3_probe, |
269 | .remove = __devexit_p(sdhci_pxav3_remove), | 270 | .remove = __devexit_p(sdhci_pxav3_remove), |
270 | #ifdef CONFIG_PM | ||
271 | .suspend = sdhci_pltfm_suspend, | ||
272 | .resume = sdhci_pltfm_resume, | ||
273 | #endif | ||
274 | }; | 271 | }; |
275 | static int __init sdhci_pxav3_init(void) | 272 | static int __init sdhci_pxav3_init(void) |
276 | { | 273 | { |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 3d00e722efc9..0d33ff0d67fb 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -622,33 +622,38 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) | |||
622 | 622 | ||
623 | #ifdef CONFIG_PM | 623 | #ifdef CONFIG_PM |
624 | 624 | ||
625 | static int sdhci_s3c_suspend(struct platform_device *dev, pm_message_t pm) | 625 | static int sdhci_s3c_suspend(struct device *dev) |
626 | { | 626 | { |
627 | struct sdhci_host *host = platform_get_drvdata(dev); | 627 | struct sdhci_host *host = dev_get_drvdata(dev); |
628 | 628 | ||
629 | return sdhci_suspend_host(host, pm); | 629 | return sdhci_suspend_host(host); |
630 | } | 630 | } |
631 | 631 | ||
632 | static int sdhci_s3c_resume(struct platform_device *dev) | 632 | static int sdhci_s3c_resume(struct device *dev) |
633 | { | 633 | { |
634 | struct sdhci_host *host = platform_get_drvdata(dev); | 634 | struct sdhci_host *host = dev_get_drvdata(dev); |
635 | 635 | ||
636 | return sdhci_resume_host(host); | 636 | return sdhci_resume_host(host); |
637 | } | 637 | } |
638 | 638 | ||
639 | static const struct dev_pm_ops sdhci_s3c_pmops = { | ||
640 | .suspend = sdhci_s3c_suspend, | ||
641 | .resume = sdhci_s3c_resume, | ||
642 | }; | ||
643 | |||
644 | #define SDHCI_S3C_PMOPS (&sdhci_s3c_pmops) | ||
645 | |||
639 | #else | 646 | #else |
640 | #define sdhci_s3c_suspend NULL | 647 | #define SDHCI_S3C_PMOPS NULL |
641 | #define sdhci_s3c_resume NULL | ||
642 | #endif | 648 | #endif |
643 | 649 | ||
644 | static struct platform_driver sdhci_s3c_driver = { | 650 | static struct platform_driver sdhci_s3c_driver = { |
645 | .probe = sdhci_s3c_probe, | 651 | .probe = sdhci_s3c_probe, |
646 | .remove = __devexit_p(sdhci_s3c_remove), | 652 | .remove = __devexit_p(sdhci_s3c_remove), |
647 | .suspend = sdhci_s3c_suspend, | ||
648 | .resume = sdhci_s3c_resume, | ||
649 | .driver = { | 653 | .driver = { |
650 | .owner = THIS_MODULE, | 654 | .owner = THIS_MODULE, |
651 | .name = "s3c-sdhci", | 655 | .name = "s3c-sdhci", |
656 | .pm = SDHCI_S3C_PMOPS, | ||
652 | }, | 657 | }, |
653 | }; | 658 | }; |
654 | 659 | ||
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 89699e861fc1..e2e18d3f949c 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
@@ -318,13 +318,10 @@ static struct platform_driver sdhci_tegra_driver = { | |||
318 | .name = "sdhci-tegra", | 318 | .name = "sdhci-tegra", |
319 | .owner = THIS_MODULE, | 319 | .owner = THIS_MODULE, |
320 | .of_match_table = sdhci_tegra_dt_match, | 320 | .of_match_table = sdhci_tegra_dt_match, |
321 | .pm = SDHCI_PLTFM_PMOPS, | ||
321 | }, | 322 | }, |
322 | .probe = sdhci_tegra_probe, | 323 | .probe = sdhci_tegra_probe, |
323 | .remove = __devexit_p(sdhci_tegra_remove), | 324 | .remove = __devexit_p(sdhci_tegra_remove), |
324 | #ifdef CONFIG_PM | ||
325 | .suspend = sdhci_pltfm_suspend, | ||
326 | .resume = sdhci_pltfm_resume, | ||
327 | #endif | ||
328 | }; | 325 | }; |
329 | 326 | ||
330 | static int __init sdhci_tegra_init(void) | 327 | static int __init sdhci_tegra_init(void) |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 6d8eea323541..19ed580f2cab 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -2327,7 +2327,7 @@ out: | |||
2327 | 2327 | ||
2328 | #ifdef CONFIG_PM | 2328 | #ifdef CONFIG_PM |
2329 | 2329 | ||
2330 | int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state) | 2330 | int sdhci_suspend_host(struct sdhci_host *host) |
2331 | { | 2331 | { |
2332 | int ret; | 2332 | int ret; |
2333 | 2333 | ||
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 0a5b65460d8a..a04d4d0c6fd2 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -374,7 +374,7 @@ extern int sdhci_add_host(struct sdhci_host *host); | |||
374 | extern void sdhci_remove_host(struct sdhci_host *host, int dead); | 374 | extern void sdhci_remove_host(struct sdhci_host *host, int dead); |
375 | 375 | ||
376 | #ifdef CONFIG_PM | 376 | #ifdef CONFIG_PM |
377 | extern int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state); | 377 | extern int sdhci_suspend_host(struct sdhci_host *host); |
378 | extern int sdhci_resume_host(struct sdhci_host *host); | 378 | extern int sdhci_resume_host(struct sdhci_host *host); |
379 | extern void sdhci_enable_irq_wakeups(struct sdhci_host *host); | 379 | extern void sdhci_enable_irq_wakeups(struct sdhci_host *host); |
380 | #endif | 380 | #endif |
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 369366c8e205..d5505f3fe2a1 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c | |||
@@ -908,7 +908,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
908 | if (host->power) { | 908 | if (host->power) { |
909 | pm_runtime_put(&host->pd->dev); | 909 | pm_runtime_put(&host->pd->dev); |
910 | host->power = false; | 910 | host->power = false; |
911 | if (p->down_pwr) | 911 | if (p->down_pwr && ios->power_mode == MMC_POWER_OFF) |
912 | p->down_pwr(host->pd); | 912 | p->down_pwr(host->pd); |
913 | } | 913 | } |
914 | host->state = STATE_IDLE; | 914 | host->state = STATE_IDLE; |
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index d85a60cda167..4208b3958069 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c | |||
@@ -798,7 +798,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
798 | /* start bus clock */ | 798 | /* start bus clock */ |
799 | tmio_mmc_clk_start(host); | 799 | tmio_mmc_clk_start(host); |
800 | } else if (ios->power_mode != MMC_POWER_UP) { | 800 | } else if (ios->power_mode != MMC_POWER_UP) { |
801 | if (host->set_pwr) | 801 | if (host->set_pwr && ios->power_mode == MMC_POWER_OFF) |
802 | host->set_pwr(host->pdev, 0); | 802 | host->set_pwr(host->pdev, 0); |
803 | if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && | 803 | if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && |
804 | pdata->power) { | 804 | pdata->power) { |
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index e8f6e65183d7..2ec978bc32ba 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c | |||
@@ -259,7 +259,7 @@ static int firmware_rom_wait_states = 0x04; | |||
259 | static int firmware_rom_wait_states = 0x1C; | 259 | static int firmware_rom_wait_states = 0x1C; |
260 | #endif | 260 | #endif |
261 | 261 | ||
262 | module_param(firmware_rom_wait_states, bool, 0644); | 262 | module_param(firmware_rom_wait_states, int, 0644); |
263 | MODULE_PARM_DESC(firmware_rom_wait_states, | 263 | MODULE_PARM_DESC(firmware_rom_wait_states, |
264 | "ROM wait states byte=RRRIIEEE (Reserved Internal External)"); | 264 | "ROM wait states byte=RRRIIEEE (Reserved Internal External)"); |
265 | 265 | ||
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index 94f553489725..45876d0e5b8e 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c | |||
@@ -227,10 +227,14 @@ static int platram_probe(struct platform_device *pdev) | |||
227 | if (!err) | 227 | if (!err) |
228 | dev_info(&pdev->dev, "registered mtd device\n"); | 228 | dev_info(&pdev->dev, "registered mtd device\n"); |
229 | 229 | ||
230 | /* add the whole device. */ | 230 | if (pdata->nr_partitions) { |
231 | err = mtd_device_register(info->mtd, NULL, 0); | 231 | /* add the whole device. */ |
232 | if (err) | 232 | err = mtd_device_register(info->mtd, NULL, 0); |
233 | dev_err(&pdev->dev, "failed to register the entire device\n"); | 233 | if (err) { |
234 | dev_err(&pdev->dev, | ||
235 | "failed to register the entire device\n"); | ||
236 | } | ||
237 | } | ||
234 | 238 | ||
235 | return err; | 239 | return err; |
236 | 240 | ||
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 411a17df9fc1..2a25b6789af4 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c | |||
@@ -98,7 +98,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) | |||
98 | } | 98 | } |
99 | info->mtd->owner = THIS_MODULE; | 99 | info->mtd->owner = THIS_MODULE; |
100 | 100 | ||
101 | mtd_device_parse_register(info->mtd, probes, 0, NULL, 0); | 101 | mtd_device_parse_register(info->mtd, probes, 0, flash->parts, flash->nr_parts); |
102 | 102 | ||
103 | platform_set_drvdata(pdev, info); | 103 | platform_set_drvdata(pdev, info); |
104 | return 0; | 104 | return 0; |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 071b63420f0e..493ec2fcf97f 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c | |||
@@ -21,9 +21,9 @@ | |||
21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/module.h> | ||
24 | #include <linux/mtd/gpmi-nand.h> | 25 | #include <linux/mtd/gpmi-nand.h> |
25 | #include <linux/mtd/partitions.h> | 26 | #include <linux/mtd/partitions.h> |
26 | |||
27 | #include "gpmi-nand.h" | 27 | #include "gpmi-nand.h" |
28 | 28 | ||
29 | /* add our owner bbt descriptor */ | 29 | /* add our owner bbt descriptor */ |
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index ee1713907b92..f8aacf48ecdd 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c | |||
@@ -188,7 +188,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, | |||
188 | if (!flash_np) | 188 | if (!flash_np) |
189 | return -ENODEV; | 189 | return -ENODEV; |
190 | 190 | ||
191 | ppdata->of_node = flash_np; | 191 | ppdata.of_node = flash_np; |
192 | ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s", | 192 | ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s", |
193 | dev_name(&ndfc->ofdev->dev), flash_np->name); | 193 | dev_name(&ndfc->ofdev->dev), flash_np->name); |
194 | if (!ndfc->mtd.name) { | 194 | if (!ndfc->mtd.name) { |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 36b2a4b1c35f..7a0c800b50ad 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -474,7 +474,6 @@ enum rtl_register_content { | |||
474 | /* Config1 register p.24 */ | 474 | /* Config1 register p.24 */ |
475 | LEDS1 = (1 << 7), | 475 | LEDS1 = (1 << 7), |
476 | LEDS0 = (1 << 6), | 476 | LEDS0 = (1 << 6), |
477 | MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */ | ||
478 | Speed_down = (1 << 4), | 477 | Speed_down = (1 << 4), |
479 | MEMMAP = (1 << 3), | 478 | MEMMAP = (1 << 3), |
480 | IOMAP = (1 << 2), | 479 | IOMAP = (1 << 2), |
@@ -482,6 +481,7 @@ enum rtl_register_content { | |||
482 | PMEnable = (1 << 0), /* Power Management Enable */ | 481 | PMEnable = (1 << 0), /* Power Management Enable */ |
483 | 482 | ||
484 | /* Config2 register p. 25 */ | 483 | /* Config2 register p. 25 */ |
484 | MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ | ||
485 | PCI_Clock_66MHz = 0x01, | 485 | PCI_Clock_66MHz = 0x01, |
486 | PCI_Clock_33MHz = 0x00, | 486 | PCI_Clock_33MHz = 0x00, |
487 | 487 | ||
@@ -3426,22 +3426,24 @@ static const struct rtl_cfg_info { | |||
3426 | }; | 3426 | }; |
3427 | 3427 | ||
3428 | /* Cfg9346_Unlock assumed. */ | 3428 | /* Cfg9346_Unlock assumed. */ |
3429 | static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr, | 3429 | static unsigned rtl_try_msi(struct rtl8169_private *tp, |
3430 | const struct rtl_cfg_info *cfg) | 3430 | const struct rtl_cfg_info *cfg) |
3431 | { | 3431 | { |
3432 | void __iomem *ioaddr = tp->mmio_addr; | ||
3432 | unsigned msi = 0; | 3433 | unsigned msi = 0; |
3433 | u8 cfg2; | 3434 | u8 cfg2; |
3434 | 3435 | ||
3435 | cfg2 = RTL_R8(Config2) & ~MSIEnable; | 3436 | cfg2 = RTL_R8(Config2) & ~MSIEnable; |
3436 | if (cfg->features & RTL_FEATURE_MSI) { | 3437 | if (cfg->features & RTL_FEATURE_MSI) { |
3437 | if (pci_enable_msi(pdev)) { | 3438 | if (pci_enable_msi(tp->pci_dev)) { |
3438 | dev_info(&pdev->dev, "no MSI. Back to INTx.\n"); | 3439 | netif_info(tp, hw, tp->dev, "no MSI. Back to INTx.\n"); |
3439 | } else { | 3440 | } else { |
3440 | cfg2 |= MSIEnable; | 3441 | cfg2 |= MSIEnable; |
3441 | msi = RTL_FEATURE_MSI; | 3442 | msi = RTL_FEATURE_MSI; |
3442 | } | 3443 | } |
3443 | } | 3444 | } |
3444 | RTL_W8(Config2, cfg2); | 3445 | if (tp->mac_version <= RTL_GIGA_MAC_VER_06) |
3446 | RTL_W8(Config2, cfg2); | ||
3445 | return msi; | 3447 | return msi; |
3446 | } | 3448 | } |
3447 | 3449 | ||
@@ -4077,7 +4079,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4077 | tp->features |= RTL_FEATURE_WOL; | 4079 | tp->features |= RTL_FEATURE_WOL; |
4078 | if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) | 4080 | if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) |
4079 | tp->features |= RTL_FEATURE_WOL; | 4081 | tp->features |= RTL_FEATURE_WOL; |
4080 | tp->features |= rtl_try_msi(pdev, ioaddr, cfg); | 4082 | tp->features |= rtl_try_msi(tp, cfg); |
4081 | RTL_W8(Cfg9346, Cfg9346_Lock); | 4083 | RTL_W8(Cfg9346, Cfg9346_Lock); |
4082 | 4084 | ||
4083 | if (rtl_tbi_enabled(tp)) { | 4085 | if (rtl_tbi_enabled(tp)) { |
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c index dca9d3369cdd..c97d2f590855 100644 --- a/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/drivers/net/ethernet/ti/davinci_cpdma.c | |||
@@ -836,11 +836,13 @@ int cpdma_chan_stop(struct cpdma_chan *chan) | |||
836 | chan_write(chan, cp, CPDMA_TEARDOWN_VALUE); | 836 | chan_write(chan, cp, CPDMA_TEARDOWN_VALUE); |
837 | 837 | ||
838 | /* handle completed packets */ | 838 | /* handle completed packets */ |
839 | spin_unlock_irqrestore(&chan->lock, flags); | ||
839 | do { | 840 | do { |
840 | ret = __cpdma_chan_process(chan); | 841 | ret = __cpdma_chan_process(chan); |
841 | if (ret < 0) | 842 | if (ret < 0) |
842 | break; | 843 | break; |
843 | } while ((ret & CPDMA_DESC_TD_COMPLETE) == 0); | 844 | } while ((ret & CPDMA_DESC_TD_COMPLETE) == 0); |
845 | spin_lock_irqsave(&chan->lock, flags); | ||
844 | 846 | ||
845 | /* remaining packets haven't been tx/rx'ed, clean them up */ | 847 | /* remaining packets haven't been tx/rx'ed, clean them up */ |
846 | while (chan->head) { | 848 | while (chan->head) { |
diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c index 63774372edfa..6b75063988ec 100644 --- a/drivers/net/ethernet/tile/tilepro.c +++ b/drivers/net/ethernet/tile/tilepro.c | |||
@@ -926,7 +926,7 @@ static int tile_net_poll(struct napi_struct *napi, int budget) | |||
926 | goto done; | 926 | goto done; |
927 | 927 | ||
928 | /* Re-enable the ingress interrupt. */ | 928 | /* Re-enable the ingress interrupt. */ |
929 | enable_percpu_irq(priv->intr_id); | 929 | enable_percpu_irq(priv->intr_id, 0); |
930 | 930 | ||
931 | /* HACK: Avoid the "rotting packet" problem (see above). */ | 931 | /* HACK: Avoid the "rotting packet" problem (see above). */ |
932 | if (qup->__packet_receive_read != | 932 | if (qup->__packet_receive_read != |
@@ -1296,7 +1296,7 @@ static void tile_net_open_enable(void *dev_ptr) | |||
1296 | info->napi_enabled = true; | 1296 | info->napi_enabled = true; |
1297 | 1297 | ||
1298 | /* Enable the ingress interrupt. */ | 1298 | /* Enable the ingress interrupt. */ |
1299 | enable_percpu_irq(priv->intr_id); | 1299 | enable_percpu_irq(priv->intr_id, 0); |
1300 | } | 1300 | } |
1301 | 1301 | ||
1302 | 1302 | ||
@@ -1697,7 +1697,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags, | |||
1697 | for (i = 0; i < sh->nr_frags; i++) { | 1697 | for (i = 0; i < sh->nr_frags; i++) { |
1698 | 1698 | ||
1699 | skb_frag_t *f = &sh->frags[i]; | 1699 | skb_frag_t *f = &sh->frags[i]; |
1700 | unsigned long pfn = page_to_pfn(f->page); | 1700 | unsigned long pfn = page_to_pfn(skb_frag_page(f)); |
1701 | 1701 | ||
1702 | /* FIXME: Compute "hash_for_home" properly. */ | 1702 | /* FIXME: Compute "hash_for_home" properly. */ |
1703 | /* ISSUE: The hypervisor checks CHIP_HAS_REV1_DMA_PACKETS(). */ | 1703 | /* ISSUE: The hypervisor checks CHIP_HAS_REV1_DMA_PACKETS(). */ |
@@ -1706,7 +1706,7 @@ static unsigned int tile_net_tx_frags(lepp_frag_t *frags, | |||
1706 | /* FIXME: Hmmm. */ | 1706 | /* FIXME: Hmmm. */ |
1707 | if (!hash_default) { | 1707 | if (!hash_default) { |
1708 | void *va = pfn_to_kaddr(pfn) + f->page_offset; | 1708 | void *va = pfn_to_kaddr(pfn) + f->page_offset; |
1709 | BUG_ON(PageHighMem(f->page)); | 1709 | BUG_ON(PageHighMem(skb_frag_page(f))); |
1710 | finv_buffer_remote(va, f->size, 0); | 1710 | finv_buffer_remote(va, f->size, 0); |
1711 | } | 1711 | } |
1712 | 1712 | ||
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 6c543b19fdb1..dbdca225b846 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
@@ -1659,6 +1659,10 @@ static const struct usb_device_id products [] = { | |||
1659 | // ASIX 88772a | 1659 | // ASIX 88772a |
1660 | USB_DEVICE(0x0db0, 0xa877), | 1660 | USB_DEVICE(0x0db0, 0xa877), |
1661 | .driver_info = (unsigned long) &ax88772_info, | 1661 | .driver_info = (unsigned long) &ax88772_info, |
1662 | }, { | ||
1663 | // Asus USB Ethernet Adapter | ||
1664 | USB_DEVICE (0x0b95, 0x7e2b), | ||
1665 | .driver_info = (unsigned long) &ax88772_info, | ||
1662 | }, | 1666 | }, |
1663 | { }, // END | 1667 | { }, // END |
1664 | }; | 1668 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 66e1b9fa0b8b..3cf62c363bc0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | |||
@@ -1205,9 +1205,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1205 | iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); | 1205 | iwl_print_hex_dump(trans, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); |
1206 | 1206 | ||
1207 | /* Set up entry for this TFD in Tx byte-count array */ | 1207 | /* Set up entry for this TFD in Tx byte-count array */ |
1208 | if (is_agg) | 1208 | iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); |
1209 | iwl_trans_txq_update_byte_cnt_tbl(trans, txq, | ||
1210 | le16_to_cpu(tx_cmd->len)); | ||
1211 | 1209 | ||
1212 | dma_sync_single_for_device(bus(trans)->dev, txcmd_phys, firstlen, | 1210 | dma_sync_single_for_device(bus(trans)->dev, txcmd_phys, firstlen, |
1213 | DMA_BIDIRECTIONAL); | 1211 | DMA_BIDIRECTIONAL); |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 19c0115092dd..0f0cfa3bca30 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
@@ -26,11 +26,6 @@ | |||
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | 28 | ||
29 | /* For archs that don't support NO_IRQ (such as x86), provide a dummy value */ | ||
30 | #ifndef NO_IRQ | ||
31 | #define NO_IRQ 0 | ||
32 | #endif | ||
33 | |||
34 | /** | 29 | /** |
35 | * irq_of_parse_and_map - Parse and map an interrupt into linux virq space | 30 | * irq_of_parse_and_map - Parse and map an interrupt into linux virq space |
36 | * @device: Device node of the device whose interrupt is to be mapped | 31 | * @device: Device node of the device whose interrupt is to be mapped |
@@ -44,7 +39,7 @@ unsigned int irq_of_parse_and_map(struct device_node *dev, int index) | |||
44 | struct of_irq oirq; | 39 | struct of_irq oirq; |
45 | 40 | ||
46 | if (of_irq_map_one(dev, index, &oirq)) | 41 | if (of_irq_map_one(dev, index, &oirq)) |
47 | return NO_IRQ; | 42 | return 0; |
48 | 43 | ||
49 | return irq_create_of_mapping(oirq.controller, oirq.specifier, | 44 | return irq_create_of_mapping(oirq.controller, oirq.specifier, |
50 | oirq.size); | 45 | oirq.size); |
@@ -345,7 +340,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) | |||
345 | 340 | ||
346 | /* Only dereference the resource if both the | 341 | /* Only dereference the resource if both the |
347 | * resource and the irq are valid. */ | 342 | * resource and the irq are valid. */ |
348 | if (r && irq != NO_IRQ) { | 343 | if (r && irq) { |
349 | r->start = r->end = irq; | 344 | r->start = r->end = irq; |
350 | r->flags = IORESOURCE_IRQ; | 345 | r->flags = IORESOURCE_IRQ; |
351 | r->name = dev->full_name; | 346 | r->name = dev->full_name; |
@@ -363,7 +358,7 @@ int of_irq_count(struct device_node *dev) | |||
363 | { | 358 | { |
364 | int nr = 0; | 359 | int nr = 0; |
365 | 360 | ||
366 | while (of_irq_to_resource(dev, nr, NULL) != NO_IRQ) | 361 | while (of_irq_to_resource(dev, nr, NULL)) |
367 | nr++; | 362 | nr++; |
368 | 363 | ||
369 | return nr; | 364 | return nr; |
@@ -383,7 +378,7 @@ int of_irq_to_resource_table(struct device_node *dev, struct resource *res, | |||
383 | int i; | 378 | int i; |
384 | 379 | ||
385 | for (i = 0; i < nr_irqs; i++, res++) | 380 | for (i = 0; i < nr_irqs; i++, res++) |
386 | if (of_irq_to_resource(dev, i, res) == NO_IRQ) | 381 | if (!of_irq_to_resource(dev, i, res)) |
387 | break; | 382 | break; |
388 | 383 | ||
389 | return i; | 384 | return i; |
diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c index 89f63456646f..84a208dbed93 100644 --- a/drivers/oprofile/oprofile_files.c +++ b/drivers/oprofile/oprofile_files.c | |||
@@ -45,7 +45,7 @@ static ssize_t timeout_write(struct file *file, char const __user *buf, | |||
45 | return -EINVAL; | 45 | return -EINVAL; |
46 | 46 | ||
47 | retval = oprofilefs_ulong_from_user(&val, buf, count); | 47 | retval = oprofilefs_ulong_from_user(&val, buf, count); |
48 | if (retval) | 48 | if (retval <= 0) |
49 | return retval; | 49 | return retval; |
50 | 50 | ||
51 | retval = oprofile_set_timeout(val); | 51 | retval = oprofile_set_timeout(val); |
@@ -84,7 +84,7 @@ static ssize_t depth_write(struct file *file, char const __user *buf, size_t cou | |||
84 | return -EINVAL; | 84 | return -EINVAL; |
85 | 85 | ||
86 | retval = oprofilefs_ulong_from_user(&val, buf, count); | 86 | retval = oprofilefs_ulong_from_user(&val, buf, count); |
87 | if (retval) | 87 | if (retval <= 0) |
88 | return retval; | 88 | return retval; |
89 | 89 | ||
90 | retval = oprofile_set_ulong(&oprofile_backtrace_depth, val); | 90 | retval = oprofile_set_ulong(&oprofile_backtrace_depth, val); |
@@ -141,9 +141,10 @@ static ssize_t enable_write(struct file *file, char const __user *buf, size_t co | |||
141 | return -EINVAL; | 141 | return -EINVAL; |
142 | 142 | ||
143 | retval = oprofilefs_ulong_from_user(&val, buf, count); | 143 | retval = oprofilefs_ulong_from_user(&val, buf, count); |
144 | if (retval) | 144 | if (retval <= 0) |
145 | return retval; | 145 | return retval; |
146 | 146 | ||
147 | retval = 0; | ||
147 | if (val) | 148 | if (val) |
148 | retval = oprofile_start(); | 149 | retval = oprofile_start(); |
149 | else | 150 | else |
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c index d0de6cc2d7a5..2f0aa0f700e6 100644 --- a/drivers/oprofile/oprofilefs.c +++ b/drivers/oprofile/oprofilefs.c | |||
@@ -60,6 +60,13 @@ ssize_t oprofilefs_ulong_to_user(unsigned long val, char __user *buf, size_t cou | |||
60 | } | 60 | } |
61 | 61 | ||
62 | 62 | ||
63 | /* | ||
64 | * Note: If oprofilefs_ulong_from_user() returns 0, then *val remains | ||
65 | * unchanged and might be uninitialized. This follows write syscall | ||
66 | * implementation when count is zero: "If count is zero ... [and if] | ||
67 | * no errors are detected, 0 will be returned without causing any | ||
68 | * other effect." (man 2 write) | ||
69 | */ | ||
63 | int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count) | 70 | int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count) |
64 | { | 71 | { |
65 | char tmpbuf[TMPBUFSIZE]; | 72 | char tmpbuf[TMPBUFSIZE]; |
@@ -79,7 +86,7 @@ int oprofilefs_ulong_from_user(unsigned long *val, char const __user *buf, size_ | |||
79 | raw_spin_lock_irqsave(&oprofilefs_lock, flags); | 86 | raw_spin_lock_irqsave(&oprofilefs_lock, flags); |
80 | *val = simple_strtoul(tmpbuf, NULL, 0); | 87 | *val = simple_strtoul(tmpbuf, NULL, 0); |
81 | raw_spin_unlock_irqrestore(&oprofilefs_lock, flags); | 88 | raw_spin_unlock_irqrestore(&oprofilefs_lock, flags); |
82 | return 0; | 89 | return count; |
83 | } | 90 | } |
84 | 91 | ||
85 | 92 | ||
@@ -99,7 +106,7 @@ static ssize_t ulong_write_file(struct file *file, char const __user *buf, size_ | |||
99 | return -EINVAL; | 106 | return -EINVAL; |
100 | 107 | ||
101 | retval = oprofilefs_ulong_from_user(&value, buf, count); | 108 | retval = oprofilefs_ulong_from_user(&value, buf, count); |
102 | if (retval) | 109 | if (retval <= 0) |
103 | return retval; | 110 | return retval; |
104 | 111 | ||
105 | retval = oprofile_set_ulong(file->private_data, value); | 112 | retval = oprofile_set_ulong(file->private_data, value); |
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c index 7ec56fb0bd78..b0dd08e6a9da 100644 --- a/drivers/pci/ats.c +++ b/drivers/pci/ats.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/export.h> | 13 | #include <linux/export.h> |
14 | #include <linux/pci-ats.h> | 14 | #include <linux/pci-ats.h> |
15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
16 | #include <linux/slab.h> | ||
16 | 17 | ||
17 | #include "pci.h" | 18 | #include "pci.h" |
18 | 19 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index fce1c54a0c8d..9ddf69e3bbef 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -132,6 +132,18 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
132 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) | 132 | if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) |
133 | return AE_OK; | 133 | return AE_OK; |
134 | 134 | ||
135 | pdev = pbus->self; | ||
136 | if (pdev && pci_is_pcie(pdev)) { | ||
137 | tmp = acpi_find_root_bridge_handle(pdev); | ||
138 | if (tmp) { | ||
139 | struct acpi_pci_root *root = acpi_pci_find_root(tmp); | ||
140 | |||
141 | if (root && (root->osc_control_set & | ||
142 | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) | ||
143 | return AE_OK; | ||
144 | } | ||
145 | } | ||
146 | |||
135 | acpi_evaluate_integer(handle, "_ADR", NULL, &adr); | 147 | acpi_evaluate_integer(handle, "_ADR", NULL, &adr); |
136 | device = (adr >> 16) & 0xffff; | 148 | device = (adr >> 16) & 0xffff; |
137 | function = adr & 0xffff; | 149 | function = adr & 0xffff; |
@@ -213,7 +225,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
213 | 225 | ||
214 | pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); | 226 | pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); |
215 | if (pdev) { | 227 | if (pdev) { |
216 | pdev->current_state = PCI_D0; | ||
217 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); | 228 | slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); |
218 | pci_dev_put(pdev); | 229 | pci_dev_put(pdev); |
219 | } | 230 | } |
@@ -459,17 +470,8 @@ static int add_bridge(acpi_handle handle) | |||
459 | { | 470 | { |
460 | acpi_status status; | 471 | acpi_status status; |
461 | unsigned long long tmp; | 472 | unsigned long long tmp; |
462 | struct acpi_pci_root *root; | ||
463 | acpi_handle dummy_handle; | 473 | acpi_handle dummy_handle; |
464 | 474 | ||
465 | /* | ||
466 | * We shouldn't use this bridge if PCIe native hotplug control has been | ||
467 | * granted by the BIOS for it. | ||
468 | */ | ||
469 | root = acpi_pci_find_root(handle); | ||
470 | if (root && (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) | ||
471 | return -ENODEV; | ||
472 | |||
473 | /* if the bridge doesn't have _STA, we assume it is always there */ | 475 | /* if the bridge doesn't have _STA, we assume it is always there */ |
474 | status = acpi_get_handle(handle, "_STA", &dummy_handle); | 476 | status = acpi_get_handle(handle, "_STA", &dummy_handle); |
475 | if (ACPI_SUCCESS(status)) { | 477 | if (ACPI_SUCCESS(status)) { |
@@ -1385,19 +1387,11 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, | |||
1385 | static acpi_status | 1387 | static acpi_status |
1386 | find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | 1388 | find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) |
1387 | { | 1389 | { |
1388 | struct acpi_pci_root *root; | ||
1389 | int *count = (int *)context; | 1390 | int *count = (int *)context; |
1390 | 1391 | ||
1391 | if (!acpi_is_root_bridge(handle)) | 1392 | if (!acpi_is_root_bridge(handle)) |
1392 | return AE_OK; | 1393 | return AE_OK; |
1393 | 1394 | ||
1394 | root = acpi_pci_find_root(handle); | ||
1395 | if (!root) | ||
1396 | return AE_OK; | ||
1397 | |||
1398 | if (root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL) | ||
1399 | return AE_OK; | ||
1400 | |||
1401 | (*count)++; | 1395 | (*count)++; |
1402 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | 1396 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, |
1403 | handle_hotplug_event_bridge, NULL); | 1397 | handle_hotplug_event_bridge, NULL); |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index b82c155d7b37..1969a3ee3058 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -283,6 +283,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
283 | struct resource *res; | 283 | struct resource *res; |
284 | struct pci_dev *pdev; | 284 | struct pci_dev *pdev; |
285 | struct pci_sriov *iov = dev->sriov; | 285 | struct pci_sriov *iov = dev->sriov; |
286 | int bars = 0; | ||
286 | 287 | ||
287 | if (!nr_virtfn) | 288 | if (!nr_virtfn) |
288 | return 0; | 289 | return 0; |
@@ -307,6 +308,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
307 | 308 | ||
308 | nres = 0; | 309 | nres = 0; |
309 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { | 310 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { |
311 | bars |= (1 << (i + PCI_IOV_RESOURCES)); | ||
310 | res = dev->resource + PCI_IOV_RESOURCES + i; | 312 | res = dev->resource + PCI_IOV_RESOURCES + i; |
311 | if (res->parent) | 313 | if (res->parent) |
312 | nres++; | 314 | nres++; |
@@ -324,6 +326,11 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) | |||
324 | return -ENOMEM; | 326 | return -ENOMEM; |
325 | } | 327 | } |
326 | 328 | ||
329 | if (pci_enable_resources(dev, bars)) { | ||
330 | dev_err(&dev->dev, "SR-IOV: IOV BARS not allocated\n"); | ||
331 | return -ENOMEM; | ||
332 | } | ||
333 | |||
327 | if (iov->link != dev->devfn) { | 334 | if (iov->link != dev->devfn) { |
328 | pdev = pci_get_slot(dev->bus, iov->link); | 335 | pdev = pci_get_slot(dev->bus, iov->link); |
329 | if (!pdev) | 336 | if (!pdev) |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 6f45a73c6e9f..6d4a5319148d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -664,6 +664,9 @@ static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state) | |||
664 | error = platform_pci_set_power_state(dev, state); | 664 | error = platform_pci_set_power_state(dev, state); |
665 | if (!error) | 665 | if (!error) |
666 | pci_update_current_state(dev, state); | 666 | pci_update_current_state(dev, state); |
667 | /* Fall back to PCI_D0 if native PM is not supported */ | ||
668 | if (!dev->pm_cap) | ||
669 | dev->current_state = PCI_D0; | ||
667 | } else { | 670 | } else { |
668 | error = -ENODEV; | 671 | error = -ENODEV; |
669 | /* Fall back to PCI_D0 if native PM is not supported */ | 672 | /* Fall back to PCI_D0 if native PM is not supported */ |
@@ -1126,7 +1129,11 @@ static int __pci_enable_device_flags(struct pci_dev *dev, | |||
1126 | if (atomic_add_return(1, &dev->enable_cnt) > 1) | 1129 | if (atomic_add_return(1, &dev->enable_cnt) > 1) |
1127 | return 0; /* already enabled */ | 1130 | return 0; /* already enabled */ |
1128 | 1131 | ||
1129 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) | 1132 | /* only skip sriov related */ |
1133 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) | ||
1134 | if (dev->resource[i].flags & flags) | ||
1135 | bars |= (1 << i); | ||
1136 | for (i = PCI_BRIDGE_RESOURCES; i < DEVICE_COUNT_RESOURCE; i++) | ||
1130 | if (dev->resource[i].flags & flags) | 1137 | if (dev->resource[i].flags & flags) |
1131 | bars |= (1 << i); | 1138 | bars |= (1 << i); |
1132 | 1139 | ||
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index cf3f9997546d..10451a15e828 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c | |||
@@ -101,7 +101,9 @@ static s32 scaled_ppm_to_ppb(long ppm) | |||
101 | 101 | ||
102 | static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) | 102 | static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) |
103 | { | 103 | { |
104 | return 1; /* always round timer functions to one nanosecond */ | 104 | tp->tv_sec = 0; |
105 | tp->tv_nsec = 1; | ||
106 | return 0; | ||
105 | } | 107 | } |
106 | 108 | ||
107 | static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) | 109 | static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) |
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 5225930a10cd..691b1ab1a3d0 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
@@ -851,14 +851,12 @@ static int tsi721_doorbell_init(struct tsi721_device *priv) | |||
851 | INIT_WORK(&priv->idb_work, tsi721_db_dpc); | 851 | INIT_WORK(&priv->idb_work, tsi721_db_dpc); |
852 | 852 | ||
853 | /* Allocate buffer for inbound doorbells queue */ | 853 | /* Allocate buffer for inbound doorbells queue */ |
854 | priv->idb_base = dma_alloc_coherent(&priv->pdev->dev, | 854 | priv->idb_base = dma_zalloc_coherent(&priv->pdev->dev, |
855 | IDB_QSIZE * TSI721_IDB_ENTRY_SIZE, | 855 | IDB_QSIZE * TSI721_IDB_ENTRY_SIZE, |
856 | &priv->idb_dma, GFP_KERNEL); | 856 | &priv->idb_dma, GFP_KERNEL); |
857 | if (!priv->idb_base) | 857 | if (!priv->idb_base) |
858 | return -ENOMEM; | 858 | return -ENOMEM; |
859 | 859 | ||
860 | memset(priv->idb_base, 0, IDB_QSIZE * TSI721_IDB_ENTRY_SIZE); | ||
861 | |||
862 | dev_dbg(&priv->pdev->dev, "Allocated IDB buffer @ %p (phys = %llx)\n", | 860 | dev_dbg(&priv->pdev->dev, "Allocated IDB buffer @ %p (phys = %llx)\n", |
863 | priv->idb_base, (unsigned long long)priv->idb_dma); | 861 | priv->idb_base, (unsigned long long)priv->idb_dma); |
864 | 862 | ||
@@ -904,7 +902,7 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | |||
904 | */ | 902 | */ |
905 | 903 | ||
906 | /* Allocate space for DMA descriptors */ | 904 | /* Allocate space for DMA descriptors */ |
907 | bd_ptr = dma_alloc_coherent(&priv->pdev->dev, | 905 | bd_ptr = dma_zalloc_coherent(&priv->pdev->dev, |
908 | bd_num * sizeof(struct tsi721_dma_desc), | 906 | bd_num * sizeof(struct tsi721_dma_desc), |
909 | &bd_phys, GFP_KERNEL); | 907 | &bd_phys, GFP_KERNEL); |
910 | if (!bd_ptr) | 908 | if (!bd_ptr) |
@@ -913,8 +911,6 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | |||
913 | priv->bdma[chnum].bd_phys = bd_phys; | 911 | priv->bdma[chnum].bd_phys = bd_phys; |
914 | priv->bdma[chnum].bd_base = bd_ptr; | 912 | priv->bdma[chnum].bd_base = bd_ptr; |
915 | 913 | ||
916 | memset(bd_ptr, 0, bd_num * sizeof(struct tsi721_dma_desc)); | ||
917 | |||
918 | dev_dbg(&priv->pdev->dev, "DMA descriptors @ %p (phys = %llx)\n", | 914 | dev_dbg(&priv->pdev->dev, "DMA descriptors @ %p (phys = %llx)\n", |
919 | bd_ptr, (unsigned long long)bd_phys); | 915 | bd_ptr, (unsigned long long)bd_phys); |
920 | 916 | ||
@@ -922,7 +918,7 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | |||
922 | sts_size = (bd_num >= TSI721_DMA_MINSTSSZ) ? | 918 | sts_size = (bd_num >= TSI721_DMA_MINSTSSZ) ? |
923 | bd_num : TSI721_DMA_MINSTSSZ; | 919 | bd_num : TSI721_DMA_MINSTSSZ; |
924 | sts_size = roundup_pow_of_two(sts_size); | 920 | sts_size = roundup_pow_of_two(sts_size); |
925 | sts_ptr = dma_alloc_coherent(&priv->pdev->dev, | 921 | sts_ptr = dma_zalloc_coherent(&priv->pdev->dev, |
926 | sts_size * sizeof(struct tsi721_dma_sts), | 922 | sts_size * sizeof(struct tsi721_dma_sts), |
927 | &sts_phys, GFP_KERNEL); | 923 | &sts_phys, GFP_KERNEL); |
928 | if (!sts_ptr) { | 924 | if (!sts_ptr) { |
@@ -938,8 +934,6 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | |||
938 | priv->bdma[chnum].sts_base = sts_ptr; | 934 | priv->bdma[chnum].sts_base = sts_ptr; |
939 | priv->bdma[chnum].sts_size = sts_size; | 935 | priv->bdma[chnum].sts_size = sts_size; |
940 | 936 | ||
941 | memset(sts_ptr, 0, sts_size); | ||
942 | |||
943 | dev_dbg(&priv->pdev->dev, | 937 | dev_dbg(&priv->pdev->dev, |
944 | "desc status FIFO @ %p (phys = %llx) size=0x%x\n", | 938 | "desc status FIFO @ %p (phys = %llx) size=0x%x\n", |
945 | sts_ptr, (unsigned long long)sts_phys, sts_size); | 939 | sts_ptr, (unsigned long long)sts_phys, sts_size); |
@@ -1400,7 +1394,7 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id, | |||
1400 | 1394 | ||
1401 | /* Outbound message descriptor status FIFO allocation */ | 1395 | /* Outbound message descriptor status FIFO allocation */ |
1402 | priv->omsg_ring[mbox].sts_size = roundup_pow_of_two(entries + 1); | 1396 | priv->omsg_ring[mbox].sts_size = roundup_pow_of_two(entries + 1); |
1403 | priv->omsg_ring[mbox].sts_base = dma_alloc_coherent(&priv->pdev->dev, | 1397 | priv->omsg_ring[mbox].sts_base = dma_zalloc_coherent(&priv->pdev->dev, |
1404 | priv->omsg_ring[mbox].sts_size * | 1398 | priv->omsg_ring[mbox].sts_size * |
1405 | sizeof(struct tsi721_dma_sts), | 1399 | sizeof(struct tsi721_dma_sts), |
1406 | &priv->omsg_ring[mbox].sts_phys, GFP_KERNEL); | 1400 | &priv->omsg_ring[mbox].sts_phys, GFP_KERNEL); |
@@ -1412,9 +1406,6 @@ static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id, | |||
1412 | goto out_desc; | 1406 | goto out_desc; |
1413 | } | 1407 | } |
1414 | 1408 | ||
1415 | memset(priv->omsg_ring[mbox].sts_base, 0, | ||
1416 | entries * sizeof(struct tsi721_dma_sts)); | ||
1417 | |||
1418 | /* | 1409 | /* |
1419 | * Configure Outbound Messaging Engine | 1410 | * Configure Outbound Messaging Engine |
1420 | */ | 1411 | */ |
@@ -2116,8 +2107,8 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv) | |||
2116 | INIT_LIST_HEAD(&mport->dbells); | 2107 | INIT_LIST_HEAD(&mport->dbells); |
2117 | 2108 | ||
2118 | rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); | 2109 | rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); |
2119 | rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 0); | 2110 | rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 3); |
2120 | rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0); | 2111 | rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 3); |
2121 | strcpy(mport->name, "Tsi721 mport"); | 2112 | strcpy(mport->name, "Tsi721 mport"); |
2122 | 2113 | ||
2123 | /* Hook up interrupt handler */ | 2114 | /* Hook up interrupt handler */ |
@@ -2163,7 +2154,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, | |||
2163 | const struct pci_device_id *id) | 2154 | const struct pci_device_id *id) |
2164 | { | 2155 | { |
2165 | struct tsi721_device *priv; | 2156 | struct tsi721_device *priv; |
2166 | int i; | 2157 | int i, cap; |
2167 | int err; | 2158 | int err; |
2168 | u32 regval; | 2159 | u32 regval; |
2169 | 2160 | ||
@@ -2271,10 +2262,20 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, | |||
2271 | dev_info(&pdev->dev, "Unable to set consistent DMA mask\n"); | 2262 | dev_info(&pdev->dev, "Unable to set consistent DMA mask\n"); |
2272 | } | 2263 | } |
2273 | 2264 | ||
2274 | /* Clear "no snoop" and "relaxed ordering" bits. */ | 2265 | cap = pci_pcie_cap(pdev); |
2275 | pci_read_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, ®val); | 2266 | BUG_ON(cap == 0); |
2276 | regval &= ~(PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN); | 2267 | |
2277 | pci_write_config_dword(pdev, 0x40 + PCI_EXP_DEVCTL, regval); | 2268 | /* Clear "no snoop" and "relaxed ordering" bits, use default MRRS. */ |
2269 | pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, ®val); | ||
2270 | regval &= ~(PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN | | ||
2271 | PCI_EXP_DEVCTL_NOSNOOP_EN); | ||
2272 | regval |= 0x2 << MAX_READ_REQUEST_SZ_SHIFT; | ||
2273 | pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL, regval); | ||
2274 | |||
2275 | /* Adjust PCIe completion timeout. */ | ||
2276 | pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL2, ®val); | ||
2277 | regval &= ~(0x0f); | ||
2278 | pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL2, regval | 0x2); | ||
2278 | 2279 | ||
2279 | /* | 2280 | /* |
2280 | * FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block | 2281 | * FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block |
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h index 58be4deb1402..822e54c394d5 100644 --- a/drivers/rapidio/devices/tsi721.h +++ b/drivers/rapidio/devices/tsi721.h | |||
@@ -72,6 +72,8 @@ | |||
72 | #define TSI721_MSIXPBA_OFFSET 0x2a000 | 72 | #define TSI721_MSIXPBA_OFFSET 0x2a000 |
73 | #define TSI721_PCIECFG_EPCTL 0x400 | 73 | #define TSI721_PCIECFG_EPCTL 0x400 |
74 | 74 | ||
75 | #define MAX_READ_REQUEST_SZ_SHIFT 12 | ||
76 | |||
75 | /* | 77 | /* |
76 | * Event Management Registers | 78 | * Event Management Registers |
77 | */ | 79 | */ |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index fa4d9f324189..3bcc7cfcaba7 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -73,6 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) | |||
73 | err = -EINVAL; | 73 | err = -EINVAL; |
74 | 74 | ||
75 | mutex_unlock(&rtc->ops_lock); | 75 | mutex_unlock(&rtc->ops_lock); |
76 | /* A timer might have just expired */ | ||
77 | schedule_work(&rtc->irqwork); | ||
76 | return err; | 78 | return err; |
77 | } | 79 | } |
78 | EXPORT_SYMBOL_GPL(rtc_set_time); | 80 | EXPORT_SYMBOL_GPL(rtc_set_time); |
@@ -112,6 +114,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) | |||
112 | err = -EINVAL; | 114 | err = -EINVAL; |
113 | 115 | ||
114 | mutex_unlock(&rtc->ops_lock); | 116 | mutex_unlock(&rtc->ops_lock); |
117 | /* A timer might have just expired */ | ||
118 | schedule_work(&rtc->irqwork); | ||
115 | 119 | ||
116 | return err; | 120 | return err; |
117 | } | 121 | } |
@@ -403,6 +407,8 @@ int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
403 | timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); | 407 | timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); |
404 | } | 408 | } |
405 | mutex_unlock(&rtc->ops_lock); | 409 | mutex_unlock(&rtc->ops_lock); |
410 | /* maybe that was in the past.*/ | ||
411 | schedule_work(&rtc->irqwork); | ||
406 | return err; | 412 | return err; |
407 | } | 413 | } |
408 | EXPORT_SYMBOL_GPL(rtc_initialize_alarm); | 414 | EXPORT_SYMBOL_GPL(rtc_initialize_alarm); |
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index eda128fc1d38..64aedd8cc095 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c | |||
@@ -357,10 +357,19 @@ static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
357 | static struct rtc_class_ops m41t80_rtc_ops = { | 357 | static struct rtc_class_ops m41t80_rtc_ops = { |
358 | .read_time = m41t80_rtc_read_time, | 358 | .read_time = m41t80_rtc_read_time, |
359 | .set_time = m41t80_rtc_set_time, | 359 | .set_time = m41t80_rtc_set_time, |
360 | /* | ||
361 | * XXX - m41t80 alarm functionality is reported broken. | ||
362 | * until it is fixed, don't register alarm functions. | ||
363 | * | ||
360 | .read_alarm = m41t80_rtc_read_alarm, | 364 | .read_alarm = m41t80_rtc_read_alarm, |
361 | .set_alarm = m41t80_rtc_set_alarm, | 365 | .set_alarm = m41t80_rtc_set_alarm, |
366 | */ | ||
362 | .proc = m41t80_rtc_proc, | 367 | .proc = m41t80_rtc_proc, |
368 | /* | ||
369 | * See above comment on broken alarm | ||
370 | * | ||
363 | .alarm_irq_enable = m41t80_rtc_alarm_irq_enable, | 371 | .alarm_irq_enable = m41t80_rtc_alarm_irq_enable, |
372 | */ | ||
364 | }; | 373 | }; |
365 | 374 | ||
366 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) | 375 | #if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE) |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 7639ab906f02..5b979d9cc332 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -202,7 +202,6 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
202 | void __iomem *base = s3c_rtc_base; | 202 | void __iomem *base = s3c_rtc_base; |
203 | int year = tm->tm_year - 100; | 203 | int year = tm->tm_year - 100; |
204 | 204 | ||
205 | clk_enable(rtc_clk); | ||
206 | pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", | 205 | pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", |
207 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | 206 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, |
208 | tm->tm_hour, tm->tm_min, tm->tm_sec); | 207 | tm->tm_hour, tm->tm_min, tm->tm_sec); |
@@ -214,6 +213,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) | |||
214 | return -EINVAL; | 213 | return -EINVAL; |
215 | } | 214 | } |
216 | 215 | ||
216 | clk_enable(rtc_clk); | ||
217 | writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); | 217 | writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); |
218 | writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); | 218 | writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); |
219 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); | 219 | writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 11f07f888223..b79576b64f45 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -55,6 +55,10 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdev) | |||
55 | { | 55 | { |
56 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); | 56 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); |
57 | 57 | ||
58 | /* if previous slave_alloc returned early, there is nothing to do */ | ||
59 | if (!zfcp_sdev->port) | ||
60 | return; | ||
61 | |||
58 | zfcp_erp_lun_shutdown_wait(sdev, "scssd_1"); | 62 | zfcp_erp_lun_shutdown_wait(sdev, "scssd_1"); |
59 | put_device(&zfcp_sdev->port->dev); | 63 | put_device(&zfcp_sdev->port->dev); |
60 | } | 64 | } |
diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 5f94d22c491e..542668292900 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c | |||
@@ -233,13 +233,9 @@ int bbc_i2c_write_buf(struct bbc_i2c_client *client, | |||
233 | int ret = 0; | 233 | int ret = 0; |
234 | 234 | ||
235 | while (len > 0) { | 235 | while (len > 0) { |
236 | int err = bbc_i2c_writeb(client, *buf, off); | 236 | ret = bbc_i2c_writeb(client, *buf, off); |
237 | 237 | if (ret < 0) | |
238 | if (err < 0) { | ||
239 | ret = err; | ||
240 | break; | 238 | break; |
241 | } | ||
242 | |||
243 | len--; | 239 | len--; |
244 | buf++; | 240 | buf++; |
245 | off++; | 241 | off++; |
@@ -253,11 +249,9 @@ int bbc_i2c_read_buf(struct bbc_i2c_client *client, | |||
253 | int ret = 0; | 249 | int ret = 0; |
254 | 250 | ||
255 | while (len > 0) { | 251 | while (len > 0) { |
256 | int err = bbc_i2c_readb(client, buf, off); | 252 | ret = bbc_i2c_readb(client, buf, off); |
257 | if (err < 0) { | 253 | if (ret < 0) |
258 | ret = err; | ||
259 | break; | 254 | break; |
260 | } | ||
261 | len--; | 255 | len--; |
262 | buf++; | 256 | buf++; |
263 | off++; | 257 | off++; |
@@ -422,17 +416,6 @@ static struct platform_driver bbc_i2c_driver = { | |||
422 | .remove = __devexit_p(bbc_i2c_remove), | 416 | .remove = __devexit_p(bbc_i2c_remove), |
423 | }; | 417 | }; |
424 | 418 | ||
425 | static int __init bbc_i2c_init(void) | 419 | module_platform_driver(bbc_i2c_driver); |
426 | { | ||
427 | return platform_driver_register(&bbc_i2c_driver); | ||
428 | } | ||
429 | |||
430 | static void __exit bbc_i2c_exit(void) | ||
431 | { | ||
432 | platform_driver_unregister(&bbc_i2c_driver); | ||
433 | } | ||
434 | |||
435 | module_init(bbc_i2c_init); | ||
436 | module_exit(bbc_i2c_exit); | ||
437 | 420 | ||
438 | MODULE_LICENSE("GPL"); | 421 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c index 965a1fccd66a..4b9939726c34 100644 --- a/drivers/sbus/char/display7seg.c +++ b/drivers/sbus/char/display7seg.c | |||
@@ -275,15 +275,4 @@ static struct platform_driver d7s_driver = { | |||
275 | .remove = __devexit_p(d7s_remove), | 275 | .remove = __devexit_p(d7s_remove), |
276 | }; | 276 | }; |
277 | 277 | ||
278 | static int __init d7s_init(void) | 278 | module_platform_driver(d7s_driver); |
279 | { | ||
280 | return platform_driver_register(&d7s_driver); | ||
281 | } | ||
282 | |||
283 | static void __exit d7s_exit(void) | ||
284 | { | ||
285 | platform_driver_unregister(&d7s_driver); | ||
286 | } | ||
287 | |||
288 | module_init(d7s_init); | ||
289 | module_exit(d7s_exit); | ||
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index be7b4e56154f..339fd6f65eda 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c | |||
@@ -1138,16 +1138,6 @@ static struct platform_driver envctrl_driver = { | |||
1138 | .remove = __devexit_p(envctrl_remove), | 1138 | .remove = __devexit_p(envctrl_remove), |
1139 | }; | 1139 | }; |
1140 | 1140 | ||
1141 | static int __init envctrl_init(void) | 1141 | module_platform_driver(envctrl_driver); |
1142 | { | ||
1143 | return platform_driver_register(&envctrl_driver); | ||
1144 | } | ||
1145 | |||
1146 | static void __exit envctrl_exit(void) | ||
1147 | { | ||
1148 | platform_driver_unregister(&envctrl_driver); | ||
1149 | } | ||
1150 | 1142 | ||
1151 | module_init(envctrl_init); | ||
1152 | module_exit(envctrl_exit); | ||
1153 | MODULE_LICENSE("GPL"); | 1143 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 73dd4e7afaaa..826157f38694 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c | |||
@@ -216,16 +216,6 @@ static struct platform_driver flash_driver = { | |||
216 | .remove = __devexit_p(flash_remove), | 216 | .remove = __devexit_p(flash_remove), |
217 | }; | 217 | }; |
218 | 218 | ||
219 | static int __init flash_init(void) | 219 | module_platform_driver(flash_driver); |
220 | { | ||
221 | return platform_driver_register(&flash_driver); | ||
222 | } | ||
223 | |||
224 | static void __exit flash_cleanup(void) | ||
225 | { | ||
226 | platform_driver_unregister(&flash_driver); | ||
227 | } | ||
228 | 220 | ||
229 | module_init(flash_init); | ||
230 | module_exit(flash_cleanup); | ||
231 | MODULE_LICENSE("GPL"); | 221 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index ebce9639a26a..0b31658ccde5 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c | |||
@@ -435,16 +435,6 @@ static struct platform_driver uctrl_driver = { | |||
435 | }; | 435 | }; |
436 | 436 | ||
437 | 437 | ||
438 | static int __init uctrl_init(void) | 438 | module_platform_driver(uctrl_driver); |
439 | { | ||
440 | return platform_driver_register(&uctrl_driver); | ||
441 | } | ||
442 | |||
443 | static void __exit uctrl_exit(void) | ||
444 | { | ||
445 | platform_driver_unregister(&uctrl_driver); | ||
446 | } | ||
447 | 439 | ||
448 | module_init(uctrl_init); | ||
449 | module_exit(uctrl_exit); | ||
450 | MODULE_LICENSE("GPL"); | 440 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index dba72a4e6a1c..1ad0b8225560 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c | |||
@@ -1906,18 +1906,19 @@ static int bnx2i_queue_scsi_cmd_resp(struct iscsi_session *session, | |||
1906 | spin_lock(&session->lock); | 1906 | spin_lock(&session->lock); |
1907 | task = iscsi_itt_to_task(bnx2i_conn->cls_conn->dd_data, | 1907 | task = iscsi_itt_to_task(bnx2i_conn->cls_conn->dd_data, |
1908 | cqe->itt & ISCSI_CMD_RESPONSE_INDEX); | 1908 | cqe->itt & ISCSI_CMD_RESPONSE_INDEX); |
1909 | if (!task) { | 1909 | if (!task || !task->sc) { |
1910 | spin_unlock(&session->lock); | 1910 | spin_unlock(&session->lock); |
1911 | return -EINVAL; | 1911 | return -EINVAL; |
1912 | } | 1912 | } |
1913 | sc = task->sc; | 1913 | sc = task->sc; |
1914 | spin_unlock(&session->lock); | ||
1915 | 1914 | ||
1916 | if (!blk_rq_cpu_valid(sc->request)) | 1915 | if (!blk_rq_cpu_valid(sc->request)) |
1917 | cpu = smp_processor_id(); | 1916 | cpu = smp_processor_id(); |
1918 | else | 1917 | else |
1919 | cpu = sc->request->cpu; | 1918 | cpu = sc->request->cpu; |
1920 | 1919 | ||
1920 | spin_unlock(&session->lock); | ||
1921 | |||
1921 | p = &per_cpu(bnx2i_percpu, cpu); | 1922 | p = &per_cpu(bnx2i_percpu, cpu); |
1922 | spin_lock(&p->p_work_lock); | 1923 | spin_lock(&p->p_work_lock); |
1923 | if (unlikely(!p->iothread)) { | 1924 | if (unlikely(!p->iothread)) { |
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index cefbe44bb84a..8d67467dd9ce 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/sysfs.h> | 31 | #include <linux/sysfs.h> |
32 | #include <linux/ctype.h> | 32 | #include <linux/ctype.h> |
33 | #include <linux/workqueue.h> | 33 | #include <linux/workqueue.h> |
34 | #include <net/dcbnl.h> | ||
35 | #include <net/dcbevent.h> | ||
34 | #include <scsi/scsi_tcq.h> | 36 | #include <scsi/scsi_tcq.h> |
35 | #include <scsi/scsicam.h> | 37 | #include <scsi/scsicam.h> |
36 | #include <scsi/scsi_transport.h> | 38 | #include <scsi/scsi_transport.h> |
@@ -101,6 +103,8 @@ static int fcoe_ddp_done(struct fc_lport *, u16); | |||
101 | static int fcoe_ddp_target(struct fc_lport *, u16, struct scatterlist *, | 103 | static int fcoe_ddp_target(struct fc_lport *, u16, struct scatterlist *, |
102 | unsigned int); | 104 | unsigned int); |
103 | static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *); | 105 | static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *); |
106 | static int fcoe_dcb_app_notification(struct notifier_block *notifier, | ||
107 | ulong event, void *ptr); | ||
104 | 108 | ||
105 | static bool fcoe_match(struct net_device *netdev); | 109 | static bool fcoe_match(struct net_device *netdev); |
106 | static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode); | 110 | static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode); |
@@ -129,6 +133,11 @@ static struct notifier_block fcoe_cpu_notifier = { | |||
129 | .notifier_call = fcoe_cpu_callback, | 133 | .notifier_call = fcoe_cpu_callback, |
130 | }; | 134 | }; |
131 | 135 | ||
136 | /* notification function for DCB events */ | ||
137 | static struct notifier_block dcb_notifier = { | ||
138 | .notifier_call = fcoe_dcb_app_notification, | ||
139 | }; | ||
140 | |||
132 | static struct scsi_transport_template *fcoe_nport_scsi_transport; | 141 | static struct scsi_transport_template *fcoe_nport_scsi_transport; |
133 | static struct scsi_transport_template *fcoe_vport_scsi_transport; | 142 | static struct scsi_transport_template *fcoe_vport_scsi_transport; |
134 | 143 | ||
@@ -1522,6 +1531,8 @@ int fcoe_xmit(struct fc_lport *lport, struct fc_frame *fp) | |||
1522 | skb_reset_network_header(skb); | 1531 | skb_reset_network_header(skb); |
1523 | skb->mac_len = elen; | 1532 | skb->mac_len = elen; |
1524 | skb->protocol = htons(ETH_P_FCOE); | 1533 | skb->protocol = htons(ETH_P_FCOE); |
1534 | skb->priority = port->priority; | ||
1535 | |||
1525 | if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN && | 1536 | if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN && |
1526 | fcoe->realdev->features & NETIF_F_HW_VLAN_TX) { | 1537 | fcoe->realdev->features & NETIF_F_HW_VLAN_TX) { |
1527 | skb->vlan_tci = VLAN_TAG_PRESENT | | 1538 | skb->vlan_tci = VLAN_TAG_PRESENT | |
@@ -1624,6 +1635,7 @@ static inline int fcoe_filter_frames(struct fc_lport *lport, | |||
1624 | stats->InvalidCRCCount++; | 1635 | stats->InvalidCRCCount++; |
1625 | if (stats->InvalidCRCCount < 5) | 1636 | if (stats->InvalidCRCCount < 5) |
1626 | printk(KERN_WARNING "fcoe: dropping frame with CRC error\n"); | 1637 | printk(KERN_WARNING "fcoe: dropping frame with CRC error\n"); |
1638 | put_cpu(); | ||
1627 | return -EINVAL; | 1639 | return -EINVAL; |
1628 | } | 1640 | } |
1629 | 1641 | ||
@@ -1746,6 +1758,7 @@ int fcoe_percpu_receive_thread(void *arg) | |||
1746 | */ | 1758 | */ |
1747 | static void fcoe_dev_setup(void) | 1759 | static void fcoe_dev_setup(void) |
1748 | { | 1760 | { |
1761 | register_dcbevent_notifier(&dcb_notifier); | ||
1749 | register_netdevice_notifier(&fcoe_notifier); | 1762 | register_netdevice_notifier(&fcoe_notifier); |
1750 | } | 1763 | } |
1751 | 1764 | ||
@@ -1754,9 +1767,69 @@ static void fcoe_dev_setup(void) | |||
1754 | */ | 1767 | */ |
1755 | static void fcoe_dev_cleanup(void) | 1768 | static void fcoe_dev_cleanup(void) |
1756 | { | 1769 | { |
1770 | unregister_dcbevent_notifier(&dcb_notifier); | ||
1757 | unregister_netdevice_notifier(&fcoe_notifier); | 1771 | unregister_netdevice_notifier(&fcoe_notifier); |
1758 | } | 1772 | } |
1759 | 1773 | ||
1774 | static struct fcoe_interface * | ||
1775 | fcoe_hostlist_lookup_realdev_port(struct net_device *netdev) | ||
1776 | { | ||
1777 | struct fcoe_interface *fcoe; | ||
1778 | struct net_device *real_dev; | ||
1779 | |||
1780 | list_for_each_entry(fcoe, &fcoe_hostlist, list) { | ||
1781 | if (fcoe->netdev->priv_flags & IFF_802_1Q_VLAN) | ||
1782 | real_dev = vlan_dev_real_dev(fcoe->netdev); | ||
1783 | else | ||
1784 | real_dev = fcoe->netdev; | ||
1785 | |||
1786 | if (netdev == real_dev) | ||
1787 | return fcoe; | ||
1788 | } | ||
1789 | return NULL; | ||
1790 | } | ||
1791 | |||
1792 | static int fcoe_dcb_app_notification(struct notifier_block *notifier, | ||
1793 | ulong event, void *ptr) | ||
1794 | { | ||
1795 | struct dcb_app_type *entry = ptr; | ||
1796 | struct fcoe_interface *fcoe; | ||
1797 | struct net_device *netdev; | ||
1798 | struct fcoe_port *port; | ||
1799 | int prio; | ||
1800 | |||
1801 | if (entry->app.selector != DCB_APP_IDTYPE_ETHTYPE) | ||
1802 | return NOTIFY_OK; | ||
1803 | |||
1804 | netdev = dev_get_by_index(&init_net, entry->ifindex); | ||
1805 | if (!netdev) | ||
1806 | return NOTIFY_OK; | ||
1807 | |||
1808 | fcoe = fcoe_hostlist_lookup_realdev_port(netdev); | ||
1809 | dev_put(netdev); | ||
1810 | if (!fcoe) | ||
1811 | return NOTIFY_OK; | ||
1812 | |||
1813 | if (entry->dcbx & DCB_CAP_DCBX_VER_CEE) | ||
1814 | prio = ffs(entry->app.priority) - 1; | ||
1815 | else | ||
1816 | prio = entry->app.priority; | ||
1817 | |||
1818 | if (prio < 0) | ||
1819 | return NOTIFY_OK; | ||
1820 | |||
1821 | if (entry->app.protocol == ETH_P_FIP || | ||
1822 | entry->app.protocol == ETH_P_FCOE) | ||
1823 | fcoe->ctlr.priority = prio; | ||
1824 | |||
1825 | if (entry->app.protocol == ETH_P_FCOE) { | ||
1826 | port = lport_priv(fcoe->ctlr.lp); | ||
1827 | port->priority = prio; | ||
1828 | } | ||
1829 | |||
1830 | return NOTIFY_OK; | ||
1831 | } | ||
1832 | |||
1760 | /** | 1833 | /** |
1761 | * fcoe_device_notification() - Handler for net device events | 1834 | * fcoe_device_notification() - Handler for net device events |
1762 | * @notifier: The context of the notification | 1835 | * @notifier: The context of the notification |
@@ -1965,6 +2038,46 @@ static bool fcoe_match(struct net_device *netdev) | |||
1965 | } | 2038 | } |
1966 | 2039 | ||
1967 | /** | 2040 | /** |
2041 | * fcoe_dcb_create() - Initialize DCB attributes and hooks | ||
2042 | * @netdev: The net_device object of the L2 link that should be queried | ||
2043 | * @port: The fcoe_port to bind FCoE APP priority with | ||
2044 | * @ | ||
2045 | */ | ||
2046 | static void fcoe_dcb_create(struct fcoe_interface *fcoe) | ||
2047 | { | ||
2048 | #ifdef CONFIG_DCB | ||
2049 | int dcbx; | ||
2050 | u8 fup, up; | ||
2051 | struct net_device *netdev = fcoe->realdev; | ||
2052 | struct fcoe_port *port = lport_priv(fcoe->ctlr.lp); | ||
2053 | struct dcb_app app = { | ||
2054 | .priority = 0, | ||
2055 | .protocol = ETH_P_FCOE | ||
2056 | }; | ||
2057 | |||
2058 | /* setup DCB priority attributes. */ | ||
2059 | if (netdev && netdev->dcbnl_ops && netdev->dcbnl_ops->getdcbx) { | ||
2060 | dcbx = netdev->dcbnl_ops->getdcbx(netdev); | ||
2061 | |||
2062 | if (dcbx & DCB_CAP_DCBX_VER_IEEE) { | ||
2063 | app.selector = IEEE_8021QAZ_APP_SEL_ETHERTYPE; | ||
2064 | up = dcb_ieee_getapp_mask(netdev, &app); | ||
2065 | app.protocol = ETH_P_FIP; | ||
2066 | fup = dcb_ieee_getapp_mask(netdev, &app); | ||
2067 | } else { | ||
2068 | app.selector = DCB_APP_IDTYPE_ETHTYPE; | ||
2069 | up = dcb_getapp(netdev, &app); | ||
2070 | app.protocol = ETH_P_FIP; | ||
2071 | fup = dcb_getapp(netdev, &app); | ||
2072 | } | ||
2073 | |||
2074 | port->priority = ffs(up) ? ffs(up) - 1 : 0; | ||
2075 | fcoe->ctlr.priority = ffs(fup) ? ffs(fup) - 1 : port->priority; | ||
2076 | } | ||
2077 | #endif | ||
2078 | } | ||
2079 | |||
2080 | /** | ||
1968 | * fcoe_create() - Create a fcoe interface | 2081 | * fcoe_create() - Create a fcoe interface |
1969 | * @netdev : The net_device object the Ethernet interface to create on | 2082 | * @netdev : The net_device object the Ethernet interface to create on |
1970 | * @fip_mode: The FIP mode for this creation | 2083 | * @fip_mode: The FIP mode for this creation |
@@ -2007,6 +2120,9 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | |||
2007 | /* Make this the "master" N_Port */ | 2120 | /* Make this the "master" N_Port */ |
2008 | fcoe->ctlr.lp = lport; | 2121 | fcoe->ctlr.lp = lport; |
2009 | 2122 | ||
2123 | /* setup DCB priority attributes. */ | ||
2124 | fcoe_dcb_create(fcoe); | ||
2125 | |||
2010 | /* add to lports list */ | 2126 | /* add to lports list */ |
2011 | fcoe_hostlist_add(lport); | 2127 | fcoe_hostlist_add(lport); |
2012 | 2128 | ||
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index c74c4b8e71ef..e7522dcc296e 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c | |||
@@ -320,6 +320,7 @@ static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf) | |||
320 | 320 | ||
321 | skb_put(skb, sizeof(*sol)); | 321 | skb_put(skb, sizeof(*sol)); |
322 | skb->protocol = htons(ETH_P_FIP); | 322 | skb->protocol = htons(ETH_P_FIP); |
323 | skb->priority = fip->priority; | ||
323 | skb_reset_mac_header(skb); | 324 | skb_reset_mac_header(skb); |
324 | skb_reset_network_header(skb); | 325 | skb_reset_network_header(skb); |
325 | fip->send(fip, skb); | 326 | fip->send(fip, skb); |
@@ -474,6 +475,7 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, | |||
474 | } | 475 | } |
475 | skb_put(skb, len); | 476 | skb_put(skb, len); |
476 | skb->protocol = htons(ETH_P_FIP); | 477 | skb->protocol = htons(ETH_P_FIP); |
478 | skb->priority = fip->priority; | ||
477 | skb_reset_mac_header(skb); | 479 | skb_reset_mac_header(skb); |
478 | skb_reset_network_header(skb); | 480 | skb_reset_network_header(skb); |
479 | fip->send(fip, skb); | 481 | fip->send(fip, skb); |
@@ -566,6 +568,7 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport, | |||
566 | cap->fip.fip_dl_len = htons(dlen / FIP_BPW); | 568 | cap->fip.fip_dl_len = htons(dlen / FIP_BPW); |
567 | 569 | ||
568 | skb->protocol = htons(ETH_P_FIP); | 570 | skb->protocol = htons(ETH_P_FIP); |
571 | skb->priority = fip->priority; | ||
569 | skb_reset_mac_header(skb); | 572 | skb_reset_mac_header(skb); |
570 | skb_reset_network_header(skb); | 573 | skb_reset_network_header(skb); |
571 | return 0; | 574 | return 0; |
@@ -1911,6 +1914,7 @@ static void fcoe_ctlr_vn_send(struct fcoe_ctlr *fip, | |||
1911 | 1914 | ||
1912 | skb_put(skb, len); | 1915 | skb_put(skb, len); |
1913 | skb->protocol = htons(ETH_P_FIP); | 1916 | skb->protocol = htons(ETH_P_FIP); |
1917 | skb->priority = fip->priority; | ||
1914 | skb_reset_mac_header(skb); | 1918 | skb_reset_mac_header(skb); |
1915 | skb_reset_network_header(skb); | 1919 | skb_reset_network_header(skb); |
1916 | 1920 | ||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 4e041f6d808c..d570573b7963 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -4335,7 +4335,7 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
4335 | /* insert into event log */ | 4335 | /* insert into event log */ |
4336 | sz = offsetof(Mpi2EventNotificationReply_t, EventData) + | 4336 | sz = offsetof(Mpi2EventNotificationReply_t, EventData) + |
4337 | sizeof(Mpi2EventDataSasDeviceStatusChange_t); | 4337 | sizeof(Mpi2EventDataSasDeviceStatusChange_t); |
4338 | event_reply = kzalloc(sz, GFP_KERNEL); | 4338 | event_reply = kzalloc(sz, GFP_ATOMIC); |
4339 | if (!event_reply) { | 4339 | if (!event_reply) { |
4340 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 4340 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
4341 | ioc->name, __FILE__, __LINE__, __func__); | 4341 | ioc->name, __FILE__, __LINE__, __func__); |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index ac326c41e931..6465dae5883a 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -1762,12 +1762,31 @@ qla2x00_get_host_port_state(struct Scsi_Host *shost) | |||
1762 | scsi_qla_host_t *vha = shost_priv(shost); | 1762 | scsi_qla_host_t *vha = shost_priv(shost); |
1763 | struct scsi_qla_host *base_vha = pci_get_drvdata(vha->hw->pdev); | 1763 | struct scsi_qla_host *base_vha = pci_get_drvdata(vha->hw->pdev); |
1764 | 1764 | ||
1765 | if (!base_vha->flags.online) | 1765 | if (!base_vha->flags.online) { |
1766 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; | 1766 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; |
1767 | else if (atomic_read(&base_vha->loop_state) == LOOP_TIMEOUT) | 1767 | return; |
1768 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; | 1768 | } |
1769 | else | 1769 | |
1770 | switch (atomic_read(&base_vha->loop_state)) { | ||
1771 | case LOOP_UPDATE: | ||
1772 | fc_host_port_state(shost) = FC_PORTSTATE_DIAGNOSTICS; | ||
1773 | break; | ||
1774 | case LOOP_DOWN: | ||
1775 | if (test_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags)) | ||
1776 | fc_host_port_state(shost) = FC_PORTSTATE_DIAGNOSTICS; | ||
1777 | else | ||
1778 | fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; | ||
1779 | break; | ||
1780 | case LOOP_DEAD: | ||
1781 | fc_host_port_state(shost) = FC_PORTSTATE_LINKDOWN; | ||
1782 | break; | ||
1783 | case LOOP_READY: | ||
1770 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; | 1784 | fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; |
1785 | break; | ||
1786 | default: | ||
1787 | fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; | ||
1788 | break; | ||
1789 | } | ||
1771 | } | 1790 | } |
1772 | 1791 | ||
1773 | static int | 1792 | static int |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 9df4787715c0..f3cddd5800c3 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -12,17 +12,17 @@ | |||
12 | * | Level | Last Value Used | Holes | | 12 | * | Level | Last Value Used | Holes | |
13 | * ---------------------------------------------------------------------- | 13 | * ---------------------------------------------------------------------- |
14 | * | Module Init and Probe | 0x0116 | | | 14 | * | Module Init and Probe | 0x0116 | | |
15 | * | Mailbox commands | 0x1129 | | | 15 | * | Mailbox commands | 0x112b | | |
16 | * | Device Discovery | 0x2083 | | | 16 | * | Device Discovery | 0x2083 | | |
17 | * | Queue Command and IO tracing | 0x302e | 0x3008 | | 17 | * | Queue Command and IO tracing | 0x302e | 0x3008 | |
18 | * | DPC Thread | 0x401c | | | 18 | * | DPC Thread | 0x401c | | |
19 | * | Async Events | 0x5059 | | | 19 | * | Async Events | 0x5059 | | |
20 | * | Timer Routines | 0x600d | | | 20 | * | Timer Routines | 0x6010 | 0x600e,0x600f | |
21 | * | User Space Interactions | 0x709d | | | 21 | * | User Space Interactions | 0x709d | | |
22 | * | Task Management | 0x8041 | | | 22 | * | Task Management | 0x8041 | 0x800b | |
23 | * | AER/EEH | 0x900f | | | 23 | * | AER/EEH | 0x900f | | |
24 | * | Virtual Port | 0xa007 | | | 24 | * | Virtual Port | 0xa007 | | |
25 | * | ISP82XX Specific | 0xb051 | | | 25 | * | ISP82XX Specific | 0xb052 | | |
26 | * | MultiQ | 0xc00b | | | 26 | * | MultiQ | 0xc00b | | |
27 | * | Misc | 0xd00b | | | 27 | * | Misc | 0xd00b | | |
28 | * ---------------------------------------------------------------------- | 28 | * ---------------------------------------------------------------------- |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index ce32d8135c9e..c0c11afb685c 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -578,6 +578,7 @@ extern int qla82xx_check_md_needed(scsi_qla_host_t *); | |||
578 | extern void qla82xx_chip_reset_cleanup(scsi_qla_host_t *); | 578 | extern void qla82xx_chip_reset_cleanup(scsi_qla_host_t *); |
579 | extern int qla82xx_mbx_beacon_ctl(scsi_qla_host_t *, int); | 579 | extern int qla82xx_mbx_beacon_ctl(scsi_qla_host_t *, int); |
580 | extern char *qdev_state(uint32_t); | 580 | extern char *qdev_state(uint32_t); |
581 | extern void qla82xx_clear_pending_mbx(scsi_qla_host_t *); | ||
581 | 582 | ||
582 | /* BSG related functions */ | 583 | /* BSG related functions */ |
583 | extern int qla24xx_bsg_request(struct fc_bsg_job *); | 584 | extern int qla24xx_bsg_request(struct fc_bsg_job *); |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index f03e915f1877..54ea68cec4c5 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1509,7 +1509,8 @@ enable_82xx_npiv: | |||
1509 | &ha->fw_xcb_count, NULL, NULL, | 1509 | &ha->fw_xcb_count, NULL, NULL, |
1510 | &ha->max_npiv_vports, NULL); | 1510 | &ha->max_npiv_vports, NULL); |
1511 | 1511 | ||
1512 | if (!fw_major_version && ql2xallocfwdump) | 1512 | if (!fw_major_version && ql2xallocfwdump |
1513 | && !IS_QLA82XX(ha)) | ||
1513 | qla2x00_alloc_fw_dump(vha); | 1514 | qla2x00_alloc_fw_dump(vha); |
1514 | } | 1515 | } |
1515 | } else { | 1516 | } else { |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index dbec89622a0f..a4b267e60a35 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -120,11 +120,10 @@ qla2x00_prep_cont_type0_iocb(struct scsi_qla_host *vha) | |||
120 | * Returns a pointer to the continuation type 1 IOCB packet. | 120 | * Returns a pointer to the continuation type 1 IOCB packet. |
121 | */ | 121 | */ |
122 | static inline cont_a64_entry_t * | 122 | static inline cont_a64_entry_t * |
123 | qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha) | 123 | qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *vha, struct req_que *req) |
124 | { | 124 | { |
125 | cont_a64_entry_t *cont_pkt; | 125 | cont_a64_entry_t *cont_pkt; |
126 | 126 | ||
127 | struct req_que *req = vha->req; | ||
128 | /* Adjust ring index. */ | 127 | /* Adjust ring index. */ |
129 | req->ring_index++; | 128 | req->ring_index++; |
130 | if (req->ring_index == req->length) { | 129 | if (req->ring_index == req->length) { |
@@ -292,7 +291,7 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt, | |||
292 | * Five DSDs are available in the Continuation | 291 | * Five DSDs are available in the Continuation |
293 | * Type 1 IOCB. | 292 | * Type 1 IOCB. |
294 | */ | 293 | */ |
295 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha); | 294 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req); |
296 | cur_dsd = (uint32_t *)cont_pkt->dseg_0_address; | 295 | cur_dsd = (uint32_t *)cont_pkt->dseg_0_address; |
297 | avail_dsds = 5; | 296 | avail_dsds = 5; |
298 | } | 297 | } |
@@ -684,7 +683,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, | |||
684 | * Five DSDs are available in the Continuation | 683 | * Five DSDs are available in the Continuation |
685 | * Type 1 IOCB. | 684 | * Type 1 IOCB. |
686 | */ | 685 | */ |
687 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha); | 686 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, vha->req); |
688 | cur_dsd = (uint32_t *)cont_pkt->dseg_0_address; | 687 | cur_dsd = (uint32_t *)cont_pkt->dseg_0_address; |
689 | avail_dsds = 5; | 688 | avail_dsds = 5; |
690 | } | 689 | } |
@@ -2070,7 +2069,8 @@ qla2x00_ct_iocb(srb_t *sp, ms_iocb_entry_t *ct_iocb) | |||
2070 | * Five DSDs are available in the Cont. | 2069 | * Five DSDs are available in the Cont. |
2071 | * Type 1 IOCB. | 2070 | * Type 1 IOCB. |
2072 | */ | 2071 | */ |
2073 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha); | 2072 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, |
2073 | vha->hw->req_q_map[0]); | ||
2074 | cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; | 2074 | cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; |
2075 | avail_dsds = 5; | 2075 | avail_dsds = 5; |
2076 | cont_iocb_prsnt = 1; | 2076 | cont_iocb_prsnt = 1; |
@@ -2096,6 +2096,7 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) | |||
2096 | int index; | 2096 | int index; |
2097 | uint16_t tot_dsds; | 2097 | uint16_t tot_dsds; |
2098 | scsi_qla_host_t *vha = sp->fcport->vha; | 2098 | scsi_qla_host_t *vha = sp->fcport->vha; |
2099 | struct qla_hw_data *ha = vha->hw; | ||
2099 | struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job; | 2100 | struct fc_bsg_job *bsg_job = ((struct srb_ctx *)sp->ctx)->u.bsg_job; |
2100 | int loop_iterartion = 0; | 2101 | int loop_iterartion = 0; |
2101 | int cont_iocb_prsnt = 0; | 2102 | int cont_iocb_prsnt = 0; |
@@ -2141,7 +2142,8 @@ qla24xx_ct_iocb(srb_t *sp, struct ct_entry_24xx *ct_iocb) | |||
2141 | * Five DSDs are available in the Cont. | 2142 | * Five DSDs are available in the Cont. |
2142 | * Type 1 IOCB. | 2143 | * Type 1 IOCB. |
2143 | */ | 2144 | */ |
2144 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha); | 2145 | cont_pkt = qla2x00_prep_cont_type1_iocb(vha, |
2146 | ha->req_q_map[0]); | ||
2145 | cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; | 2147 | cur_dsd = (uint32_t *) cont_pkt->dseg_0_address; |
2146 | avail_dsds = 5; | 2148 | avail_dsds = 5; |
2147 | cont_iocb_prsnt = 1; | 2149 | cont_iocb_prsnt = 1; |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 2516adf1aeea..7b91b290ffd6 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1741,7 +1741,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
1741 | resid, scsi_bufflen(cp)); | 1741 | resid, scsi_bufflen(cp)); |
1742 | 1742 | ||
1743 | cp->result = DID_ERROR << 16 | lscsi_status; | 1743 | cp->result = DID_ERROR << 16 | lscsi_status; |
1744 | break; | 1744 | goto check_scsi_status; |
1745 | } | 1745 | } |
1746 | 1746 | ||
1747 | if (!lscsi_status && | 1747 | if (!lscsi_status && |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 3b3cec9f6ac2..82a33533ed26 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -79,8 +79,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
79 | mcp->mb[0] = MBS_LINK_DOWN_ERROR; | 79 | mcp->mb[0] = MBS_LINK_DOWN_ERROR; |
80 | ql_log(ql_log_warn, base_vha, 0x1004, | 80 | ql_log(ql_log_warn, base_vha, 0x1004, |
81 | "FW hung = %d.\n", ha->flags.isp82xx_fw_hung); | 81 | "FW hung = %d.\n", ha->flags.isp82xx_fw_hung); |
82 | rval = QLA_FUNCTION_FAILED; | 82 | return QLA_FUNCTION_TIMEOUT; |
83 | goto premature_exit; | ||
84 | } | 83 | } |
85 | 84 | ||
86 | /* | 85 | /* |
@@ -163,6 +162,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
163 | HINT_MBX_INT_PENDING) { | 162 | HINT_MBX_INT_PENDING) { |
164 | spin_unlock_irqrestore(&ha->hardware_lock, | 163 | spin_unlock_irqrestore(&ha->hardware_lock, |
165 | flags); | 164 | flags); |
165 | ha->flags.mbox_busy = 0; | ||
166 | ql_dbg(ql_dbg_mbx, base_vha, 0x1010, | 166 | ql_dbg(ql_dbg_mbx, base_vha, 0x1010, |
167 | "Pending mailbox timeout, exiting.\n"); | 167 | "Pending mailbox timeout, exiting.\n"); |
168 | rval = QLA_FUNCTION_TIMEOUT; | 168 | rval = QLA_FUNCTION_TIMEOUT; |
@@ -188,6 +188,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
188 | HINT_MBX_INT_PENDING) { | 188 | HINT_MBX_INT_PENDING) { |
189 | spin_unlock_irqrestore(&ha->hardware_lock, | 189 | spin_unlock_irqrestore(&ha->hardware_lock, |
190 | flags); | 190 | flags); |
191 | ha->flags.mbox_busy = 0; | ||
191 | ql_dbg(ql_dbg_mbx, base_vha, 0x1012, | 192 | ql_dbg(ql_dbg_mbx, base_vha, 0x1012, |
192 | "Pending mailbox timeout, exiting.\n"); | 193 | "Pending mailbox timeout, exiting.\n"); |
193 | rval = QLA_FUNCTION_TIMEOUT; | 194 | rval = QLA_FUNCTION_TIMEOUT; |
@@ -302,7 +303,15 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
302 | if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && | 303 | if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && |
303 | !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && | 304 | !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && |
304 | !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { | 305 | !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { |
305 | 306 | if (IS_QLA82XX(ha)) { | |
307 | ql_dbg(ql_dbg_mbx, vha, 0x112a, | ||
308 | "disabling pause transmit on port " | ||
309 | "0 & 1.\n"); | ||
310 | qla82xx_wr_32(ha, | ||
311 | QLA82XX_CRB_NIU + 0x98, | ||
312 | CRB_NIU_XG_PAUSE_CTL_P0| | ||
313 | CRB_NIU_XG_PAUSE_CTL_P1); | ||
314 | } | ||
306 | ql_log(ql_log_info, base_vha, 0x101c, | 315 | ql_log(ql_log_info, base_vha, 0x101c, |
307 | "Mailbox cmd timeout occured. " | 316 | "Mailbox cmd timeout occured. " |
308 | "Scheduling ISP abort eeh_busy=0x%x.\n", | 317 | "Scheduling ISP abort eeh_busy=0x%x.\n", |
@@ -318,7 +327,15 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) | |||
318 | if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && | 327 | if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) && |
319 | !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && | 328 | !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && |
320 | !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { | 329 | !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) { |
321 | 330 | if (IS_QLA82XX(ha)) { | |
331 | ql_dbg(ql_dbg_mbx, vha, 0x112b, | ||
332 | "disabling pause transmit on port " | ||
333 | "0 & 1.\n"); | ||
334 | qla82xx_wr_32(ha, | ||
335 | QLA82XX_CRB_NIU + 0x98, | ||
336 | CRB_NIU_XG_PAUSE_CTL_P0| | ||
337 | CRB_NIU_XG_PAUSE_CTL_P1); | ||
338 | } | ||
322 | ql_log(ql_log_info, base_vha, 0x101e, | 339 | ql_log(ql_log_info, base_vha, 0x101e, |
323 | "Mailbox cmd timeout occured. " | 340 | "Mailbox cmd timeout occured. " |
324 | "Scheduling ISP abort.\n"); | 341 | "Scheduling ISP abort.\n"); |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 94bded5ddce4..03554934b0a5 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
@@ -3817,6 +3817,20 @@ exit: | |||
3817 | return rval; | 3817 | return rval; |
3818 | } | 3818 | } |
3819 | 3819 | ||
3820 | void qla82xx_clear_pending_mbx(scsi_qla_host_t *vha) | ||
3821 | { | ||
3822 | struct qla_hw_data *ha = vha->hw; | ||
3823 | |||
3824 | if (ha->flags.mbox_busy) { | ||
3825 | ha->flags.mbox_int = 1; | ||
3826 | ha->flags.mbox_busy = 0; | ||
3827 | ql_log(ql_log_warn, vha, 0x6010, | ||
3828 | "Doing premature completion of mbx command.\n"); | ||
3829 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) | ||
3830 | complete(&ha->mbx_intr_comp); | ||
3831 | } | ||
3832 | } | ||
3833 | |||
3820 | void qla82xx_watchdog(scsi_qla_host_t *vha) | 3834 | void qla82xx_watchdog(scsi_qla_host_t *vha) |
3821 | { | 3835 | { |
3822 | uint32_t dev_state, halt_status; | 3836 | uint32_t dev_state, halt_status; |
@@ -3839,9 +3853,13 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) | |||
3839 | qla2xxx_wake_dpc(vha); | 3853 | qla2xxx_wake_dpc(vha); |
3840 | } else { | 3854 | } else { |
3841 | if (qla82xx_check_fw_alive(vha)) { | 3855 | if (qla82xx_check_fw_alive(vha)) { |
3856 | ql_dbg(ql_dbg_timer, vha, 0x6011, | ||
3857 | "disabling pause transmit on port 0 & 1.\n"); | ||
3858 | qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98, | ||
3859 | CRB_NIU_XG_PAUSE_CTL_P0|CRB_NIU_XG_PAUSE_CTL_P1); | ||
3842 | halt_status = qla82xx_rd_32(ha, | 3860 | halt_status = qla82xx_rd_32(ha, |
3843 | QLA82XX_PEG_HALT_STATUS1); | 3861 | QLA82XX_PEG_HALT_STATUS1); |
3844 | ql_dbg(ql_dbg_timer, vha, 0x6005, | 3862 | ql_log(ql_log_info, vha, 0x6005, |
3845 | "dumping hw/fw registers:.\n " | 3863 | "dumping hw/fw registers:.\n " |
3846 | " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,.\n " | 3864 | " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,.\n " |
3847 | " PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,.\n " | 3865 | " PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,.\n " |
@@ -3858,6 +3876,11 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) | |||
3858 | QLA82XX_CRB_PEG_NET_3 + 0x3c), | 3876 | QLA82XX_CRB_PEG_NET_3 + 0x3c), |
3859 | qla82xx_rd_32(ha, | 3877 | qla82xx_rd_32(ha, |
3860 | QLA82XX_CRB_PEG_NET_4 + 0x3c)); | 3878 | QLA82XX_CRB_PEG_NET_4 + 0x3c)); |
3879 | if (LSW(MSB(halt_status)) == 0x67) | ||
3880 | ql_log(ql_log_warn, vha, 0xb052, | ||
3881 | "Firmware aborted with " | ||
3882 | "error code 0x00006700. Device is " | ||
3883 | "being reset.\n"); | ||
3861 | if (halt_status & HALT_STATUS_UNRECOVERABLE) { | 3884 | if (halt_status & HALT_STATUS_UNRECOVERABLE) { |
3862 | set_bit(ISP_UNRECOVERABLE, | 3885 | set_bit(ISP_UNRECOVERABLE, |
3863 | &vha->dpc_flags); | 3886 | &vha->dpc_flags); |
@@ -3869,16 +3892,8 @@ void qla82xx_watchdog(scsi_qla_host_t *vha) | |||
3869 | } | 3892 | } |
3870 | qla2xxx_wake_dpc(vha); | 3893 | qla2xxx_wake_dpc(vha); |
3871 | ha->flags.isp82xx_fw_hung = 1; | 3894 | ha->flags.isp82xx_fw_hung = 1; |
3872 | if (ha->flags.mbox_busy) { | 3895 | ql_log(ql_log_warn, vha, 0x6007, "Firmware hung.\n"); |
3873 | ha->flags.mbox_int = 1; | 3896 | qla82xx_clear_pending_mbx(vha); |
3874 | ql_log(ql_log_warn, vha, 0x6007, | ||
3875 | "Due to FW hung, doing " | ||
3876 | "premature completion of mbx " | ||
3877 | "command.\n"); | ||
3878 | if (test_bit(MBX_INTR_WAIT, | ||
3879 | &ha->mbx_cmd_flags)) | ||
3880 | complete(&ha->mbx_intr_comp); | ||
3881 | } | ||
3882 | } | 3897 | } |
3883 | } | 3898 | } |
3884 | } | 3899 | } |
@@ -4073,10 +4088,7 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha) | |||
4073 | msleep(1000); | 4088 | msleep(1000); |
4074 | if (qla82xx_check_fw_alive(vha)) { | 4089 | if (qla82xx_check_fw_alive(vha)) { |
4075 | ha->flags.isp82xx_fw_hung = 1; | 4090 | ha->flags.isp82xx_fw_hung = 1; |
4076 | if (ha->flags.mbox_busy) { | 4091 | qla82xx_clear_pending_mbx(vha); |
4077 | ha->flags.mbox_int = 1; | ||
4078 | complete(&ha->mbx_intr_comp); | ||
4079 | } | ||
4080 | break; | 4092 | break; |
4081 | } | 4093 | } |
4082 | } | 4094 | } |
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h index 57820c199bc2..57a226be339a 100644 --- a/drivers/scsi/qla2xxx/qla_nx.h +++ b/drivers/scsi/qla2xxx/qla_nx.h | |||
@@ -1173,4 +1173,8 @@ struct qla82xx_md_entry_queue { | |||
1173 | 1173 | ||
1174 | static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, 0x410000AC, | 1174 | static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, 0x410000AC, |
1175 | 0x410000B8, 0x410000BC }; | 1175 | 0x410000B8, 0x410000BC }; |
1176 | |||
1177 | #define CRB_NIU_XG_PAUSE_CTL_P0 0x1 | ||
1178 | #define CRB_NIU_XG_PAUSE_CTL_P1 0x8 | ||
1179 | |||
1176 | #endif | 1180 | #endif |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index fd14c7bfc626..f9e5b85e84d8 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -201,12 +201,12 @@ MODULE_PARM_DESC(ql2xmdcapmask, | |||
201 | "Set the Minidump driver capture mask level. " | 201 | "Set the Minidump driver capture mask level. " |
202 | "Default is 0x7F - Can be set to 0x3, 0x7, 0xF, 0x1F, 0x7F."); | 202 | "Default is 0x7F - Can be set to 0x3, 0x7, 0xF, 0x1F, 0x7F."); |
203 | 203 | ||
204 | int ql2xmdenable; | 204 | int ql2xmdenable = 1; |
205 | module_param(ql2xmdenable, int, S_IRUGO); | 205 | module_param(ql2xmdenable, int, S_IRUGO); |
206 | MODULE_PARM_DESC(ql2xmdenable, | 206 | MODULE_PARM_DESC(ql2xmdenable, |
207 | "Enable/disable MiniDump. " | 207 | "Enable/disable MiniDump. " |
208 | "0 (Default) - MiniDump disabled. " | 208 | "0 - MiniDump disabled. " |
209 | "1 - MiniDump enabled."); | 209 | "1 (Default) - MiniDump enabled."); |
210 | 210 | ||
211 | /* | 211 | /* |
212 | * SCSI host template entry points | 212 | * SCSI host template entry points |
@@ -423,6 +423,7 @@ fail2: | |||
423 | qla25xx_delete_queues(vha); | 423 | qla25xx_delete_queues(vha); |
424 | destroy_workqueue(ha->wq); | 424 | destroy_workqueue(ha->wq); |
425 | ha->wq = NULL; | 425 | ha->wq = NULL; |
426 | vha->req = ha->req_q_map[0]; | ||
426 | fail: | 427 | fail: |
427 | ha->mqenable = 0; | 428 | ha->mqenable = 0; |
428 | kfree(ha->req_q_map); | 429 | kfree(ha->req_q_map); |
@@ -814,49 +815,6 @@ qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha) | |||
814 | return return_status; | 815 | return return_status; |
815 | } | 816 | } |
816 | 817 | ||
817 | /* | ||
818 | * qla2x00_wait_for_loop_ready | ||
819 | * Wait for MAX_LOOP_TIMEOUT(5 min) value for loop | ||
820 | * to be in LOOP_READY state. | ||
821 | * Input: | ||
822 | * ha - pointer to host adapter structure | ||
823 | * | ||
824 | * Note: | ||
825 | * Does context switching-Release SPIN_LOCK | ||
826 | * (if any) before calling this routine. | ||
827 | * | ||
828 | * | ||
829 | * Return: | ||
830 | * Success (LOOP_READY) : 0 | ||
831 | * Failed (LOOP_NOT_READY) : 1 | ||
832 | */ | ||
833 | static inline int | ||
834 | qla2x00_wait_for_loop_ready(scsi_qla_host_t *vha) | ||
835 | { | ||
836 | int return_status = QLA_SUCCESS; | ||
837 | unsigned long loop_timeout ; | ||
838 | struct qla_hw_data *ha = vha->hw; | ||
839 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | ||
840 | |||
841 | /* wait for 5 min at the max for loop to be ready */ | ||
842 | loop_timeout = jiffies + (MAX_LOOP_TIMEOUT * HZ); | ||
843 | |||
844 | while ((!atomic_read(&base_vha->loop_down_timer) && | ||
845 | atomic_read(&base_vha->loop_state) == LOOP_DOWN) || | ||
846 | atomic_read(&base_vha->loop_state) != LOOP_READY) { | ||
847 | if (atomic_read(&base_vha->loop_state) == LOOP_DEAD) { | ||
848 | return_status = QLA_FUNCTION_FAILED; | ||
849 | break; | ||
850 | } | ||
851 | msleep(1000); | ||
852 | if (time_after_eq(jiffies, loop_timeout)) { | ||
853 | return_status = QLA_FUNCTION_FAILED; | ||
854 | break; | ||
855 | } | ||
856 | } | ||
857 | return (return_status); | ||
858 | } | ||
859 | |||
860 | static void | 818 | static void |
861 | sp_get(struct srb *sp) | 819 | sp_get(struct srb *sp) |
862 | { | 820 | { |
@@ -1035,12 +993,6 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, | |||
1035 | "Wait for hba online failed for cmd=%p.\n", cmd); | 993 | "Wait for hba online failed for cmd=%p.\n", cmd); |
1036 | goto eh_reset_failed; | 994 | goto eh_reset_failed; |
1037 | } | 995 | } |
1038 | err = 1; | ||
1039 | if (qla2x00_wait_for_loop_ready(vha) != QLA_SUCCESS) { | ||
1040 | ql_log(ql_log_warn, vha, 0x800b, | ||
1041 | "Wait for loop ready failed for cmd=%p.\n", cmd); | ||
1042 | goto eh_reset_failed; | ||
1043 | } | ||
1044 | err = 2; | 996 | err = 2; |
1045 | if (do_reset(fcport, cmd->device->lun, cmd->request->cpu + 1) | 997 | if (do_reset(fcport, cmd->device->lun, cmd->request->cpu + 1) |
1046 | != QLA_SUCCESS) { | 998 | != QLA_SUCCESS) { |
@@ -1137,10 +1089,9 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | |||
1137 | goto eh_bus_reset_done; | 1089 | goto eh_bus_reset_done; |
1138 | } | 1090 | } |
1139 | 1091 | ||
1140 | if (qla2x00_wait_for_loop_ready(vha) == QLA_SUCCESS) { | 1092 | if (qla2x00_loop_reset(vha) == QLA_SUCCESS) |
1141 | if (qla2x00_loop_reset(vha) == QLA_SUCCESS) | 1093 | ret = SUCCESS; |
1142 | ret = SUCCESS; | 1094 | |
1143 | } | ||
1144 | if (ret == FAILED) | 1095 | if (ret == FAILED) |
1145 | goto eh_bus_reset_done; | 1096 | goto eh_bus_reset_done; |
1146 | 1097 | ||
@@ -1206,15 +1157,6 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
1206 | if (qla2x00_wait_for_reset_ready(vha) != QLA_SUCCESS) | 1157 | if (qla2x00_wait_for_reset_ready(vha) != QLA_SUCCESS) |
1207 | goto eh_host_reset_lock; | 1158 | goto eh_host_reset_lock; |
1208 | 1159 | ||
1209 | /* | ||
1210 | * Fixme-may be dpc thread is active and processing | ||
1211 | * loop_resync,so wait a while for it to | ||
1212 | * be completed and then issue big hammer.Otherwise | ||
1213 | * it may cause I/O failure as big hammer marks the | ||
1214 | * devices as lost kicking of the port_down_timer | ||
1215 | * while dpc is stuck for the mailbox to complete. | ||
1216 | */ | ||
1217 | qla2x00_wait_for_loop_ready(vha); | ||
1218 | if (vha != base_vha) { | 1160 | if (vha != base_vha) { |
1219 | if (qla2x00_vp_abort_isp(vha)) | 1161 | if (qla2x00_vp_abort_isp(vha)) |
1220 | goto eh_host_reset_lock; | 1162 | goto eh_host_reset_lock; |
@@ -1297,16 +1239,13 @@ qla2x00_loop_reset(scsi_qla_host_t *vha) | |||
1297 | atomic_set(&vha->loop_state, LOOP_DOWN); | 1239 | atomic_set(&vha->loop_state, LOOP_DOWN); |
1298 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); | 1240 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
1299 | qla2x00_mark_all_devices_lost(vha, 0); | 1241 | qla2x00_mark_all_devices_lost(vha, 0); |
1300 | qla2x00_wait_for_loop_ready(vha); | ||
1301 | } | 1242 | } |
1302 | 1243 | ||
1303 | if (ha->flags.enable_lip_reset) { | 1244 | if (ha->flags.enable_lip_reset) { |
1304 | ret = qla2x00_lip_reset(vha); | 1245 | ret = qla2x00_lip_reset(vha); |
1305 | if (ret != QLA_SUCCESS) { | 1246 | if (ret != QLA_SUCCESS) |
1306 | ql_dbg(ql_dbg_taskm, vha, 0x802e, | 1247 | ql_dbg(ql_dbg_taskm, vha, 0x802e, |
1307 | "lip_reset failed (%d).\n", ret); | 1248 | "lip_reset failed (%d).\n", ret); |
1308 | } else | ||
1309 | qla2x00_wait_for_loop_ready(vha); | ||
1310 | } | 1249 | } |
1311 | 1250 | ||
1312 | /* Issue marker command only when we are going to start the I/O */ | 1251 | /* Issue marker command only when we are going to start the I/O */ |
@@ -4070,13 +4009,8 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | |||
4070 | /* For ISP82XX complete any pending mailbox cmd */ | 4009 | /* For ISP82XX complete any pending mailbox cmd */ |
4071 | if (IS_QLA82XX(ha)) { | 4010 | if (IS_QLA82XX(ha)) { |
4072 | ha->flags.isp82xx_fw_hung = 1; | 4011 | ha->flags.isp82xx_fw_hung = 1; |
4073 | if (ha->flags.mbox_busy) { | 4012 | ql_dbg(ql_dbg_aer, vha, 0x9001, "Pci channel io frozen\n"); |
4074 | ha->flags.mbox_int = 1; | 4013 | qla82xx_clear_pending_mbx(vha); |
4075 | ql_dbg(ql_dbg_aer, vha, 0x9001, | ||
4076 | "Due to pci channel io frozen, doing premature " | ||
4077 | "completion of mbx command.\n"); | ||
4078 | complete(&ha->mbx_intr_comp); | ||
4079 | } | ||
4080 | } | 4014 | } |
4081 | qla2x00_free_irqs(vha); | 4015 | qla2x00_free_irqs(vha); |
4082 | pci_disable_device(pdev); | 4016 | pci_disable_device(pdev); |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 13b6357c1fa2..23f33a6d52d7 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.03.07.07-k" | 10 | #define QLA2XXX_VERSION "8.03.07.12-k" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 3 | 13 | #define QLA_DRIVER_MINOR_VER 3 |
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index ace637bf254e..fd5edc6e166d 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
@@ -147,7 +147,7 @@ | |||
147 | #define ISCSI_ALIAS_SIZE 32 /* ISCSI Alias name size */ | 147 | #define ISCSI_ALIAS_SIZE 32 /* ISCSI Alias name size */ |
148 | #define ISCSI_NAME_SIZE 0xE0 /* ISCSI Name size */ | 148 | #define ISCSI_NAME_SIZE 0xE0 /* ISCSI Name size */ |
149 | 149 | ||
150 | #define QL4_SESS_RECOVERY_TMO 30 /* iSCSI session */ | 150 | #define QL4_SESS_RECOVERY_TMO 120 /* iSCSI session */ |
151 | /* recovery timeout */ | 151 | /* recovery timeout */ |
152 | 152 | ||
153 | #define LSDW(x) ((u32)((u64)(x))) | 153 | #define LSDW(x) ((u32)((u64)(x))) |
@@ -173,6 +173,8 @@ | |||
173 | #define ISNS_DEREG_TOV 5 | 173 | #define ISNS_DEREG_TOV 5 |
174 | #define HBA_ONLINE_TOV 30 | 174 | #define HBA_ONLINE_TOV 30 |
175 | #define DISABLE_ACB_TOV 30 | 175 | #define DISABLE_ACB_TOV 30 |
176 | #define IP_CONFIG_TOV 30 | ||
177 | #define LOGIN_TOV 12 | ||
176 | 178 | ||
177 | #define MAX_RESET_HA_RETRIES 2 | 179 | #define MAX_RESET_HA_RETRIES 2 |
178 | 180 | ||
@@ -240,6 +242,45 @@ struct ddb_entry { | |||
240 | 242 | ||
241 | uint16_t fw_ddb_index; /* DDB firmware index */ | 243 | uint16_t fw_ddb_index; /* DDB firmware index */ |
242 | uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */ | 244 | uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */ |
245 | uint16_t ddb_type; | ||
246 | #define FLASH_DDB 0x01 | ||
247 | |||
248 | struct dev_db_entry fw_ddb_entry; | ||
249 | int (*unblock_sess)(struct iscsi_cls_session *cls_session); | ||
250 | int (*ddb_change)(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | ||
251 | struct ddb_entry *ddb_entry, uint32_t state); | ||
252 | |||
253 | /* Driver Re-login */ | ||
254 | unsigned long flags; /* DDB Flags */ | ||
255 | uint16_t default_relogin_timeout; /* Max time to wait for | ||
256 | * relogin to complete */ | ||
257 | atomic_t retry_relogin_timer; /* Min Time between relogins | ||
258 | * (4000 only) */ | ||
259 | atomic_t relogin_timer; /* Max Time to wait for | ||
260 | * relogin to complete */ | ||
261 | atomic_t relogin_retry_count; /* Num of times relogin has been | ||
262 | * retried */ | ||
263 | uint32_t default_time2wait; /* Default Min time between | ||
264 | * relogins (+aens) */ | ||
265 | |||
266 | }; | ||
267 | |||
268 | struct qla_ddb_index { | ||
269 | struct list_head list; | ||
270 | uint16_t fw_ddb_idx; | ||
271 | struct dev_db_entry fw_ddb; | ||
272 | }; | ||
273 | |||
274 | #define DDB_IPADDR_LEN 64 | ||
275 | |||
276 | struct ql4_tuple_ddb { | ||
277 | int port; | ||
278 | int tpgt; | ||
279 | char ip_addr[DDB_IPADDR_LEN]; | ||
280 | char iscsi_name[ISCSI_NAME_SIZE]; | ||
281 | uint16_t options; | ||
282 | #define DDB_OPT_IPV6 0x0e0e | ||
283 | #define DDB_OPT_IPV4 0x0f0f | ||
243 | }; | 284 | }; |
244 | 285 | ||
245 | /* | 286 | /* |
@@ -411,7 +452,7 @@ struct scsi_qla_host { | |||
411 | #define AF_FW_RECOVERY 19 /* 0x00080000 */ | 452 | #define AF_FW_RECOVERY 19 /* 0x00080000 */ |
412 | #define AF_EEH_BUSY 20 /* 0x00100000 */ | 453 | #define AF_EEH_BUSY 20 /* 0x00100000 */ |
413 | #define AF_PCI_CHANNEL_IO_PERM_FAILURE 21 /* 0x00200000 */ | 454 | #define AF_PCI_CHANNEL_IO_PERM_FAILURE 21 /* 0x00200000 */ |
414 | 455 | #define AF_BUILD_DDB_LIST 22 /* 0x00400000 */ | |
415 | unsigned long dpc_flags; | 456 | unsigned long dpc_flags; |
416 | 457 | ||
417 | #define DPC_RESET_HA 1 /* 0x00000002 */ | 458 | #define DPC_RESET_HA 1 /* 0x00000002 */ |
@@ -604,6 +645,7 @@ struct scsi_qla_host { | |||
604 | uint16_t bootload_minor; | 645 | uint16_t bootload_minor; |
605 | uint16_t bootload_patch; | 646 | uint16_t bootload_patch; |
606 | uint16_t bootload_build; | 647 | uint16_t bootload_build; |
648 | uint16_t def_timeout; /* Default login timeout */ | ||
607 | 649 | ||
608 | uint32_t flash_state; | 650 | uint32_t flash_state; |
609 | #define QLFLASH_WAITING 0 | 651 | #define QLFLASH_WAITING 0 |
@@ -623,6 +665,11 @@ struct scsi_qla_host { | |||
623 | uint16_t iscsi_pci_func_cnt; | 665 | uint16_t iscsi_pci_func_cnt; |
624 | uint8_t model_name[16]; | 666 | uint8_t model_name[16]; |
625 | struct completion disable_acb_comp; | 667 | struct completion disable_acb_comp; |
668 | struct dma_pool *fw_ddb_dma_pool; | ||
669 | #define DDB_DMA_BLOCK_SIZE 512 | ||
670 | uint16_t pri_ddb_idx; | ||
671 | uint16_t sec_ddb_idx; | ||
672 | int is_reset; | ||
626 | }; | 673 | }; |
627 | 674 | ||
628 | struct ql4_task_data { | 675 | struct ql4_task_data { |
@@ -835,6 +882,10 @@ static inline int ql4xxx_reset_active(struct scsi_qla_host *ha) | |||
835 | /*---------------------------------------------------------------------------*/ | 882 | /*---------------------------------------------------------------------------*/ |
836 | 883 | ||
837 | /* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */ | 884 | /* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */ |
885 | |||
886 | #define INIT_ADAPTER 0 | ||
887 | #define RESET_ADAPTER 1 | ||
888 | |||
838 | #define PRESERVE_DDB_LIST 0 | 889 | #define PRESERVE_DDB_LIST 0 |
839 | #define REBUILD_DDB_LIST 1 | 890 | #define REBUILD_DDB_LIST 1 |
840 | 891 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index cbd5a20dbbd1..4ac07f882521 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define MAX_PRST_DEV_DB_ENTRIES 64 | 12 | #define MAX_PRST_DEV_DB_ENTRIES 64 |
13 | #define MIN_DISC_DEV_DB_ENTRY MAX_PRST_DEV_DB_ENTRIES | 13 | #define MIN_DISC_DEV_DB_ENTRY MAX_PRST_DEV_DB_ENTRIES |
14 | #define MAX_DEV_DB_ENTRIES 512 | 14 | #define MAX_DEV_DB_ENTRIES 512 |
15 | #define MAX_DEV_DB_ENTRIES_40XX 256 | ||
15 | 16 | ||
16 | /************************************************************************* | 17 | /************************************************************************* |
17 | * | 18 | * |
@@ -604,6 +605,13 @@ struct addr_ctrl_blk { | |||
604 | uint8_t res14[140]; /* 274-2FF */ | 605 | uint8_t res14[140]; /* 274-2FF */ |
605 | }; | 606 | }; |
606 | 607 | ||
608 | #define IP_ADDR_COUNT 4 /* Total 4 IP address supported in one interface | ||
609 | * One IPv4, one IPv6 link local and 2 IPv6 | ||
610 | */ | ||
611 | |||
612 | #define IP_STATE_MASK 0x0F000000 | ||
613 | #define IP_STATE_SHIFT 24 | ||
614 | |||
607 | struct init_fw_ctrl_blk { | 615 | struct init_fw_ctrl_blk { |
608 | struct addr_ctrl_blk pri; | 616 | struct addr_ctrl_blk pri; |
609 | /* struct addr_ctrl_blk sec;*/ | 617 | /* struct addr_ctrl_blk sec;*/ |
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index 160db9d5ea21..d0dd4b330206 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -13,7 +13,7 @@ struct iscsi_cls_conn; | |||
13 | int qla4xxx_hw_reset(struct scsi_qla_host *ha); | 13 | int qla4xxx_hw_reset(struct scsi_qla_host *ha); |
14 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a); | 14 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a); |
15 | int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb *srb); | 15 | int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb *srb); |
16 | int qla4xxx_initialize_adapter(struct scsi_qla_host *ha); | 16 | int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset); |
17 | int qla4xxx_soft_reset(struct scsi_qla_host *ha); | 17 | int qla4xxx_soft_reset(struct scsi_qla_host *ha); |
18 | irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id); | 18 | irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id); |
19 | 19 | ||
@@ -153,10 +153,13 @@ int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | |||
153 | uint32_t *mbx_sts); | 153 | uint32_t *mbx_sts); |
154 | int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t fw_ddb_index); | 154 | int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t fw_ddb_index); |
155 | int qla4xxx_send_passthru0(struct iscsi_task *task); | 155 | int qla4xxx_send_passthru0(struct iscsi_task *task); |
156 | void qla4xxx_free_ddb_index(struct scsi_qla_host *ha); | ||
156 | int qla4xxx_get_mgmt_data(struct scsi_qla_host *ha, uint16_t fw_ddb_index, | 157 | int qla4xxx_get_mgmt_data(struct scsi_qla_host *ha, uint16_t fw_ddb_index, |
157 | uint16_t stats_size, dma_addr_t stats_dma); | 158 | uint16_t stats_size, dma_addr_t stats_dma); |
158 | void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, | 159 | void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, |
159 | struct ddb_entry *ddb_entry); | 160 | struct ddb_entry *ddb_entry); |
161 | void qla4xxx_update_session_conn_fwddb_param(struct scsi_qla_host *ha, | ||
162 | struct ddb_entry *ddb_entry); | ||
160 | int qla4xxx_bootdb_by_index(struct scsi_qla_host *ha, | 163 | int qla4xxx_bootdb_by_index(struct scsi_qla_host *ha, |
161 | struct dev_db_entry *fw_ddb_entry, | 164 | struct dev_db_entry *fw_ddb_entry, |
162 | dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index); | 165 | dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index); |
@@ -169,11 +172,22 @@ int qla4xxx_set_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma, | |||
169 | int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha, | 172 | int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha, |
170 | uint32_t region, uint32_t field0, | 173 | uint32_t region, uint32_t field0, |
171 | uint32_t field1); | 174 | uint32_t field1); |
175 | int qla4xxx_get_ddb_index(struct scsi_qla_host *ha, uint16_t *ddb_index); | ||
176 | void qla4xxx_login_flash_ddb(struct iscsi_cls_session *cls_session); | ||
177 | int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session); | ||
178 | int qla4xxx_unblock_flash_ddb(struct iscsi_cls_session *cls_session); | ||
179 | int qla4xxx_flash_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | ||
180 | struct ddb_entry *ddb_entry, uint32_t state); | ||
181 | int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | ||
182 | struct ddb_entry *ddb_entry, uint32_t state); | ||
183 | void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset); | ||
172 | 184 | ||
173 | /* BSG Functions */ | 185 | /* BSG Functions */ |
174 | int qla4xxx_bsg_request(struct bsg_job *bsg_job); | 186 | int qla4xxx_bsg_request(struct bsg_job *bsg_job); |
175 | int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job); | 187 | int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job); |
176 | 188 | ||
189 | void qla4xxx_arm_relogin_timer(struct ddb_entry *ddb_entry); | ||
190 | |||
177 | extern int ql4xextended_error_logging; | 191 | extern int ql4xextended_error_logging; |
178 | extern int ql4xdontresethba; | 192 | extern int ql4xdontresethba; |
179 | extern int ql4xenablemsix; | 193 | extern int ql4xenablemsix; |
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 3075fbaef553..1bdfa8120ac8 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -773,22 +773,24 @@ int qla4xxx_start_firmware(struct scsi_qla_host *ha) | |||
773 | * be freed so that when login happens from user space there are free DDB | 773 | * be freed so that when login happens from user space there are free DDB |
774 | * indices available. | 774 | * indices available. |
775 | **/ | 775 | **/ |
776 | static void qla4xxx_free_ddb_index(struct scsi_qla_host *ha) | 776 | void qla4xxx_free_ddb_index(struct scsi_qla_host *ha) |
777 | { | 777 | { |
778 | int max_ddbs; | 778 | int max_ddbs; |
779 | int ret; | 779 | int ret; |
780 | uint32_t idx = 0, next_idx = 0; | 780 | uint32_t idx = 0, next_idx = 0; |
781 | uint32_t state = 0, conn_err = 0; | 781 | uint32_t state = 0, conn_err = 0; |
782 | 782 | ||
783 | max_ddbs = is_qla40XX(ha) ? MAX_PRST_DEV_DB_ENTRIES : | 783 | max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX : |
784 | MAX_DEV_DB_ENTRIES; | 784 | MAX_DEV_DB_ENTRIES; |
785 | 785 | ||
786 | for (idx = 0; idx < max_ddbs; idx = next_idx) { | 786 | for (idx = 0; idx < max_ddbs; idx = next_idx) { |
787 | ret = qla4xxx_get_fwddb_entry(ha, idx, NULL, 0, NULL, | 787 | ret = qla4xxx_get_fwddb_entry(ha, idx, NULL, 0, NULL, |
788 | &next_idx, &state, &conn_err, | 788 | &next_idx, &state, &conn_err, |
789 | NULL, NULL); | 789 | NULL, NULL); |
790 | if (ret == QLA_ERROR) | 790 | if (ret == QLA_ERROR) { |
791 | next_idx++; | ||
791 | continue; | 792 | continue; |
793 | } | ||
792 | if (state == DDB_DS_NO_CONNECTION_ACTIVE || | 794 | if (state == DDB_DS_NO_CONNECTION_ACTIVE || |
793 | state == DDB_DS_SESSION_FAILED) { | 795 | state == DDB_DS_SESSION_FAILED) { |
794 | DEBUG2(ql4_printk(KERN_INFO, ha, | 796 | DEBUG2(ql4_printk(KERN_INFO, ha, |
@@ -804,7 +806,6 @@ static void qla4xxx_free_ddb_index(struct scsi_qla_host *ha) | |||
804 | } | 806 | } |
805 | } | 807 | } |
806 | 808 | ||
807 | |||
808 | /** | 809 | /** |
809 | * qla4xxx_initialize_adapter - initiailizes hba | 810 | * qla4xxx_initialize_adapter - initiailizes hba |
810 | * @ha: Pointer to host adapter structure. | 811 | * @ha: Pointer to host adapter structure. |
@@ -812,7 +813,7 @@ static void qla4xxx_free_ddb_index(struct scsi_qla_host *ha) | |||
812 | * This routine parforms all of the steps necessary to initialize the adapter. | 813 | * This routine parforms all of the steps necessary to initialize the adapter. |
813 | * | 814 | * |
814 | **/ | 815 | **/ |
815 | int qla4xxx_initialize_adapter(struct scsi_qla_host *ha) | 816 | int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset) |
816 | { | 817 | { |
817 | int status = QLA_ERROR; | 818 | int status = QLA_ERROR; |
818 | 819 | ||
@@ -840,7 +841,8 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha) | |||
840 | if (status == QLA_ERROR) | 841 | if (status == QLA_ERROR) |
841 | goto exit_init_hba; | 842 | goto exit_init_hba; |
842 | 843 | ||
843 | qla4xxx_free_ddb_index(ha); | 844 | if (is_reset == RESET_ADAPTER) |
845 | qla4xxx_build_ddb_list(ha, is_reset); | ||
844 | 846 | ||
845 | set_bit(AF_ONLINE, &ha->flags); | 847 | set_bit(AF_ONLINE, &ha->flags); |
846 | exit_init_hba: | 848 | exit_init_hba: |
@@ -855,38 +857,12 @@ exit_init_hba: | |||
855 | return status; | 857 | return status; |
856 | } | 858 | } |
857 | 859 | ||
858 | /** | 860 | int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, |
859 | * qla4xxx_process_ddb_changed - process ddb state change | 861 | struct ddb_entry *ddb_entry, uint32_t state) |
860 | * @ha - Pointer to host adapter structure. | ||
861 | * @fw_ddb_index - Firmware's device database index | ||
862 | * @state - Device state | ||
863 | * | ||
864 | * This routine processes a Decive Database Changed AEN Event. | ||
865 | **/ | ||
866 | int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | ||
867 | uint32_t state, uint32_t conn_err) | ||
868 | { | 862 | { |
869 | struct ddb_entry * ddb_entry; | ||
870 | uint32_t old_fw_ddb_device_state; | 863 | uint32_t old_fw_ddb_device_state; |
871 | int status = QLA_ERROR; | 864 | int status = QLA_ERROR; |
872 | 865 | ||
873 | /* check for out of range index */ | ||
874 | if (fw_ddb_index >= MAX_DDB_ENTRIES) | ||
875 | goto exit_ddb_event; | ||
876 | |||
877 | /* Get the corresponging ddb entry */ | ||
878 | ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, fw_ddb_index); | ||
879 | /* Device does not currently exist in our database. */ | ||
880 | if (ddb_entry == NULL) { | ||
881 | ql4_printk(KERN_ERR, ha, "%s: No ddb_entry at FW index [%d]\n", | ||
882 | __func__, fw_ddb_index); | ||
883 | |||
884 | if (state == DDB_DS_NO_CONNECTION_ACTIVE) | ||
885 | clear_bit(fw_ddb_index, ha->ddb_idx_map); | ||
886 | |||
887 | goto exit_ddb_event; | ||
888 | } | ||
889 | |||
890 | old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state; | 866 | old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state; |
891 | DEBUG2(ql4_printk(KERN_INFO, ha, | 867 | DEBUG2(ql4_printk(KERN_INFO, ha, |
892 | "%s: DDB - old state = 0x%x, new state = 0x%x for " | 868 | "%s: DDB - old state = 0x%x, new state = 0x%x for " |
@@ -900,9 +876,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | |||
900 | switch (state) { | 876 | switch (state) { |
901 | case DDB_DS_SESSION_ACTIVE: | 877 | case DDB_DS_SESSION_ACTIVE: |
902 | case DDB_DS_DISCOVERY: | 878 | case DDB_DS_DISCOVERY: |
903 | iscsi_conn_start(ddb_entry->conn); | 879 | ddb_entry->unblock_sess(ddb_entry->sess); |
904 | iscsi_conn_login_event(ddb_entry->conn, | ||
905 | ISCSI_CONN_STATE_LOGGED_IN); | ||
906 | qla4xxx_update_session_conn_param(ha, ddb_entry); | 880 | qla4xxx_update_session_conn_param(ha, ddb_entry); |
907 | status = QLA_SUCCESS; | 881 | status = QLA_SUCCESS; |
908 | break; | 882 | break; |
@@ -936,9 +910,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | |||
936 | switch (state) { | 910 | switch (state) { |
937 | case DDB_DS_SESSION_ACTIVE: | 911 | case DDB_DS_SESSION_ACTIVE: |
938 | case DDB_DS_DISCOVERY: | 912 | case DDB_DS_DISCOVERY: |
939 | iscsi_conn_start(ddb_entry->conn); | 913 | ddb_entry->unblock_sess(ddb_entry->sess); |
940 | iscsi_conn_login_event(ddb_entry->conn, | ||
941 | ISCSI_CONN_STATE_LOGGED_IN); | ||
942 | qla4xxx_update_session_conn_param(ha, ddb_entry); | 914 | qla4xxx_update_session_conn_param(ha, ddb_entry); |
943 | status = QLA_SUCCESS; | 915 | status = QLA_SUCCESS; |
944 | break; | 916 | break; |
@@ -954,7 +926,198 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | |||
954 | __func__)); | 926 | __func__)); |
955 | break; | 927 | break; |
956 | } | 928 | } |
929 | return status; | ||
930 | } | ||
931 | |||
932 | void qla4xxx_arm_relogin_timer(struct ddb_entry *ddb_entry) | ||
933 | { | ||
934 | /* | ||
935 | * This triggers a relogin. After the relogin_timer | ||
936 | * expires, the relogin gets scheduled. We must wait a | ||
937 | * minimum amount of time since receiving an 0x8014 AEN | ||
938 | * with failed device_state or a logout response before | ||
939 | * we can issue another relogin. | ||
940 | * | ||
941 | * Firmware pads this timeout: (time2wait +1). | ||
942 | * Driver retry to login should be longer than F/W. | ||
943 | * Otherwise F/W will fail | ||
944 | * set_ddb() mbx cmd with 0x4005 since it still | ||
945 | * counting down its time2wait. | ||
946 | */ | ||
947 | atomic_set(&ddb_entry->relogin_timer, 0); | ||
948 | atomic_set(&ddb_entry->retry_relogin_timer, | ||
949 | ddb_entry->default_time2wait + 4); | ||
950 | |||
951 | } | ||
952 | |||
953 | int qla4xxx_flash_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | ||
954 | struct ddb_entry *ddb_entry, uint32_t state) | ||
955 | { | ||
956 | uint32_t old_fw_ddb_device_state; | ||
957 | int status = QLA_ERROR; | ||
958 | |||
959 | old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state; | ||
960 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
961 | "%s: DDB - old state = 0x%x, new state = 0x%x for " | ||
962 | "index [%d]\n", __func__, | ||
963 | ddb_entry->fw_ddb_device_state, state, fw_ddb_index)); | ||
964 | |||
965 | ddb_entry->fw_ddb_device_state = state; | ||
966 | |||
967 | switch (old_fw_ddb_device_state) { | ||
968 | case DDB_DS_LOGIN_IN_PROCESS: | ||
969 | case DDB_DS_NO_CONNECTION_ACTIVE: | ||
970 | switch (state) { | ||
971 | case DDB_DS_SESSION_ACTIVE: | ||
972 | ddb_entry->unblock_sess(ddb_entry->sess); | ||
973 | qla4xxx_update_session_conn_fwddb_param(ha, ddb_entry); | ||
974 | status = QLA_SUCCESS; | ||
975 | break; | ||
976 | case DDB_DS_SESSION_FAILED: | ||
977 | iscsi_block_session(ddb_entry->sess); | ||
978 | if (!test_bit(DF_RELOGIN, &ddb_entry->flags)) | ||
979 | qla4xxx_arm_relogin_timer(ddb_entry); | ||
980 | status = QLA_SUCCESS; | ||
981 | break; | ||
982 | } | ||
983 | break; | ||
984 | case DDB_DS_SESSION_ACTIVE: | ||
985 | switch (state) { | ||
986 | case DDB_DS_SESSION_FAILED: | ||
987 | iscsi_block_session(ddb_entry->sess); | ||
988 | if (!test_bit(DF_RELOGIN, &ddb_entry->flags)) | ||
989 | qla4xxx_arm_relogin_timer(ddb_entry); | ||
990 | status = QLA_SUCCESS; | ||
991 | break; | ||
992 | } | ||
993 | break; | ||
994 | case DDB_DS_SESSION_FAILED: | ||
995 | switch (state) { | ||
996 | case DDB_DS_SESSION_ACTIVE: | ||
997 | ddb_entry->unblock_sess(ddb_entry->sess); | ||
998 | qla4xxx_update_session_conn_fwddb_param(ha, ddb_entry); | ||
999 | status = QLA_SUCCESS; | ||
1000 | break; | ||
1001 | case DDB_DS_SESSION_FAILED: | ||
1002 | if (!test_bit(DF_RELOGIN, &ddb_entry->flags)) | ||
1003 | qla4xxx_arm_relogin_timer(ddb_entry); | ||
1004 | status = QLA_SUCCESS; | ||
1005 | break; | ||
1006 | } | ||
1007 | break; | ||
1008 | default: | ||
1009 | DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Unknown Event\n", | ||
1010 | __func__)); | ||
1011 | break; | ||
1012 | } | ||
1013 | return status; | ||
1014 | } | ||
1015 | |||
1016 | /** | ||
1017 | * qla4xxx_process_ddb_changed - process ddb state change | ||
1018 | * @ha - Pointer to host adapter structure. | ||
1019 | * @fw_ddb_index - Firmware's device database index | ||
1020 | * @state - Device state | ||
1021 | * | ||
1022 | * This routine processes a Decive Database Changed AEN Event. | ||
1023 | **/ | ||
1024 | int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, | ||
1025 | uint32_t fw_ddb_index, | ||
1026 | uint32_t state, uint32_t conn_err) | ||
1027 | { | ||
1028 | struct ddb_entry *ddb_entry; | ||
1029 | int status = QLA_ERROR; | ||
1030 | |||
1031 | /* check for out of range index */ | ||
1032 | if (fw_ddb_index >= MAX_DDB_ENTRIES) | ||
1033 | goto exit_ddb_event; | ||
1034 | |||
1035 | /* Get the corresponging ddb entry */ | ||
1036 | ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, fw_ddb_index); | ||
1037 | /* Device does not currently exist in our database. */ | ||
1038 | if (ddb_entry == NULL) { | ||
1039 | ql4_printk(KERN_ERR, ha, "%s: No ddb_entry at FW index [%d]\n", | ||
1040 | __func__, fw_ddb_index); | ||
1041 | |||
1042 | if (state == DDB_DS_NO_CONNECTION_ACTIVE) | ||
1043 | clear_bit(fw_ddb_index, ha->ddb_idx_map); | ||
1044 | |||
1045 | goto exit_ddb_event; | ||
1046 | } | ||
1047 | |||
1048 | ddb_entry->ddb_change(ha, fw_ddb_index, ddb_entry, state); | ||
957 | 1049 | ||
958 | exit_ddb_event: | 1050 | exit_ddb_event: |
959 | return status; | 1051 | return status; |
960 | } | 1052 | } |
1053 | |||
1054 | /** | ||
1055 | * qla4xxx_login_flash_ddb - Login to target (DDB) | ||
1056 | * @cls_session: Pointer to the session to login | ||
1057 | * | ||
1058 | * This routine logins to the target. | ||
1059 | * Issues setddb and conn open mbx | ||
1060 | **/ | ||
1061 | void qla4xxx_login_flash_ddb(struct iscsi_cls_session *cls_session) | ||
1062 | { | ||
1063 | struct iscsi_session *sess; | ||
1064 | struct ddb_entry *ddb_entry; | ||
1065 | struct scsi_qla_host *ha; | ||
1066 | struct dev_db_entry *fw_ddb_entry = NULL; | ||
1067 | dma_addr_t fw_ddb_dma; | ||
1068 | uint32_t mbx_sts = 0; | ||
1069 | int ret; | ||
1070 | |||
1071 | sess = cls_session->dd_data; | ||
1072 | ddb_entry = sess->dd_data; | ||
1073 | ha = ddb_entry->ha; | ||
1074 | |||
1075 | if (!test_bit(AF_LINK_UP, &ha->flags)) | ||
1076 | return; | ||
1077 | |||
1078 | if (ddb_entry->ddb_type != FLASH_DDB) { | ||
1079 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
1080 | "Skipping login to non FLASH DB")); | ||
1081 | goto exit_login; | ||
1082 | } | ||
1083 | |||
1084 | fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL, | ||
1085 | &fw_ddb_dma); | ||
1086 | if (fw_ddb_entry == NULL) { | ||
1087 | DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n")); | ||
1088 | goto exit_login; | ||
1089 | } | ||
1090 | |||
1091 | if (ddb_entry->fw_ddb_index == INVALID_ENTRY) { | ||
1092 | ret = qla4xxx_get_ddb_index(ha, &ddb_entry->fw_ddb_index); | ||
1093 | if (ret == QLA_ERROR) | ||
1094 | goto exit_login; | ||
1095 | |||
1096 | ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = ddb_entry; | ||
1097 | ha->tot_ddbs++; | ||
1098 | } | ||
1099 | |||
1100 | memcpy(fw_ddb_entry, &ddb_entry->fw_ddb_entry, | ||
1101 | sizeof(struct dev_db_entry)); | ||
1102 | ddb_entry->sess->target_id = ddb_entry->fw_ddb_index; | ||
1103 | |||
1104 | ret = qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index, | ||
1105 | fw_ddb_dma, &mbx_sts); | ||
1106 | if (ret == QLA_ERROR) { | ||
1107 | DEBUG2(ql4_printk(KERN_ERR, ha, "Set DDB failed\n")); | ||
1108 | goto exit_login; | ||
1109 | } | ||
1110 | |||
1111 | ddb_entry->fw_ddb_device_state = DDB_DS_LOGIN_IN_PROCESS; | ||
1112 | ret = qla4xxx_conn_open(ha, ddb_entry->fw_ddb_index); | ||
1113 | if (ret == QLA_ERROR) { | ||
1114 | ql4_printk(KERN_ERR, ha, "%s: Login failed: %s\n", __func__, | ||
1115 | sess->targetname); | ||
1116 | goto exit_login; | ||
1117 | } | ||
1118 | |||
1119 | exit_login: | ||
1120 | if (fw_ddb_entry) | ||
1121 | dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma); | ||
1122 | } | ||
1123 | |||
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 4c2b84870392..c2593782fbbe 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -41,6 +41,16 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |||
41 | return status; | 41 | return status; |
42 | } | 42 | } |
43 | 43 | ||
44 | if (is_qla40XX(ha)) { | ||
45 | if (test_bit(AF_HA_REMOVAL, &ha->flags)) { | ||
46 | DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: " | ||
47 | "prematurely completing mbx cmd as " | ||
48 | "adapter removal detected\n", | ||
49 | ha->host_no, __func__)); | ||
50 | return status; | ||
51 | } | ||
52 | } | ||
53 | |||
44 | if (is_qla8022(ha)) { | 54 | if (is_qla8022(ha)) { |
45 | if (test_bit(AF_FW_RECOVERY, &ha->flags)) { | 55 | if (test_bit(AF_FW_RECOVERY, &ha->flags)) { |
46 | DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: " | 56 | DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: " |
@@ -413,6 +423,7 @@ qla4xxx_update_local_ifcb(struct scsi_qla_host *ha, | |||
413 | memcpy(ha->name_string, init_fw_cb->iscsi_name, | 423 | memcpy(ha->name_string, init_fw_cb->iscsi_name, |
414 | min(sizeof(ha->name_string), | 424 | min(sizeof(ha->name_string), |
415 | sizeof(init_fw_cb->iscsi_name))); | 425 | sizeof(init_fw_cb->iscsi_name))); |
426 | ha->def_timeout = le16_to_cpu(init_fw_cb->def_timeout); | ||
416 | /*memcpy(ha->alias, init_fw_cb->Alias, | 427 | /*memcpy(ha->alias, init_fw_cb->Alias, |
417 | min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/ | 428 | min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/ |
418 | 429 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 30f31b127f33..4169c8baa112 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <linux/blkdev.h> | 9 | #include <linux/blkdev.h> |
10 | #include <linux/iscsi_boot_sysfs.h> | 10 | #include <linux/iscsi_boot_sysfs.h> |
11 | #include <linux/inet.h> | ||
11 | 12 | ||
12 | #include <scsi/scsi_tcq.h> | 13 | #include <scsi/scsi_tcq.h> |
13 | #include <scsi/scsicam.h> | 14 | #include <scsi/scsicam.h> |
@@ -31,6 +32,13 @@ static struct kmem_cache *srb_cachep; | |||
31 | /* | 32 | /* |
32 | * Module parameter information and variables | 33 | * Module parameter information and variables |
33 | */ | 34 | */ |
35 | int ql4xdisablesysfsboot = 1; | ||
36 | module_param(ql4xdisablesysfsboot, int, S_IRUGO | S_IWUSR); | ||
37 | MODULE_PARM_DESC(ql4xdisablesysfsboot, | ||
38 | "Set to disable exporting boot targets to sysfs\n" | ||
39 | " 0 - Export boot targets\n" | ||
40 | " 1 - Do not export boot targets (Default)"); | ||
41 | |||
34 | int ql4xdontresethba = 0; | 42 | int ql4xdontresethba = 0; |
35 | module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR); | 43 | module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR); |
36 | MODULE_PARM_DESC(ql4xdontresethba, | 44 | MODULE_PARM_DESC(ql4xdontresethba, |
@@ -63,7 +71,7 @@ static int ql4xsess_recovery_tmo = QL4_SESS_RECOVERY_TMO; | |||
63 | module_param(ql4xsess_recovery_tmo, int, S_IRUGO); | 71 | module_param(ql4xsess_recovery_tmo, int, S_IRUGO); |
64 | MODULE_PARM_DESC(ql4xsess_recovery_tmo, | 72 | MODULE_PARM_DESC(ql4xsess_recovery_tmo, |
65 | "Target Session Recovery Timeout.\n" | 73 | "Target Session Recovery Timeout.\n" |
66 | " Default: 30 sec."); | 74 | " Default: 120 sec."); |
67 | 75 | ||
68 | static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha); | 76 | static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha); |
69 | /* | 77 | /* |
@@ -415,7 +423,7 @@ static int qla4xxx_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) | |||
415 | qla_ep = ep->dd_data; | 423 | qla_ep = ep->dd_data; |
416 | ha = to_qla_host(qla_ep->host); | 424 | ha = to_qla_host(qla_ep->host); |
417 | 425 | ||
418 | if (adapter_up(ha)) | 426 | if (adapter_up(ha) && !test_bit(AF_BUILD_DDB_LIST, &ha->flags)) |
419 | ret = 1; | 427 | ret = 1; |
420 | 428 | ||
421 | return ret; | 429 | return ret; |
@@ -975,6 +983,150 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *cls_conn, | |||
975 | 983 | ||
976 | } | 984 | } |
977 | 985 | ||
986 | int qla4xxx_get_ddb_index(struct scsi_qla_host *ha, uint16_t *ddb_index) | ||
987 | { | ||
988 | uint32_t mbx_sts = 0; | ||
989 | uint16_t tmp_ddb_index; | ||
990 | int ret; | ||
991 | |||
992 | get_ddb_index: | ||
993 | tmp_ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES); | ||
994 | |||
995 | if (tmp_ddb_index >= MAX_DDB_ENTRIES) { | ||
996 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
997 | "Free DDB index not available\n")); | ||
998 | ret = QLA_ERROR; | ||
999 | goto exit_get_ddb_index; | ||
1000 | } | ||
1001 | |||
1002 | if (test_and_set_bit(tmp_ddb_index, ha->ddb_idx_map)) | ||
1003 | goto get_ddb_index; | ||
1004 | |||
1005 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
1006 | "Found a free DDB index at %d\n", tmp_ddb_index)); | ||
1007 | ret = qla4xxx_req_ddb_entry(ha, tmp_ddb_index, &mbx_sts); | ||
1008 | if (ret == QLA_ERROR) { | ||
1009 | if (mbx_sts == MBOX_STS_COMMAND_ERROR) { | ||
1010 | ql4_printk(KERN_INFO, ha, | ||
1011 | "DDB index = %d not available trying next\n", | ||
1012 | tmp_ddb_index); | ||
1013 | goto get_ddb_index; | ||
1014 | } | ||
1015 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
1016 | "Free FW DDB not available\n")); | ||
1017 | } | ||
1018 | |||
1019 | *ddb_index = tmp_ddb_index; | ||
1020 | |||
1021 | exit_get_ddb_index: | ||
1022 | return ret; | ||
1023 | } | ||
1024 | |||
1025 | static int qla4xxx_match_ipaddress(struct scsi_qla_host *ha, | ||
1026 | struct ddb_entry *ddb_entry, | ||
1027 | char *existing_ipaddr, | ||
1028 | char *user_ipaddr) | ||
1029 | { | ||
1030 | uint8_t dst_ipaddr[IPv6_ADDR_LEN]; | ||
1031 | char formatted_ipaddr[DDB_IPADDR_LEN]; | ||
1032 | int status = QLA_SUCCESS, ret = 0; | ||
1033 | |||
1034 | if (ddb_entry->fw_ddb_entry.options & DDB_OPT_IPV6_DEVICE) { | ||
1035 | ret = in6_pton(user_ipaddr, strlen(user_ipaddr), dst_ipaddr, | ||
1036 | '\0', NULL); | ||
1037 | if (ret == 0) { | ||
1038 | status = QLA_ERROR; | ||
1039 | goto out_match; | ||
1040 | } | ||
1041 | ret = sprintf(formatted_ipaddr, "%pI6", dst_ipaddr); | ||
1042 | } else { | ||
1043 | ret = in4_pton(user_ipaddr, strlen(user_ipaddr), dst_ipaddr, | ||
1044 | '\0', NULL); | ||
1045 | if (ret == 0) { | ||
1046 | status = QLA_ERROR; | ||
1047 | goto out_match; | ||
1048 | } | ||
1049 | ret = sprintf(formatted_ipaddr, "%pI4", dst_ipaddr); | ||
1050 | } | ||
1051 | |||
1052 | if (strcmp(existing_ipaddr, formatted_ipaddr)) | ||
1053 | status = QLA_ERROR; | ||
1054 | |||
1055 | out_match: | ||
1056 | return status; | ||
1057 | } | ||
1058 | |||
1059 | static int qla4xxx_match_fwdb_session(struct scsi_qla_host *ha, | ||
1060 | struct iscsi_cls_conn *cls_conn) | ||
1061 | { | ||
1062 | int idx = 0, max_ddbs, rval; | ||
1063 | struct iscsi_cls_session *cls_sess = iscsi_conn_to_session(cls_conn); | ||
1064 | struct iscsi_session *sess, *existing_sess; | ||
1065 | struct iscsi_conn *conn, *existing_conn; | ||
1066 | struct ddb_entry *ddb_entry; | ||
1067 | |||
1068 | sess = cls_sess->dd_data; | ||
1069 | conn = cls_conn->dd_data; | ||
1070 | |||
1071 | if (sess->targetname == NULL || | ||
1072 | conn->persistent_address == NULL || | ||
1073 | conn->persistent_port == 0) | ||
1074 | return QLA_ERROR; | ||
1075 | |||
1076 | max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX : | ||
1077 | MAX_DEV_DB_ENTRIES; | ||
1078 | |||
1079 | for (idx = 0; idx < max_ddbs; idx++) { | ||
1080 | ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx); | ||
1081 | if (ddb_entry == NULL) | ||
1082 | continue; | ||
1083 | |||
1084 | if (ddb_entry->ddb_type != FLASH_DDB) | ||
1085 | continue; | ||
1086 | |||
1087 | existing_sess = ddb_entry->sess->dd_data; | ||
1088 | existing_conn = ddb_entry->conn->dd_data; | ||
1089 | |||
1090 | if (existing_sess->targetname == NULL || | ||
1091 | existing_conn->persistent_address == NULL || | ||
1092 | existing_conn->persistent_port == 0) | ||
1093 | continue; | ||
1094 | |||
1095 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
1096 | "IQN = %s User IQN = %s\n", | ||
1097 | existing_sess->targetname, | ||
1098 | sess->targetname)); | ||
1099 | |||
1100 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
1101 | "IP = %s User IP = %s\n", | ||
1102 | existing_conn->persistent_address, | ||
1103 | conn->persistent_address)); | ||
1104 | |||
1105 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
1106 | "Port = %d User Port = %d\n", | ||
1107 | existing_conn->persistent_port, | ||
1108 | conn->persistent_port)); | ||
1109 | |||
1110 | if (strcmp(existing_sess->targetname, sess->targetname)) | ||
1111 | continue; | ||
1112 | rval = qla4xxx_match_ipaddress(ha, ddb_entry, | ||
1113 | existing_conn->persistent_address, | ||
1114 | conn->persistent_address); | ||
1115 | if (rval == QLA_ERROR) | ||
1116 | continue; | ||
1117 | if (existing_conn->persistent_port != conn->persistent_port) | ||
1118 | continue; | ||
1119 | break; | ||
1120 | } | ||
1121 | |||
1122 | if (idx == max_ddbs) | ||
1123 | return QLA_ERROR; | ||
1124 | |||
1125 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
1126 | "Match found in fwdb sessions\n")); | ||
1127 | return QLA_SUCCESS; | ||
1128 | } | ||
1129 | |||
978 | static struct iscsi_cls_session * | 1130 | static struct iscsi_cls_session * |
979 | qla4xxx_session_create(struct iscsi_endpoint *ep, | 1131 | qla4xxx_session_create(struct iscsi_endpoint *ep, |
980 | uint16_t cmds_max, uint16_t qdepth, | 1132 | uint16_t cmds_max, uint16_t qdepth, |
@@ -984,8 +1136,7 @@ qla4xxx_session_create(struct iscsi_endpoint *ep, | |||
984 | struct scsi_qla_host *ha; | 1136 | struct scsi_qla_host *ha; |
985 | struct qla_endpoint *qla_ep; | 1137 | struct qla_endpoint *qla_ep; |
986 | struct ddb_entry *ddb_entry; | 1138 | struct ddb_entry *ddb_entry; |
987 | uint32_t ddb_index; | 1139 | uint16_t ddb_index; |
988 | uint32_t mbx_sts = 0; | ||
989 | struct iscsi_session *sess; | 1140 | struct iscsi_session *sess; |
990 | struct sockaddr *dst_addr; | 1141 | struct sockaddr *dst_addr; |
991 | int ret; | 1142 | int ret; |
@@ -1000,32 +1151,9 @@ qla4xxx_session_create(struct iscsi_endpoint *ep, | |||
1000 | dst_addr = (struct sockaddr *)&qla_ep->dst_addr; | 1151 | dst_addr = (struct sockaddr *)&qla_ep->dst_addr; |
1001 | ha = to_qla_host(qla_ep->host); | 1152 | ha = to_qla_host(qla_ep->host); |
1002 | 1153 | ||
1003 | get_ddb_index: | 1154 | ret = qla4xxx_get_ddb_index(ha, &ddb_index); |
1004 | ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES); | 1155 | if (ret == QLA_ERROR) |
1005 | |||
1006 | if (ddb_index >= MAX_DDB_ENTRIES) { | ||
1007 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
1008 | "Free DDB index not available\n")); | ||
1009 | return NULL; | ||
1010 | } | ||
1011 | |||
1012 | if (test_and_set_bit(ddb_index, ha->ddb_idx_map)) | ||
1013 | goto get_ddb_index; | ||
1014 | |||
1015 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
1016 | "Found a free DDB index at %d\n", ddb_index)); | ||
1017 | ret = qla4xxx_req_ddb_entry(ha, ddb_index, &mbx_sts); | ||
1018 | if (ret == QLA_ERROR) { | ||
1019 | if (mbx_sts == MBOX_STS_COMMAND_ERROR) { | ||
1020 | ql4_printk(KERN_INFO, ha, | ||
1021 | "DDB index = %d not available trying next\n", | ||
1022 | ddb_index); | ||
1023 | goto get_ddb_index; | ||
1024 | } | ||
1025 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
1026 | "Free FW DDB not available\n")); | ||
1027 | return NULL; | 1156 | return NULL; |
1028 | } | ||
1029 | 1157 | ||
1030 | cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, qla_ep->host, | 1158 | cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, qla_ep->host, |
1031 | cmds_max, sizeof(struct ddb_entry), | 1159 | cmds_max, sizeof(struct ddb_entry), |
@@ -1040,6 +1168,8 @@ get_ddb_index: | |||
1040 | ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE; | 1168 | ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE; |
1041 | ddb_entry->ha = ha; | 1169 | ddb_entry->ha = ha; |
1042 | ddb_entry->sess = cls_sess; | 1170 | ddb_entry->sess = cls_sess; |
1171 | ddb_entry->unblock_sess = qla4xxx_unblock_ddb; | ||
1172 | ddb_entry->ddb_change = qla4xxx_ddb_change; | ||
1043 | cls_sess->recovery_tmo = ql4xsess_recovery_tmo; | 1173 | cls_sess->recovery_tmo = ql4xsess_recovery_tmo; |
1044 | ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = ddb_entry; | 1174 | ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = ddb_entry; |
1045 | ha->tot_ddbs++; | 1175 | ha->tot_ddbs++; |
@@ -1077,6 +1207,9 @@ qla4xxx_conn_create(struct iscsi_cls_session *cls_sess, uint32_t conn_idx) | |||
1077 | DEBUG2(printk(KERN_INFO "Func: %s\n", __func__)); | 1207 | DEBUG2(printk(KERN_INFO "Func: %s\n", __func__)); |
1078 | cls_conn = iscsi_conn_setup(cls_sess, sizeof(struct qla_conn), | 1208 | cls_conn = iscsi_conn_setup(cls_sess, sizeof(struct qla_conn), |
1079 | conn_idx); | 1209 | conn_idx); |
1210 | if (!cls_conn) | ||
1211 | return NULL; | ||
1212 | |||
1080 | sess = cls_sess->dd_data; | 1213 | sess = cls_sess->dd_data; |
1081 | ddb_entry = sess->dd_data; | 1214 | ddb_entry = sess->dd_data; |
1082 | ddb_entry->conn = cls_conn; | 1215 | ddb_entry->conn = cls_conn; |
@@ -1109,7 +1242,7 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn) | |||
1109 | struct iscsi_session *sess; | 1242 | struct iscsi_session *sess; |
1110 | struct ddb_entry *ddb_entry; | 1243 | struct ddb_entry *ddb_entry; |
1111 | struct scsi_qla_host *ha; | 1244 | struct scsi_qla_host *ha; |
1112 | struct dev_db_entry *fw_ddb_entry; | 1245 | struct dev_db_entry *fw_ddb_entry = NULL; |
1113 | dma_addr_t fw_ddb_entry_dma; | 1246 | dma_addr_t fw_ddb_entry_dma; |
1114 | uint32_t mbx_sts = 0; | 1247 | uint32_t mbx_sts = 0; |
1115 | int ret = 0; | 1248 | int ret = 0; |
@@ -1120,12 +1253,25 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn) | |||
1120 | ddb_entry = sess->dd_data; | 1253 | ddb_entry = sess->dd_data; |
1121 | ha = ddb_entry->ha; | 1254 | ha = ddb_entry->ha; |
1122 | 1255 | ||
1256 | /* Check if we have matching FW DDB, if yes then do not | ||
1257 | * login to this target. This could cause target to logout previous | ||
1258 | * connection | ||
1259 | */ | ||
1260 | ret = qla4xxx_match_fwdb_session(ha, cls_conn); | ||
1261 | if (ret == QLA_SUCCESS) { | ||
1262 | ql4_printk(KERN_INFO, ha, | ||
1263 | "Session already exist in FW.\n"); | ||
1264 | ret = -EEXIST; | ||
1265 | goto exit_conn_start; | ||
1266 | } | ||
1267 | |||
1123 | fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | 1268 | fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), |
1124 | &fw_ddb_entry_dma, GFP_KERNEL); | 1269 | &fw_ddb_entry_dma, GFP_KERNEL); |
1125 | if (!fw_ddb_entry) { | 1270 | if (!fw_ddb_entry) { |
1126 | ql4_printk(KERN_ERR, ha, | 1271 | ql4_printk(KERN_ERR, ha, |
1127 | "%s: Unable to allocate dma buffer\n", __func__); | 1272 | "%s: Unable to allocate dma buffer\n", __func__); |
1128 | return -ENOMEM; | 1273 | ret = -ENOMEM; |
1274 | goto exit_conn_start; | ||
1129 | } | 1275 | } |
1130 | 1276 | ||
1131 | ret = qla4xxx_set_param_ddbentry(ha, ddb_entry, cls_conn, &mbx_sts); | 1277 | ret = qla4xxx_set_param_ddbentry(ha, ddb_entry, cls_conn, &mbx_sts); |
@@ -1138,9 +1284,7 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn) | |||
1138 | if (mbx_sts) | 1284 | if (mbx_sts) |
1139 | if (ddb_entry->fw_ddb_device_state == | 1285 | if (ddb_entry->fw_ddb_device_state == |
1140 | DDB_DS_SESSION_ACTIVE) { | 1286 | DDB_DS_SESSION_ACTIVE) { |
1141 | iscsi_conn_start(ddb_entry->conn); | 1287 | ddb_entry->unblock_sess(ddb_entry->sess); |
1142 | iscsi_conn_login_event(ddb_entry->conn, | ||
1143 | ISCSI_CONN_STATE_LOGGED_IN); | ||
1144 | goto exit_set_param; | 1288 | goto exit_set_param; |
1145 | } | 1289 | } |
1146 | 1290 | ||
@@ -1167,8 +1311,9 @@ exit_set_param: | |||
1167 | ret = 0; | 1311 | ret = 0; |
1168 | 1312 | ||
1169 | exit_conn_start: | 1313 | exit_conn_start: |
1170 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | 1314 | if (fw_ddb_entry) |
1171 | fw_ddb_entry, fw_ddb_entry_dma); | 1315 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), |
1316 | fw_ddb_entry, fw_ddb_entry_dma); | ||
1172 | return ret; | 1317 | return ret; |
1173 | } | 1318 | } |
1174 | 1319 | ||
@@ -1344,6 +1489,101 @@ static int qla4xxx_task_xmit(struct iscsi_task *task) | |||
1344 | return -ENOSYS; | 1489 | return -ENOSYS; |
1345 | } | 1490 | } |
1346 | 1491 | ||
1492 | static void qla4xxx_copy_fwddb_param(struct scsi_qla_host *ha, | ||
1493 | struct dev_db_entry *fw_ddb_entry, | ||
1494 | struct iscsi_cls_session *cls_sess, | ||
1495 | struct iscsi_cls_conn *cls_conn) | ||
1496 | { | ||
1497 | int buflen = 0; | ||
1498 | struct iscsi_session *sess; | ||
1499 | struct iscsi_conn *conn; | ||
1500 | char ip_addr[DDB_IPADDR_LEN]; | ||
1501 | uint16_t options = 0; | ||
1502 | |||
1503 | sess = cls_sess->dd_data; | ||
1504 | conn = cls_conn->dd_data; | ||
1505 | |||
1506 | conn->max_recv_dlength = BYTE_UNITS * | ||
1507 | le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len); | ||
1508 | |||
1509 | conn->max_xmit_dlength = BYTE_UNITS * | ||
1510 | le16_to_cpu(fw_ddb_entry->iscsi_max_snd_data_seg_len); | ||
1511 | |||
1512 | sess->initial_r2t_en = | ||
1513 | (BIT_10 & le16_to_cpu(fw_ddb_entry->iscsi_options)); | ||
1514 | |||
1515 | sess->max_r2t = le16_to_cpu(fw_ddb_entry->iscsi_max_outsnd_r2t); | ||
1516 | |||
1517 | sess->imm_data_en = (BIT_11 & le16_to_cpu(fw_ddb_entry->iscsi_options)); | ||
1518 | |||
1519 | sess->first_burst = BYTE_UNITS * | ||
1520 | le16_to_cpu(fw_ddb_entry->iscsi_first_burst_len); | ||
1521 | |||
1522 | sess->max_burst = BYTE_UNITS * | ||
1523 | le16_to_cpu(fw_ddb_entry->iscsi_max_burst_len); | ||
1524 | |||
1525 | sess->time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait); | ||
1526 | |||
1527 | sess->time2retain = le16_to_cpu(fw_ddb_entry->iscsi_def_time2retain); | ||
1528 | |||
1529 | conn->persistent_port = le16_to_cpu(fw_ddb_entry->port); | ||
1530 | |||
1531 | sess->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp); | ||
1532 | |||
1533 | options = le16_to_cpu(fw_ddb_entry->options); | ||
1534 | if (options & DDB_OPT_IPV6_DEVICE) | ||
1535 | sprintf(ip_addr, "%pI6", fw_ddb_entry->ip_addr); | ||
1536 | else | ||
1537 | sprintf(ip_addr, "%pI4", fw_ddb_entry->ip_addr); | ||
1538 | |||
1539 | iscsi_set_param(cls_conn, ISCSI_PARAM_TARGET_NAME, | ||
1540 | (char *)fw_ddb_entry->iscsi_name, buflen); | ||
1541 | iscsi_set_param(cls_conn, ISCSI_PARAM_INITIATOR_NAME, | ||
1542 | (char *)ha->name_string, buflen); | ||
1543 | iscsi_set_param(cls_conn, ISCSI_PARAM_PERSISTENT_ADDRESS, | ||
1544 | (char *)ip_addr, buflen); | ||
1545 | } | ||
1546 | |||
1547 | void qla4xxx_update_session_conn_fwddb_param(struct scsi_qla_host *ha, | ||
1548 | struct ddb_entry *ddb_entry) | ||
1549 | { | ||
1550 | struct iscsi_cls_session *cls_sess; | ||
1551 | struct iscsi_cls_conn *cls_conn; | ||
1552 | uint32_t ddb_state; | ||
1553 | dma_addr_t fw_ddb_entry_dma; | ||
1554 | struct dev_db_entry *fw_ddb_entry; | ||
1555 | |||
1556 | fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | ||
1557 | &fw_ddb_entry_dma, GFP_KERNEL); | ||
1558 | if (!fw_ddb_entry) { | ||
1559 | ql4_printk(KERN_ERR, ha, | ||
1560 | "%s: Unable to allocate dma buffer\n", __func__); | ||
1561 | goto exit_session_conn_fwddb_param; | ||
1562 | } | ||
1563 | |||
1564 | if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry, | ||
1565 | fw_ddb_entry_dma, NULL, NULL, &ddb_state, | ||
1566 | NULL, NULL, NULL) == QLA_ERROR) { | ||
1567 | DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed " | ||
1568 | "get_ddb_entry for fw_ddb_index %d\n", | ||
1569 | ha->host_no, __func__, | ||
1570 | ddb_entry->fw_ddb_index)); | ||
1571 | goto exit_session_conn_fwddb_param; | ||
1572 | } | ||
1573 | |||
1574 | cls_sess = ddb_entry->sess; | ||
1575 | |||
1576 | cls_conn = ddb_entry->conn; | ||
1577 | |||
1578 | /* Update params */ | ||
1579 | qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, cls_conn); | ||
1580 | |||
1581 | exit_session_conn_fwddb_param: | ||
1582 | if (fw_ddb_entry) | ||
1583 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | ||
1584 | fw_ddb_entry, fw_ddb_entry_dma); | ||
1585 | } | ||
1586 | |||
1347 | void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, | 1587 | void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, |
1348 | struct ddb_entry *ddb_entry) | 1588 | struct ddb_entry *ddb_entry) |
1349 | { | 1589 | { |
@@ -1360,7 +1600,7 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, | |||
1360 | if (!fw_ddb_entry) { | 1600 | if (!fw_ddb_entry) { |
1361 | ql4_printk(KERN_ERR, ha, | 1601 | ql4_printk(KERN_ERR, ha, |
1362 | "%s: Unable to allocate dma buffer\n", __func__); | 1602 | "%s: Unable to allocate dma buffer\n", __func__); |
1363 | return; | 1603 | goto exit_session_conn_param; |
1364 | } | 1604 | } |
1365 | 1605 | ||
1366 | if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry, | 1606 | if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry, |
@@ -1370,7 +1610,7 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, | |||
1370 | "get_ddb_entry for fw_ddb_index %d\n", | 1610 | "get_ddb_entry for fw_ddb_index %d\n", |
1371 | ha->host_no, __func__, | 1611 | ha->host_no, __func__, |
1372 | ddb_entry->fw_ddb_index)); | 1612 | ddb_entry->fw_ddb_index)); |
1373 | return; | 1613 | goto exit_session_conn_param; |
1374 | } | 1614 | } |
1375 | 1615 | ||
1376 | cls_sess = ddb_entry->sess; | 1616 | cls_sess = ddb_entry->sess; |
@@ -1379,6 +1619,12 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, | |||
1379 | cls_conn = ddb_entry->conn; | 1619 | cls_conn = ddb_entry->conn; |
1380 | conn = cls_conn->dd_data; | 1620 | conn = cls_conn->dd_data; |
1381 | 1621 | ||
1622 | /* Update timers after login */ | ||
1623 | ddb_entry->default_relogin_timeout = | ||
1624 | le16_to_cpu(fw_ddb_entry->def_timeout); | ||
1625 | ddb_entry->default_time2wait = | ||
1626 | le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait); | ||
1627 | |||
1382 | /* Update params */ | 1628 | /* Update params */ |
1383 | conn->max_recv_dlength = BYTE_UNITS * | 1629 | conn->max_recv_dlength = BYTE_UNITS * |
1384 | le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len); | 1630 | le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len); |
@@ -1407,6 +1653,11 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, | |||
1407 | 1653 | ||
1408 | memcpy(sess->initiatorname, ha->name_string, | 1654 | memcpy(sess->initiatorname, ha->name_string, |
1409 | min(sizeof(ha->name_string), sizeof(sess->initiatorname))); | 1655 | min(sizeof(ha->name_string), sizeof(sess->initiatorname))); |
1656 | |||
1657 | exit_session_conn_param: | ||
1658 | if (fw_ddb_entry) | ||
1659 | dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), | ||
1660 | fw_ddb_entry, fw_ddb_entry_dma); | ||
1410 | } | 1661 | } |
1411 | 1662 | ||
1412 | /* | 1663 | /* |
@@ -1607,6 +1858,9 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha) | |||
1607 | vfree(ha->chap_list); | 1858 | vfree(ha->chap_list); |
1608 | ha->chap_list = NULL; | 1859 | ha->chap_list = NULL; |
1609 | 1860 | ||
1861 | if (ha->fw_ddb_dma_pool) | ||
1862 | dma_pool_destroy(ha->fw_ddb_dma_pool); | ||
1863 | |||
1610 | /* release io space registers */ | 1864 | /* release io space registers */ |
1611 | if (is_qla8022(ha)) { | 1865 | if (is_qla8022(ha)) { |
1612 | if (ha->nx_pcibase) | 1866 | if (ha->nx_pcibase) |
@@ -1689,6 +1943,16 @@ static int qla4xxx_mem_alloc(struct scsi_qla_host *ha) | |||
1689 | goto mem_alloc_error_exit; | 1943 | goto mem_alloc_error_exit; |
1690 | } | 1944 | } |
1691 | 1945 | ||
1946 | ha->fw_ddb_dma_pool = dma_pool_create("ql4_fw_ddb", &ha->pdev->dev, | ||
1947 | DDB_DMA_BLOCK_SIZE, 8, 0); | ||
1948 | |||
1949 | if (ha->fw_ddb_dma_pool == NULL) { | ||
1950 | ql4_printk(KERN_WARNING, ha, | ||
1951 | "%s: fw_ddb_dma_pool allocation failed..\n", | ||
1952 | __func__); | ||
1953 | goto mem_alloc_error_exit; | ||
1954 | } | ||
1955 | |||
1692 | return QLA_SUCCESS; | 1956 | return QLA_SUCCESS; |
1693 | 1957 | ||
1694 | mem_alloc_error_exit: | 1958 | mem_alloc_error_exit: |
@@ -1800,6 +2064,60 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha) | |||
1800 | } | 2064 | } |
1801 | } | 2065 | } |
1802 | 2066 | ||
2067 | void qla4xxx_check_relogin_flash_ddb(struct iscsi_cls_session *cls_sess) | ||
2068 | { | ||
2069 | struct iscsi_session *sess; | ||
2070 | struct ddb_entry *ddb_entry; | ||
2071 | struct scsi_qla_host *ha; | ||
2072 | |||
2073 | sess = cls_sess->dd_data; | ||
2074 | ddb_entry = sess->dd_data; | ||
2075 | ha = ddb_entry->ha; | ||
2076 | |||
2077 | if (!(ddb_entry->ddb_type == FLASH_DDB)) | ||
2078 | return; | ||
2079 | |||
2080 | if (adapter_up(ha) && !test_bit(DF_RELOGIN, &ddb_entry->flags) && | ||
2081 | !iscsi_is_session_online(cls_sess)) { | ||
2082 | if (atomic_read(&ddb_entry->retry_relogin_timer) != | ||
2083 | INVALID_ENTRY) { | ||
2084 | if (atomic_read(&ddb_entry->retry_relogin_timer) == | ||
2085 | 0) { | ||
2086 | atomic_set(&ddb_entry->retry_relogin_timer, | ||
2087 | INVALID_ENTRY); | ||
2088 | set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags); | ||
2089 | set_bit(DF_RELOGIN, &ddb_entry->flags); | ||
2090 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
2091 | "%s: index [%d] login device\n", | ||
2092 | __func__, ddb_entry->fw_ddb_index)); | ||
2093 | } else | ||
2094 | atomic_dec(&ddb_entry->retry_relogin_timer); | ||
2095 | } | ||
2096 | } | ||
2097 | |||
2098 | /* Wait for relogin to timeout */ | ||
2099 | if (atomic_read(&ddb_entry->relogin_timer) && | ||
2100 | (atomic_dec_and_test(&ddb_entry->relogin_timer) != 0)) { | ||
2101 | /* | ||
2102 | * If the relogin times out and the device is | ||
2103 | * still NOT ONLINE then try and relogin again. | ||
2104 | */ | ||
2105 | if (!iscsi_is_session_online(cls_sess)) { | ||
2106 | /* Reset retry relogin timer */ | ||
2107 | atomic_inc(&ddb_entry->relogin_retry_count); | ||
2108 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
2109 | "%s: index[%d] relogin timed out-retrying" | ||
2110 | " relogin (%d), retry (%d)\n", __func__, | ||
2111 | ddb_entry->fw_ddb_index, | ||
2112 | atomic_read(&ddb_entry->relogin_retry_count), | ||
2113 | ddb_entry->default_time2wait + 4)); | ||
2114 | set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags); | ||
2115 | atomic_set(&ddb_entry->retry_relogin_timer, | ||
2116 | ddb_entry->default_time2wait + 4); | ||
2117 | } | ||
2118 | } | ||
2119 | } | ||
2120 | |||
1803 | /** | 2121 | /** |
1804 | * qla4xxx_timer - checks every second for work to do. | 2122 | * qla4xxx_timer - checks every second for work to do. |
1805 | * @ha: Pointer to host adapter structure. | 2123 | * @ha: Pointer to host adapter structure. |
@@ -1809,6 +2127,8 @@ static void qla4xxx_timer(struct scsi_qla_host *ha) | |||
1809 | int start_dpc = 0; | 2127 | int start_dpc = 0; |
1810 | uint16_t w; | 2128 | uint16_t w; |
1811 | 2129 | ||
2130 | iscsi_host_for_each_session(ha->host, qla4xxx_check_relogin_flash_ddb); | ||
2131 | |||
1812 | /* If we are in the middle of AER/EEH processing | 2132 | /* If we are in the middle of AER/EEH processing |
1813 | * skip any processing and reschedule the timer | 2133 | * skip any processing and reschedule the timer |
1814 | */ | 2134 | */ |
@@ -2078,7 +2398,12 @@ static void qla4xxx_fail_session(struct iscsi_cls_session *cls_session) | |||
2078 | sess = cls_session->dd_data; | 2398 | sess = cls_session->dd_data; |
2079 | ddb_entry = sess->dd_data; | 2399 | ddb_entry = sess->dd_data; |
2080 | ddb_entry->fw_ddb_device_state = DDB_DS_SESSION_FAILED; | 2400 | ddb_entry->fw_ddb_device_state = DDB_DS_SESSION_FAILED; |
2081 | iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); | 2401 | |
2402 | if (ddb_entry->ddb_type == FLASH_DDB) | ||
2403 | iscsi_block_session(ddb_entry->sess); | ||
2404 | else | ||
2405 | iscsi_session_failure(cls_session->dd_data, | ||
2406 | ISCSI_ERR_CONN_FAILED); | ||
2082 | } | 2407 | } |
2083 | 2408 | ||
2084 | /** | 2409 | /** |
@@ -2163,7 +2488,7 @@ recover_ha_init_adapter: | |||
2163 | 2488 | ||
2164 | /* NOTE: AF_ONLINE flag set upon successful completion of | 2489 | /* NOTE: AF_ONLINE flag set upon successful completion of |
2165 | * qla4xxx_initialize_adapter */ | 2490 | * qla4xxx_initialize_adapter */ |
2166 | status = qla4xxx_initialize_adapter(ha); | 2491 | status = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); |
2167 | } | 2492 | } |
2168 | 2493 | ||
2169 | /* Retry failed adapter initialization, if necessary | 2494 | /* Retry failed adapter initialization, if necessary |
@@ -2245,17 +2570,108 @@ static void qla4xxx_relogin_devices(struct iscsi_cls_session *cls_session) | |||
2245 | iscsi_unblock_session(ddb_entry->sess); | 2570 | iscsi_unblock_session(ddb_entry->sess); |
2246 | } else { | 2571 | } else { |
2247 | /* Trigger relogin */ | 2572 | /* Trigger relogin */ |
2248 | iscsi_session_failure(cls_session->dd_data, | 2573 | if (ddb_entry->ddb_type == FLASH_DDB) { |
2249 | ISCSI_ERR_CONN_FAILED); | 2574 | if (!test_bit(DF_RELOGIN, &ddb_entry->flags)) |
2575 | qla4xxx_arm_relogin_timer(ddb_entry); | ||
2576 | } else | ||
2577 | iscsi_session_failure(cls_session->dd_data, | ||
2578 | ISCSI_ERR_CONN_FAILED); | ||
2250 | } | 2579 | } |
2251 | } | 2580 | } |
2252 | } | 2581 | } |
2253 | 2582 | ||
2583 | int qla4xxx_unblock_flash_ddb(struct iscsi_cls_session *cls_session) | ||
2584 | { | ||
2585 | struct iscsi_session *sess; | ||
2586 | struct ddb_entry *ddb_entry; | ||
2587 | struct scsi_qla_host *ha; | ||
2588 | |||
2589 | sess = cls_session->dd_data; | ||
2590 | ddb_entry = sess->dd_data; | ||
2591 | ha = ddb_entry->ha; | ||
2592 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]" | ||
2593 | " unblock session\n", ha->host_no, __func__, | ||
2594 | ddb_entry->fw_ddb_index); | ||
2595 | |||
2596 | iscsi_unblock_session(ddb_entry->sess); | ||
2597 | |||
2598 | /* Start scan target */ | ||
2599 | if (test_bit(AF_ONLINE, &ha->flags)) { | ||
2600 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]" | ||
2601 | " start scan\n", ha->host_no, __func__, | ||
2602 | ddb_entry->fw_ddb_index); | ||
2603 | scsi_queue_work(ha->host, &ddb_entry->sess->scan_work); | ||
2604 | } | ||
2605 | return QLA_SUCCESS; | ||
2606 | } | ||
2607 | |||
2608 | int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session) | ||
2609 | { | ||
2610 | struct iscsi_session *sess; | ||
2611 | struct ddb_entry *ddb_entry; | ||
2612 | struct scsi_qla_host *ha; | ||
2613 | |||
2614 | sess = cls_session->dd_data; | ||
2615 | ddb_entry = sess->dd_data; | ||
2616 | ha = ddb_entry->ha; | ||
2617 | ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]" | ||
2618 | " unblock user space session\n", ha->host_no, __func__, | ||
2619 | ddb_entry->fw_ddb_index); | ||
2620 | iscsi_conn_start(ddb_entry->conn); | ||
2621 | iscsi_conn_login_event(ddb_entry->conn, | ||
2622 | ISCSI_CONN_STATE_LOGGED_IN); | ||
2623 | |||
2624 | return QLA_SUCCESS; | ||
2625 | } | ||
2626 | |||
2254 | static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha) | 2627 | static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha) |
2255 | { | 2628 | { |
2256 | iscsi_host_for_each_session(ha->host, qla4xxx_relogin_devices); | 2629 | iscsi_host_for_each_session(ha->host, qla4xxx_relogin_devices); |
2257 | } | 2630 | } |
2258 | 2631 | ||
2632 | static void qla4xxx_relogin_flash_ddb(struct iscsi_cls_session *cls_sess) | ||
2633 | { | ||
2634 | uint16_t relogin_timer; | ||
2635 | struct iscsi_session *sess; | ||
2636 | struct ddb_entry *ddb_entry; | ||
2637 | struct scsi_qla_host *ha; | ||
2638 | |||
2639 | sess = cls_sess->dd_data; | ||
2640 | ddb_entry = sess->dd_data; | ||
2641 | ha = ddb_entry->ha; | ||
2642 | |||
2643 | relogin_timer = max(ddb_entry->default_relogin_timeout, | ||
2644 | (uint16_t)RELOGIN_TOV); | ||
2645 | atomic_set(&ddb_entry->relogin_timer, relogin_timer); | ||
2646 | |||
2647 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
2648 | "scsi%ld: Relogin index [%d]. TOV=%d\n", ha->host_no, | ||
2649 | ddb_entry->fw_ddb_index, relogin_timer)); | ||
2650 | |||
2651 | qla4xxx_login_flash_ddb(cls_sess); | ||
2652 | } | ||
2653 | |||
2654 | static void qla4xxx_dpc_relogin(struct iscsi_cls_session *cls_sess) | ||
2655 | { | ||
2656 | struct iscsi_session *sess; | ||
2657 | struct ddb_entry *ddb_entry; | ||
2658 | struct scsi_qla_host *ha; | ||
2659 | |||
2660 | sess = cls_sess->dd_data; | ||
2661 | ddb_entry = sess->dd_data; | ||
2662 | ha = ddb_entry->ha; | ||
2663 | |||
2664 | if (!(ddb_entry->ddb_type == FLASH_DDB)) | ||
2665 | return; | ||
2666 | |||
2667 | if (test_and_clear_bit(DF_RELOGIN, &ddb_entry->flags) && | ||
2668 | !iscsi_is_session_online(cls_sess)) { | ||
2669 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
2670 | "relogin issued\n")); | ||
2671 | qla4xxx_relogin_flash_ddb(cls_sess); | ||
2672 | } | ||
2673 | } | ||
2674 | |||
2259 | void qla4xxx_wake_dpc(struct scsi_qla_host *ha) | 2675 | void qla4xxx_wake_dpc(struct scsi_qla_host *ha) |
2260 | { | 2676 | { |
2261 | if (ha->dpc_thread) | 2677 | if (ha->dpc_thread) |
@@ -2356,6 +2772,12 @@ dpc_post_reset_ha: | |||
2356 | if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags)) | 2772 | if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags)) |
2357 | qla4xxx_get_dhcp_ip_address(ha); | 2773 | qla4xxx_get_dhcp_ip_address(ha); |
2358 | 2774 | ||
2775 | /* ---- relogin device? --- */ | ||
2776 | if (adapter_up(ha) && | ||
2777 | test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) { | ||
2778 | iscsi_host_for_each_session(ha->host, qla4xxx_dpc_relogin); | ||
2779 | } | ||
2780 | |||
2359 | /* ---- link change? --- */ | 2781 | /* ---- link change? --- */ |
2360 | if (test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) { | 2782 | if (test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) { |
2361 | if (!test_bit(AF_LINK_UP, &ha->flags)) { | 2783 | if (!test_bit(AF_LINK_UP, &ha->flags)) { |
@@ -2368,8 +2790,12 @@ dpc_post_reset_ha: | |||
2368 | * fatal error recovery. Therefore, the driver must | 2790 | * fatal error recovery. Therefore, the driver must |
2369 | * manually relogin to devices when recovering from | 2791 | * manually relogin to devices when recovering from |
2370 | * connection failures, logouts, expired KATO, etc. */ | 2792 | * connection failures, logouts, expired KATO, etc. */ |
2371 | 2793 | if (test_and_clear_bit(AF_BUILD_DDB_LIST, &ha->flags)) { | |
2372 | qla4xxx_relogin_all_devices(ha); | 2794 | qla4xxx_build_ddb_list(ha, ha->is_reset); |
2795 | iscsi_host_for_each_session(ha->host, | ||
2796 | qla4xxx_login_flash_ddb); | ||
2797 | } else | ||
2798 | qla4xxx_relogin_all_devices(ha); | ||
2373 | } | 2799 | } |
2374 | } | 2800 | } |
2375 | } | 2801 | } |
@@ -2867,6 +3293,9 @@ static int get_fw_boot_info(struct scsi_qla_host *ha, uint16_t ddb_index[]) | |||
2867 | " target ID %d\n", __func__, ddb_index[0], | 3293 | " target ID %d\n", __func__, ddb_index[0], |
2868 | ddb_index[1])); | 3294 | ddb_index[1])); |
2869 | 3295 | ||
3296 | ha->pri_ddb_idx = ddb_index[0]; | ||
3297 | ha->sec_ddb_idx = ddb_index[1]; | ||
3298 | |||
2870 | exit_boot_info_free: | 3299 | exit_boot_info_free: |
2871 | dma_free_coherent(&ha->pdev->dev, size, buf, buf_dma); | 3300 | dma_free_coherent(&ha->pdev->dev, size, buf, buf_dma); |
2872 | exit_boot_info: | 3301 | exit_boot_info: |
@@ -3034,6 +3463,9 @@ static int qla4xxx_get_boot_info(struct scsi_qla_host *ha) | |||
3034 | return ret; | 3463 | return ret; |
3035 | } | 3464 | } |
3036 | 3465 | ||
3466 | if (ql4xdisablesysfsboot) | ||
3467 | return QLA_SUCCESS; | ||
3468 | |||
3037 | if (ddb_index[0] == 0xffff) | 3469 | if (ddb_index[0] == 0xffff) |
3038 | goto sec_target; | 3470 | goto sec_target; |
3039 | 3471 | ||
@@ -3066,7 +3498,15 @@ static int qla4xxx_setup_boot_info(struct scsi_qla_host *ha) | |||
3066 | struct iscsi_boot_kobj *boot_kobj; | 3498 | struct iscsi_boot_kobj *boot_kobj; |
3067 | 3499 | ||
3068 | if (qla4xxx_get_boot_info(ha) != QLA_SUCCESS) | 3500 | if (qla4xxx_get_boot_info(ha) != QLA_SUCCESS) |
3069 | return 0; | 3501 | return QLA_ERROR; |
3502 | |||
3503 | if (ql4xdisablesysfsboot) { | ||
3504 | ql4_printk(KERN_INFO, ha, | ||
3505 | "%s: syfsboot disabled - driver will trigger login" | ||
3506 | "and publish session for discovery .\n", __func__); | ||
3507 | return QLA_SUCCESS; | ||
3508 | } | ||
3509 | |||
3070 | 3510 | ||
3071 | ha->boot_kset = iscsi_boot_create_host_kset(ha->host->host_no); | 3511 | ha->boot_kset = iscsi_boot_create_host_kset(ha->host->host_no); |
3072 | if (!ha->boot_kset) | 3512 | if (!ha->boot_kset) |
@@ -3108,7 +3548,7 @@ static int qla4xxx_setup_boot_info(struct scsi_qla_host *ha) | |||
3108 | if (!boot_kobj) | 3548 | if (!boot_kobj) |
3109 | goto put_host; | 3549 | goto put_host; |
3110 | 3550 | ||
3111 | return 0; | 3551 | return QLA_SUCCESS; |
3112 | 3552 | ||
3113 | put_host: | 3553 | put_host: |
3114 | scsi_host_put(ha->host); | 3554 | scsi_host_put(ha->host); |
@@ -3174,9 +3614,507 @@ static void qla4xxx_create_chap_list(struct scsi_qla_host *ha) | |||
3174 | exit_chap_list: | 3614 | exit_chap_list: |
3175 | dma_free_coherent(&ha->pdev->dev, chap_size, | 3615 | dma_free_coherent(&ha->pdev->dev, chap_size, |
3176 | chap_flash_data, chap_dma); | 3616 | chap_flash_data, chap_dma); |
3177 | return; | ||
3178 | } | 3617 | } |
3179 | 3618 | ||
3619 | static void qla4xxx_get_param_ddb(struct ddb_entry *ddb_entry, | ||
3620 | struct ql4_tuple_ddb *tddb) | ||
3621 | { | ||
3622 | struct scsi_qla_host *ha; | ||
3623 | struct iscsi_cls_session *cls_sess; | ||
3624 | struct iscsi_cls_conn *cls_conn; | ||
3625 | struct iscsi_session *sess; | ||
3626 | struct iscsi_conn *conn; | ||
3627 | |||
3628 | DEBUG2(printk(KERN_INFO "Func: %s\n", __func__)); | ||
3629 | ha = ddb_entry->ha; | ||
3630 | cls_sess = ddb_entry->sess; | ||
3631 | sess = cls_sess->dd_data; | ||
3632 | cls_conn = ddb_entry->conn; | ||
3633 | conn = cls_conn->dd_data; | ||
3634 | |||
3635 | tddb->tpgt = sess->tpgt; | ||
3636 | tddb->port = conn->persistent_port; | ||
3637 | strncpy(tddb->iscsi_name, sess->targetname, ISCSI_NAME_SIZE); | ||
3638 | strncpy(tddb->ip_addr, conn->persistent_address, DDB_IPADDR_LEN); | ||
3639 | } | ||
3640 | |||
3641 | static void qla4xxx_convert_param_ddb(struct dev_db_entry *fw_ddb_entry, | ||
3642 | struct ql4_tuple_ddb *tddb) | ||
3643 | { | ||
3644 | uint16_t options = 0; | ||
3645 | |||
3646 | tddb->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp); | ||
3647 | memcpy(&tddb->iscsi_name[0], &fw_ddb_entry->iscsi_name[0], | ||
3648 | min(sizeof(tddb->iscsi_name), sizeof(fw_ddb_entry->iscsi_name))); | ||
3649 | |||
3650 | options = le16_to_cpu(fw_ddb_entry->options); | ||
3651 | if (options & DDB_OPT_IPV6_DEVICE) | ||
3652 | sprintf(tddb->ip_addr, "%pI6", fw_ddb_entry->ip_addr); | ||
3653 | else | ||
3654 | sprintf(tddb->ip_addr, "%pI4", fw_ddb_entry->ip_addr); | ||
3655 | |||
3656 | tddb->port = le16_to_cpu(fw_ddb_entry->port); | ||
3657 | } | ||
3658 | |||
3659 | static int qla4xxx_compare_tuple_ddb(struct scsi_qla_host *ha, | ||
3660 | struct ql4_tuple_ddb *old_tddb, | ||
3661 | struct ql4_tuple_ddb *new_tddb) | ||
3662 | { | ||
3663 | if (strcmp(old_tddb->iscsi_name, new_tddb->iscsi_name)) | ||
3664 | return QLA_ERROR; | ||
3665 | |||
3666 | if (strcmp(old_tddb->ip_addr, new_tddb->ip_addr)) | ||
3667 | return QLA_ERROR; | ||
3668 | |||
3669 | if (old_tddb->port != new_tddb->port) | ||
3670 | return QLA_ERROR; | ||
3671 | |||
3672 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
3673 | "Match Found, fw[%d,%d,%s,%s], [%d,%d,%s,%s]", | ||
3674 | old_tddb->port, old_tddb->tpgt, old_tddb->ip_addr, | ||
3675 | old_tddb->iscsi_name, new_tddb->port, new_tddb->tpgt, | ||
3676 | new_tddb->ip_addr, new_tddb->iscsi_name)); | ||
3677 | |||
3678 | return QLA_SUCCESS; | ||
3679 | } | ||
3680 | |||
3681 | static int qla4xxx_is_session_exists(struct scsi_qla_host *ha, | ||
3682 | struct dev_db_entry *fw_ddb_entry) | ||
3683 | { | ||
3684 | struct ddb_entry *ddb_entry; | ||
3685 | struct ql4_tuple_ddb *fw_tddb = NULL; | ||
3686 | struct ql4_tuple_ddb *tmp_tddb = NULL; | ||
3687 | int idx; | ||
3688 | int ret = QLA_ERROR; | ||
3689 | |||
3690 | fw_tddb = vzalloc(sizeof(*fw_tddb)); | ||
3691 | if (!fw_tddb) { | ||
3692 | DEBUG2(ql4_printk(KERN_WARNING, ha, | ||
3693 | "Memory Allocation failed.\n")); | ||
3694 | ret = QLA_SUCCESS; | ||
3695 | goto exit_check; | ||
3696 | } | ||
3697 | |||
3698 | tmp_tddb = vzalloc(sizeof(*tmp_tddb)); | ||
3699 | if (!tmp_tddb) { | ||
3700 | DEBUG2(ql4_printk(KERN_WARNING, ha, | ||
3701 | "Memory Allocation failed.\n")); | ||
3702 | ret = QLA_SUCCESS; | ||
3703 | goto exit_check; | ||
3704 | } | ||
3705 | |||
3706 | qla4xxx_convert_param_ddb(fw_ddb_entry, fw_tddb); | ||
3707 | |||
3708 | for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) { | ||
3709 | ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx); | ||
3710 | if (ddb_entry == NULL) | ||
3711 | continue; | ||
3712 | |||
3713 | qla4xxx_get_param_ddb(ddb_entry, tmp_tddb); | ||
3714 | if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb)) { | ||
3715 | ret = QLA_SUCCESS; /* found */ | ||
3716 | goto exit_check; | ||
3717 | } | ||
3718 | } | ||
3719 | |||
3720 | exit_check: | ||
3721 | if (fw_tddb) | ||
3722 | vfree(fw_tddb); | ||
3723 | if (tmp_tddb) | ||
3724 | vfree(tmp_tddb); | ||
3725 | return ret; | ||
3726 | } | ||
3727 | |||
3728 | static int qla4xxx_is_flash_ddb_exists(struct scsi_qla_host *ha, | ||
3729 | struct list_head *list_nt, | ||
3730 | struct dev_db_entry *fw_ddb_entry) | ||
3731 | { | ||
3732 | struct qla_ddb_index *nt_ddb_idx, *nt_ddb_idx_tmp; | ||
3733 | struct ql4_tuple_ddb *fw_tddb = NULL; | ||
3734 | struct ql4_tuple_ddb *tmp_tddb = NULL; | ||
3735 | int ret = QLA_ERROR; | ||
3736 | |||
3737 | fw_tddb = vzalloc(sizeof(*fw_tddb)); | ||
3738 | if (!fw_tddb) { | ||
3739 | DEBUG2(ql4_printk(KERN_WARNING, ha, | ||
3740 | "Memory Allocation failed.\n")); | ||
3741 | ret = QLA_SUCCESS; | ||
3742 | goto exit_check; | ||
3743 | } | ||
3744 | |||
3745 | tmp_tddb = vzalloc(sizeof(*tmp_tddb)); | ||
3746 | if (!tmp_tddb) { | ||
3747 | DEBUG2(ql4_printk(KERN_WARNING, ha, | ||
3748 | "Memory Allocation failed.\n")); | ||
3749 | ret = QLA_SUCCESS; | ||
3750 | goto exit_check; | ||
3751 | } | ||
3752 | |||
3753 | qla4xxx_convert_param_ddb(fw_ddb_entry, fw_tddb); | ||
3754 | |||
3755 | list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) { | ||
3756 | qla4xxx_convert_param_ddb(&nt_ddb_idx->fw_ddb, tmp_tddb); | ||
3757 | if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb)) { | ||
3758 | ret = QLA_SUCCESS; /* found */ | ||
3759 | goto exit_check; | ||
3760 | } | ||
3761 | } | ||
3762 | |||
3763 | exit_check: | ||
3764 | if (fw_tddb) | ||
3765 | vfree(fw_tddb); | ||
3766 | if (tmp_tddb) | ||
3767 | vfree(tmp_tddb); | ||
3768 | return ret; | ||
3769 | } | ||
3770 | |||
3771 | static void qla4xxx_free_nt_list(struct list_head *list_nt) | ||
3772 | { | ||
3773 | struct qla_ddb_index *nt_ddb_idx, *nt_ddb_idx_tmp; | ||
3774 | |||
3775 | /* Free up the normaltargets list */ | ||
3776 | list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) { | ||
3777 | list_del_init(&nt_ddb_idx->list); | ||
3778 | vfree(nt_ddb_idx); | ||
3779 | } | ||
3780 | |||
3781 | } | ||
3782 | |||
3783 | static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha, | ||
3784 | struct dev_db_entry *fw_ddb_entry) | ||
3785 | { | ||
3786 | struct iscsi_endpoint *ep; | ||
3787 | struct sockaddr_in *addr; | ||
3788 | struct sockaddr_in6 *addr6; | ||
3789 | struct sockaddr *dst_addr; | ||
3790 | char *ip; | ||
3791 | |||
3792 | /* TODO: need to destroy on unload iscsi_endpoint*/ | ||
3793 | dst_addr = vmalloc(sizeof(*dst_addr)); | ||
3794 | if (!dst_addr) | ||
3795 | return NULL; | ||
3796 | |||
3797 | if (fw_ddb_entry->options & DDB_OPT_IPV6_DEVICE) { | ||
3798 | dst_addr->sa_family = AF_INET6; | ||
3799 | addr6 = (struct sockaddr_in6 *)dst_addr; | ||
3800 | ip = (char *)&addr6->sin6_addr; | ||
3801 | memcpy(ip, fw_ddb_entry->ip_addr, IPv6_ADDR_LEN); | ||
3802 | addr6->sin6_port = htons(le16_to_cpu(fw_ddb_entry->port)); | ||
3803 | |||
3804 | } else { | ||
3805 | dst_addr->sa_family = AF_INET; | ||
3806 | addr = (struct sockaddr_in *)dst_addr; | ||
3807 | ip = (char *)&addr->sin_addr; | ||
3808 | memcpy(ip, fw_ddb_entry->ip_addr, IP_ADDR_LEN); | ||
3809 | addr->sin_port = htons(le16_to_cpu(fw_ddb_entry->port)); | ||
3810 | } | ||
3811 | |||
3812 | ep = qla4xxx_ep_connect(ha->host, dst_addr, 0); | ||
3813 | vfree(dst_addr); | ||
3814 | return ep; | ||
3815 | } | ||
3816 | |||
3817 | static int qla4xxx_verify_boot_idx(struct scsi_qla_host *ha, uint16_t idx) | ||
3818 | { | ||
3819 | if (ql4xdisablesysfsboot) | ||
3820 | return QLA_SUCCESS; | ||
3821 | if (idx == ha->pri_ddb_idx || idx == ha->sec_ddb_idx) | ||
3822 | return QLA_ERROR; | ||
3823 | return QLA_SUCCESS; | ||
3824 | } | ||
3825 | |||
3826 | static void qla4xxx_setup_flash_ddb_entry(struct scsi_qla_host *ha, | ||
3827 | struct ddb_entry *ddb_entry) | ||
3828 | { | ||
3829 | ddb_entry->ddb_type = FLASH_DDB; | ||
3830 | ddb_entry->fw_ddb_index = INVALID_ENTRY; | ||
3831 | ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE; | ||
3832 | ddb_entry->ha = ha; | ||
3833 | ddb_entry->unblock_sess = qla4xxx_unblock_flash_ddb; | ||
3834 | ddb_entry->ddb_change = qla4xxx_flash_ddb_change; | ||
3835 | |||
3836 | atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY); | ||
3837 | atomic_set(&ddb_entry->relogin_timer, 0); | ||
3838 | atomic_set(&ddb_entry->relogin_retry_count, 0); | ||
3839 | |||
3840 | ddb_entry->default_relogin_timeout = | ||
3841 | le16_to_cpu(ddb_entry->fw_ddb_entry.def_timeout); | ||
3842 | ddb_entry->default_time2wait = | ||
3843 | le16_to_cpu(ddb_entry->fw_ddb_entry.iscsi_def_time2wait); | ||
3844 | } | ||
3845 | |||
3846 | static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha) | ||
3847 | { | ||
3848 | uint32_t idx = 0; | ||
3849 | uint32_t ip_idx[IP_ADDR_COUNT] = {0, 1, 2, 3}; /* 4 IP interfaces */ | ||
3850 | uint32_t sts[MBOX_REG_COUNT]; | ||
3851 | uint32_t ip_state; | ||
3852 | unsigned long wtime; | ||
3853 | int ret; | ||
3854 | |||
3855 | wtime = jiffies + (HZ * IP_CONFIG_TOV); | ||
3856 | do { | ||
3857 | for (idx = 0; idx < IP_ADDR_COUNT; idx++) { | ||
3858 | if (ip_idx[idx] == -1) | ||
3859 | continue; | ||
3860 | |||
3861 | ret = qla4xxx_get_ip_state(ha, 0, ip_idx[idx], sts); | ||
3862 | |||
3863 | if (ret == QLA_ERROR) { | ||
3864 | ip_idx[idx] = -1; | ||
3865 | continue; | ||
3866 | } | ||
3867 | |||
3868 | ip_state = (sts[1] & IP_STATE_MASK) >> IP_STATE_SHIFT; | ||
3869 | |||
3870 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
3871 | "Waiting for IP state for idx = %d, state = 0x%x\n", | ||
3872 | ip_idx[idx], ip_state)); | ||
3873 | if (ip_state == IP_ADDRSTATE_UNCONFIGURED || | ||
3874 | ip_state == IP_ADDRSTATE_INVALID || | ||
3875 | ip_state == IP_ADDRSTATE_PREFERRED || | ||
3876 | ip_state == IP_ADDRSTATE_DEPRICATED || | ||
3877 | ip_state == IP_ADDRSTATE_DISABLING) | ||
3878 | ip_idx[idx] = -1; | ||
3879 | |||
3880 | } | ||
3881 | |||
3882 | /* Break if all IP states checked */ | ||
3883 | if ((ip_idx[0] == -1) && | ||
3884 | (ip_idx[1] == -1) && | ||
3885 | (ip_idx[2] == -1) && | ||
3886 | (ip_idx[3] == -1)) | ||
3887 | break; | ||
3888 | schedule_timeout_uninterruptible(HZ); | ||
3889 | } while (time_after(wtime, jiffies)); | ||
3890 | } | ||
3891 | |||
3892 | void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset) | ||
3893 | { | ||
3894 | int max_ddbs; | ||
3895 | int ret; | ||
3896 | uint32_t idx = 0, next_idx = 0; | ||
3897 | uint32_t state = 0, conn_err = 0; | ||
3898 | uint16_t conn_id; | ||
3899 | struct dev_db_entry *fw_ddb_entry; | ||
3900 | struct ddb_entry *ddb_entry = NULL; | ||
3901 | dma_addr_t fw_ddb_dma; | ||
3902 | struct iscsi_cls_session *cls_sess; | ||
3903 | struct iscsi_session *sess; | ||
3904 | struct iscsi_cls_conn *cls_conn; | ||
3905 | struct iscsi_endpoint *ep; | ||
3906 | uint16_t cmds_max = 32, tmo = 0; | ||
3907 | uint32_t initial_cmdsn = 0; | ||
3908 | struct list_head list_st, list_nt; /* List of sendtargets */ | ||
3909 | struct qla_ddb_index *st_ddb_idx, *st_ddb_idx_tmp; | ||
3910 | int fw_idx_size; | ||
3911 | unsigned long wtime; | ||
3912 | struct qla_ddb_index *nt_ddb_idx; | ||
3913 | |||
3914 | if (!test_bit(AF_LINK_UP, &ha->flags)) { | ||
3915 | set_bit(AF_BUILD_DDB_LIST, &ha->flags); | ||
3916 | ha->is_reset = is_reset; | ||
3917 | return; | ||
3918 | } | ||
3919 | max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX : | ||
3920 | MAX_DEV_DB_ENTRIES; | ||
3921 | |||
3922 | fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL, | ||
3923 | &fw_ddb_dma); | ||
3924 | if (fw_ddb_entry == NULL) { | ||
3925 | DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n")); | ||
3926 | goto exit_ddb_list; | ||
3927 | } | ||
3928 | |||
3929 | INIT_LIST_HEAD(&list_st); | ||
3930 | INIT_LIST_HEAD(&list_nt); | ||
3931 | fw_idx_size = sizeof(struct qla_ddb_index); | ||
3932 | |||
3933 | for (idx = 0; idx < max_ddbs; idx = next_idx) { | ||
3934 | ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, | ||
3935 | fw_ddb_dma, NULL, | ||
3936 | &next_idx, &state, &conn_err, | ||
3937 | NULL, &conn_id); | ||
3938 | if (ret == QLA_ERROR) | ||
3939 | break; | ||
3940 | |||
3941 | if (qla4xxx_verify_boot_idx(ha, idx) != QLA_SUCCESS) | ||
3942 | goto continue_next_st; | ||
3943 | |||
3944 | /* Check if ST, add to the list_st */ | ||
3945 | if (strlen((char *) fw_ddb_entry->iscsi_name) != 0) | ||
3946 | goto continue_next_st; | ||
3947 | |||
3948 | st_ddb_idx = vzalloc(fw_idx_size); | ||
3949 | if (!st_ddb_idx) | ||
3950 | break; | ||
3951 | |||
3952 | st_ddb_idx->fw_ddb_idx = idx; | ||
3953 | |||
3954 | list_add_tail(&st_ddb_idx->list, &list_st); | ||
3955 | continue_next_st: | ||
3956 | if (next_idx == 0) | ||
3957 | break; | ||
3958 | } | ||
3959 | |||
3960 | /* Before issuing conn open mbox, ensure all IPs states are configured | ||
3961 | * Note, conn open fails if IPs are not configured | ||
3962 | */ | ||
3963 | qla4xxx_wait_for_ip_configuration(ha); | ||
3964 | |||
3965 | /* Go thru the STs and fire the sendtargets by issuing conn open mbx */ | ||
3966 | list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) { | ||
3967 | qla4xxx_conn_open(ha, st_ddb_idx->fw_ddb_idx); | ||
3968 | } | ||
3969 | |||
3970 | /* Wait to ensure all sendtargets are done for min 12 sec wait */ | ||
3971 | tmo = ((ha->def_timeout < LOGIN_TOV) ? LOGIN_TOV : ha->def_timeout); | ||
3972 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
3973 | "Default time to wait for build ddb %d\n", tmo)); | ||
3974 | |||
3975 | wtime = jiffies + (HZ * tmo); | ||
3976 | do { | ||
3977 | list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, | ||
3978 | list) { | ||
3979 | ret = qla4xxx_get_fwddb_entry(ha, | ||
3980 | st_ddb_idx->fw_ddb_idx, | ||
3981 | NULL, 0, NULL, &next_idx, | ||
3982 | &state, &conn_err, NULL, | ||
3983 | NULL); | ||
3984 | if (ret == QLA_ERROR) | ||
3985 | continue; | ||
3986 | |||
3987 | if (state == DDB_DS_NO_CONNECTION_ACTIVE || | ||
3988 | state == DDB_DS_SESSION_FAILED) { | ||
3989 | list_del_init(&st_ddb_idx->list); | ||
3990 | vfree(st_ddb_idx); | ||
3991 | } | ||
3992 | } | ||
3993 | schedule_timeout_uninterruptible(HZ / 10); | ||
3994 | } while (time_after(wtime, jiffies)); | ||
3995 | |||
3996 | /* Free up the sendtargets list */ | ||
3997 | list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) { | ||
3998 | list_del_init(&st_ddb_idx->list); | ||
3999 | vfree(st_ddb_idx); | ||
4000 | } | ||
4001 | |||
4002 | for (idx = 0; idx < max_ddbs; idx = next_idx) { | ||
4003 | ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, | ||
4004 | fw_ddb_dma, NULL, | ||
4005 | &next_idx, &state, &conn_err, | ||
4006 | NULL, &conn_id); | ||
4007 | if (ret == QLA_ERROR) | ||
4008 | break; | ||
4009 | |||
4010 | if (qla4xxx_verify_boot_idx(ha, idx) != QLA_SUCCESS) | ||
4011 | goto continue_next_nt; | ||
4012 | |||
4013 | /* Check if NT, then add to list it */ | ||
4014 | if (strlen((char *) fw_ddb_entry->iscsi_name) == 0) | ||
4015 | goto continue_next_nt; | ||
4016 | |||
4017 | if (state == DDB_DS_NO_CONNECTION_ACTIVE || | ||
4018 | state == DDB_DS_SESSION_FAILED) { | ||
4019 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
4020 | "Adding DDB to session = 0x%x\n", | ||
4021 | idx)); | ||
4022 | if (is_reset == INIT_ADAPTER) { | ||
4023 | nt_ddb_idx = vmalloc(fw_idx_size); | ||
4024 | if (!nt_ddb_idx) | ||
4025 | break; | ||
4026 | |||
4027 | nt_ddb_idx->fw_ddb_idx = idx; | ||
4028 | |||
4029 | memcpy(&nt_ddb_idx->fw_ddb, fw_ddb_entry, | ||
4030 | sizeof(struct dev_db_entry)); | ||
4031 | |||
4032 | if (qla4xxx_is_flash_ddb_exists(ha, &list_nt, | ||
4033 | fw_ddb_entry) == QLA_SUCCESS) { | ||
4034 | vfree(nt_ddb_idx); | ||
4035 | goto continue_next_nt; | ||
4036 | } | ||
4037 | list_add_tail(&nt_ddb_idx->list, &list_nt); | ||
4038 | } else if (is_reset == RESET_ADAPTER) { | ||
4039 | if (qla4xxx_is_session_exists(ha, | ||
4040 | fw_ddb_entry) == QLA_SUCCESS) | ||
4041 | goto continue_next_nt; | ||
4042 | } | ||
4043 | |||
4044 | /* Create session object, with INVALID_ENTRY, | ||
4045 | * the targer_id would get set when we issue the login | ||
4046 | */ | ||
4047 | cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, | ||
4048 | ha->host, cmds_max, | ||
4049 | sizeof(struct ddb_entry), | ||
4050 | sizeof(struct ql4_task_data), | ||
4051 | initial_cmdsn, INVALID_ENTRY); | ||
4052 | if (!cls_sess) | ||
4053 | goto exit_ddb_list; | ||
4054 | |||
4055 | /* | ||
4056 | * iscsi_session_setup increments the driver reference | ||
4057 | * count which wouldn't let the driver to be unloaded. | ||
4058 | * so calling module_put function to decrement the | ||
4059 | * reference count. | ||
4060 | **/ | ||
4061 | module_put(qla4xxx_iscsi_transport.owner); | ||
4062 | sess = cls_sess->dd_data; | ||
4063 | ddb_entry = sess->dd_data; | ||
4064 | ddb_entry->sess = cls_sess; | ||
4065 | |||
4066 | cls_sess->recovery_tmo = ql4xsess_recovery_tmo; | ||
4067 | memcpy(&ddb_entry->fw_ddb_entry, fw_ddb_entry, | ||
4068 | sizeof(struct dev_db_entry)); | ||
4069 | |||
4070 | qla4xxx_setup_flash_ddb_entry(ha, ddb_entry); | ||
4071 | |||
4072 | cls_conn = iscsi_conn_setup(cls_sess, | ||
4073 | sizeof(struct qla_conn), | ||
4074 | conn_id); | ||
4075 | if (!cls_conn) | ||
4076 | goto exit_ddb_list; | ||
4077 | |||
4078 | ddb_entry->conn = cls_conn; | ||
4079 | |||
4080 | /* Setup ep, for displaying attributes in sysfs */ | ||
4081 | ep = qla4xxx_get_ep_fwdb(ha, fw_ddb_entry); | ||
4082 | if (ep) { | ||
4083 | ep->conn = cls_conn; | ||
4084 | cls_conn->ep = ep; | ||
4085 | } else { | ||
4086 | DEBUG2(ql4_printk(KERN_ERR, ha, | ||
4087 | "Unable to get ep\n")); | ||
4088 | } | ||
4089 | |||
4090 | /* Update sess/conn params */ | ||
4091 | qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, | ||
4092 | cls_conn); | ||
4093 | |||
4094 | if (is_reset == RESET_ADAPTER) { | ||
4095 | iscsi_block_session(cls_sess); | ||
4096 | /* Use the relogin path to discover new devices | ||
4097 | * by short-circuting the logic of setting | ||
4098 | * timer to relogin - instead set the flags | ||
4099 | * to initiate login right away. | ||
4100 | */ | ||
4101 | set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags); | ||
4102 | set_bit(DF_RELOGIN, &ddb_entry->flags); | ||
4103 | } | ||
4104 | } | ||
4105 | continue_next_nt: | ||
4106 | if (next_idx == 0) | ||
4107 | break; | ||
4108 | } | ||
4109 | exit_ddb_list: | ||
4110 | qla4xxx_free_nt_list(&list_nt); | ||
4111 | if (fw_ddb_entry) | ||
4112 | dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma); | ||
4113 | |||
4114 | qla4xxx_free_ddb_index(ha); | ||
4115 | } | ||
4116 | |||
4117 | |||
3180 | /** | 4118 | /** |
3181 | * qla4xxx_probe_adapter - callback function to probe HBA | 4119 | * qla4xxx_probe_adapter - callback function to probe HBA |
3182 | * @pdev: pointer to pci_dev structure | 4120 | * @pdev: pointer to pci_dev structure |
@@ -3298,7 +4236,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
3298 | * firmware | 4236 | * firmware |
3299 | * NOTE: interrupts enabled upon successful completion | 4237 | * NOTE: interrupts enabled upon successful completion |
3300 | */ | 4238 | */ |
3301 | status = qla4xxx_initialize_adapter(ha); | 4239 | status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER); |
3302 | while ((!test_bit(AF_ONLINE, &ha->flags)) && | 4240 | while ((!test_bit(AF_ONLINE, &ha->flags)) && |
3303 | init_retry_count++ < MAX_INIT_RETRIES) { | 4241 | init_retry_count++ < MAX_INIT_RETRIES) { |
3304 | 4242 | ||
@@ -3319,7 +4257,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
3319 | if (ha->isp_ops->reset_chip(ha) == QLA_ERROR) | 4257 | if (ha->isp_ops->reset_chip(ha) == QLA_ERROR) |
3320 | continue; | 4258 | continue; |
3321 | 4259 | ||
3322 | status = qla4xxx_initialize_adapter(ha); | 4260 | status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER); |
3323 | } | 4261 | } |
3324 | 4262 | ||
3325 | if (!test_bit(AF_ONLINE, &ha->flags)) { | 4263 | if (!test_bit(AF_ONLINE, &ha->flags)) { |
@@ -3386,12 +4324,16 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
3386 | ha->host_no, ha->firmware_version[0], ha->firmware_version[1], | 4324 | ha->host_no, ha->firmware_version[0], ha->firmware_version[1], |
3387 | ha->patch_number, ha->build_number); | 4325 | ha->patch_number, ha->build_number); |
3388 | 4326 | ||
3389 | qla4xxx_create_chap_list(ha); | ||
3390 | |||
3391 | if (qla4xxx_setup_boot_info(ha)) | 4327 | if (qla4xxx_setup_boot_info(ha)) |
3392 | ql4_printk(KERN_ERR, ha, "%s:ISCSI boot info setup failed\n", | 4328 | ql4_printk(KERN_ERR, ha, "%s:ISCSI boot info setup failed\n", |
3393 | __func__); | 4329 | __func__); |
3394 | 4330 | ||
4331 | /* Perform the build ddb list and login to each */ | ||
4332 | qla4xxx_build_ddb_list(ha, INIT_ADAPTER); | ||
4333 | iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb); | ||
4334 | |||
4335 | qla4xxx_create_chap_list(ha); | ||
4336 | |||
3395 | qla4xxx_create_ifaces(ha); | 4337 | qla4xxx_create_ifaces(ha); |
3396 | return 0; | 4338 | return 0; |
3397 | 4339 | ||
@@ -3449,6 +4391,38 @@ static void qla4xxx_prevent_other_port_reinit(struct scsi_qla_host *ha) | |||
3449 | } | 4391 | } |
3450 | } | 4392 | } |
3451 | 4393 | ||
4394 | static void qla4xxx_destroy_fw_ddb_session(struct scsi_qla_host *ha) | ||
4395 | { | ||
4396 | struct ddb_entry *ddb_entry; | ||
4397 | int options; | ||
4398 | int idx; | ||
4399 | |||
4400 | for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) { | ||
4401 | |||
4402 | ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx); | ||
4403 | if ((ddb_entry != NULL) && | ||
4404 | (ddb_entry->ddb_type == FLASH_DDB)) { | ||
4405 | |||
4406 | options = LOGOUT_OPTION_CLOSE_SESSION; | ||
4407 | if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) | ||
4408 | == QLA_ERROR) | ||
4409 | ql4_printk(KERN_ERR, ha, "%s: Logout failed\n", | ||
4410 | __func__); | ||
4411 | |||
4412 | qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index); | ||
4413 | /* | ||
4414 | * we have decremented the reference count of the driver | ||
4415 | * when we setup the session to have the driver unload | ||
4416 | * to be seamless without actually destroying the | ||
4417 | * session | ||
4418 | **/ | ||
4419 | try_module_get(qla4xxx_iscsi_transport.owner); | ||
4420 | iscsi_destroy_endpoint(ddb_entry->conn->ep); | ||
4421 | qla4xxx_free_ddb(ha, ddb_entry); | ||
4422 | iscsi_session_teardown(ddb_entry->sess); | ||
4423 | } | ||
4424 | } | ||
4425 | } | ||
3452 | /** | 4426 | /** |
3453 | * qla4xxx_remove_adapter - calback function to remove adapter. | 4427 | * qla4xxx_remove_adapter - calback function to remove adapter. |
3454 | * @pci_dev: PCI device pointer | 4428 | * @pci_dev: PCI device pointer |
@@ -3465,9 +4439,11 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev) | |||
3465 | /* destroy iface from sysfs */ | 4439 | /* destroy iface from sysfs */ |
3466 | qla4xxx_destroy_ifaces(ha); | 4440 | qla4xxx_destroy_ifaces(ha); |
3467 | 4441 | ||
3468 | if (ha->boot_kset) | 4442 | if ((!ql4xdisablesysfsboot) && ha->boot_kset) |
3469 | iscsi_boot_destroy_kset(ha->boot_kset); | 4443 | iscsi_boot_destroy_kset(ha->boot_kset); |
3470 | 4444 | ||
4445 | qla4xxx_destroy_fw_ddb_session(ha); | ||
4446 | |||
3471 | scsi_remove_host(ha->host); | 4447 | scsi_remove_host(ha->host); |
3472 | 4448 | ||
3473 | qla4xxx_free_adapter(ha); | 4449 | qla4xxx_free_adapter(ha); |
@@ -4115,7 +5091,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha) | |||
4115 | 5091 | ||
4116 | qla4_8xxx_idc_unlock(ha); | 5092 | qla4_8xxx_idc_unlock(ha); |
4117 | clear_bit(AF_FW_RECOVERY, &ha->flags); | 5093 | clear_bit(AF_FW_RECOVERY, &ha->flags); |
4118 | rval = qla4xxx_initialize_adapter(ha); | 5094 | rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); |
4119 | qla4_8xxx_idc_lock(ha); | 5095 | qla4_8xxx_idc_lock(ha); |
4120 | 5096 | ||
4121 | if (rval != QLA_SUCCESS) { | 5097 | if (rval != QLA_SUCCESS) { |
@@ -4151,7 +5127,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha) | |||
4151 | if ((qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == | 5127 | if ((qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == |
4152 | QLA82XX_DEV_READY)) { | 5128 | QLA82XX_DEV_READY)) { |
4153 | clear_bit(AF_FW_RECOVERY, &ha->flags); | 5129 | clear_bit(AF_FW_RECOVERY, &ha->flags); |
4154 | rval = qla4xxx_initialize_adapter(ha); | 5130 | rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER); |
4155 | if (rval == QLA_SUCCESS) { | 5131 | if (rval == QLA_SUCCESS) { |
4156 | ret = qla4xxx_request_irqs(ha); | 5132 | ret = qla4xxx_request_irqs(ha); |
4157 | if (ret) { | 5133 | if (ret) { |
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h index c15347d3f532..5254e57968f5 100644 --- a/drivers/scsi/qla4xxx/ql4_version.h +++ b/drivers/scsi/qla4xxx/ql4_version.h | |||
@@ -5,4 +5,4 @@ | |||
5 | * See LICENSE.qla4xxx for copyright and licensing details. | 5 | * See LICENSE.qla4xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #define QLA4XXX_DRIVER_VERSION "5.02.00-k8" | 8 | #define QLA4XXX_DRIVER_VERSION "5.02.00-k9" |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a1fd73df5416..8ba4510a9519 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -199,7 +199,7 @@ config SPI_FSL_LIB | |||
199 | depends on FSL_SOC | 199 | depends on FSL_SOC |
200 | 200 | ||
201 | config SPI_FSL_SPI | 201 | config SPI_FSL_SPI |
202 | tristate "Freescale SPI controller" | 202 | bool "Freescale SPI controller" |
203 | depends on FSL_SOC | 203 | depends on FSL_SOC |
204 | select SPI_FSL_LIB | 204 | select SPI_FSL_LIB |
205 | help | 205 | help |
@@ -208,7 +208,7 @@ config SPI_FSL_SPI | |||
208 | MPC8569 uses the controller in QE mode, MPC8610 in cpu mode. | 208 | MPC8569 uses the controller in QE mode, MPC8610 in cpu mode. |
209 | 209 | ||
210 | config SPI_FSL_ESPI | 210 | config SPI_FSL_ESPI |
211 | tristate "Freescale eSPI controller" | 211 | bool "Freescale eSPI controller" |
212 | depends on FSL_SOC | 212 | depends on FSL_SOC |
213 | select SPI_FSL_LIB | 213 | select SPI_FSL_LIB |
214 | help | 214 | help |
diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 024b48aed5ca..acc88b4d2869 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c | |||
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | ||
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
17 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
18 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index e093d3ec41ba..0094c645ff0d 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
@@ -256,7 +256,7 @@ static void spi_gpio_cleanup(struct spi_device *spi) | |||
256 | spi_bitbang_cleanup(spi); | 256 | spi_bitbang_cleanup(spi); |
257 | } | 257 | } |
258 | 258 | ||
259 | static int __init spi_gpio_alloc(unsigned pin, const char *label, bool is_in) | 259 | static int __devinit spi_gpio_alloc(unsigned pin, const char *label, bool is_in) |
260 | { | 260 | { |
261 | int value; | 261 | int value; |
262 | 262 | ||
@@ -270,7 +270,7 @@ static int __init spi_gpio_alloc(unsigned pin, const char *label, bool is_in) | |||
270 | return value; | 270 | return value; |
271 | } | 271 | } |
272 | 272 | ||
273 | static int __init | 273 | static int __devinit |
274 | spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label, | 274 | spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label, |
275 | u16 *res_flags) | 275 | u16 *res_flags) |
276 | { | 276 | { |
diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index 21c70b2b8311..182e9c873822 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
13 | #include <linux/workqueue.h> | 14 | #include <linux/workqueue.h> |
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index fb2e89c3056c..5385da2e9cdb 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c | |||
@@ -89,6 +89,7 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = { | |||
89 | {USB_DEVICE(0x0DF6, 0x0045)}, | 89 | {USB_DEVICE(0x0DF6, 0x0045)}, |
90 | {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */ | 90 | {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */ |
91 | {USB_DEVICE(0x0DF6, 0x004B)}, | 91 | {USB_DEVICE(0x0DF6, 0x004B)}, |
92 | {USB_DEVICE(0x0DF6, 0x005D)}, | ||
92 | {USB_DEVICE(0x0DF6, 0x0063)}, | 93 | {USB_DEVICE(0x0DF6, 0x0063)}, |
93 | /* Sweex */ | 94 | /* Sweex */ |
94 | {USB_DEVICE(0x177F, 0x0154)}, | 95 | {USB_DEVICE(0x177F, 0x0154)}, |
diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c index 3d1279c424a8..7eb56178fb64 100644 --- a/drivers/staging/tidspbridge/core/dsp-clock.c +++ b/drivers/staging/tidspbridge/core/dsp-clock.c | |||
@@ -54,6 +54,7 @@ | |||
54 | 54 | ||
55 | /* Bridge GPT id (1 - 4), DM Timer id (5 - 8) */ | 55 | /* Bridge GPT id (1 - 4), DM Timer id (5 - 8) */ |
56 | #define DMT_ID(id) ((id) + 4) | 56 | #define DMT_ID(id) ((id) + 4) |
57 | #define DM_TIMER_CLOCKS 4 | ||
57 | 58 | ||
58 | /* Bridge MCBSP id (6 - 10), OMAP Mcbsp id (0 - 4) */ | 59 | /* Bridge MCBSP id (6 - 10), OMAP Mcbsp id (0 - 4) */ |
59 | #define MCBSP_ID(id) ((id) - 6) | 60 | #define MCBSP_ID(id) ((id) - 6) |
@@ -114,8 +115,13 @@ static s8 get_clk_type(u8 id) | |||
114 | */ | 115 | */ |
115 | void dsp_clk_exit(void) | 116 | void dsp_clk_exit(void) |
116 | { | 117 | { |
118 | int i; | ||
119 | |||
117 | dsp_clock_disable_all(dsp_clocks); | 120 | dsp_clock_disable_all(dsp_clocks); |
118 | 121 | ||
122 | for (i = 0; i < DM_TIMER_CLOCKS; i++) | ||
123 | omap_dm_timer_free(timer[i]); | ||
124 | |||
119 | clk_put(iva2_clk); | 125 | clk_put(iva2_clk); |
120 | clk_put(ssi.sst_fck); | 126 | clk_put(ssi.sst_fck); |
121 | clk_put(ssi.ssr_fck); | 127 | clk_put(ssi.ssr_fck); |
@@ -130,9 +136,13 @@ void dsp_clk_exit(void) | |||
130 | void dsp_clk_init(void) | 136 | void dsp_clk_init(void) |
131 | { | 137 | { |
132 | static struct platform_device dspbridge_device; | 138 | static struct platform_device dspbridge_device; |
139 | int i, id; | ||
133 | 140 | ||
134 | dspbridge_device.dev.bus = &platform_bus_type; | 141 | dspbridge_device.dev.bus = &platform_bus_type; |
135 | 142 | ||
143 | for (i = 0, id = 5; i < DM_TIMER_CLOCKS; i++, id++) | ||
144 | timer[i] = omap_dm_timer_request_specific(id); | ||
145 | |||
136 | iva2_clk = clk_get(&dspbridge_device.dev, "iva2_ck"); | 146 | iva2_clk = clk_get(&dspbridge_device.dev, "iva2_ck"); |
137 | if (IS_ERR(iva2_clk)) | 147 | if (IS_ERR(iva2_clk)) |
138 | dev_err(bridge, "failed to get iva2 clock %p\n", iva2_clk); | 148 | dev_err(bridge, "failed to get iva2 clock %p\n", iva2_clk); |
@@ -204,8 +214,7 @@ int dsp_clk_enable(enum dsp_clk_id clk_id) | |||
204 | clk_enable(iva2_clk); | 214 | clk_enable(iva2_clk); |
205 | break; | 215 | break; |
206 | case GPT_CLK: | 216 | case GPT_CLK: |
207 | timer[clk_id - 1] = | 217 | status = omap_dm_timer_start(timer[clk_id - 1]); |
208 | omap_dm_timer_request_specific(DMT_ID(clk_id)); | ||
209 | break; | 218 | break; |
210 | #ifdef CONFIG_OMAP_MCBSP | 219 | #ifdef CONFIG_OMAP_MCBSP |
211 | case MCBSP_CLK: | 220 | case MCBSP_CLK: |
@@ -281,7 +290,7 @@ int dsp_clk_disable(enum dsp_clk_id clk_id) | |||
281 | clk_disable(iva2_clk); | 290 | clk_disable(iva2_clk); |
282 | break; | 291 | break; |
283 | case GPT_CLK: | 292 | case GPT_CLK: |
284 | omap_dm_timer_free(timer[clk_id - 1]); | 293 | status = omap_dm_timer_stop(timer[clk_id - 1]); |
285 | break; | 294 | break; |
286 | #ifdef CONFIG_OMAP_MCBSP | 295 | #ifdef CONFIG_OMAP_MCBSP |
287 | case MCBSP_CLK: | 296 | case MCBSP_CLK: |
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index c43c7e3421c8..76cfc6edecd9 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c | |||
@@ -24,11 +24,7 @@ | |||
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/pm.h> | 26 | #include <linux/pm.h> |
27 | |||
28 | #ifdef MODULE | ||
29 | #include <linux/module.h> | 27 | #include <linux/module.h> |
30 | #endif | ||
31 | |||
32 | #include <linux/device.h> | 28 | #include <linux/device.h> |
33 | #include <linux/init.h> | 29 | #include <linux/init.h> |
34 | #include <linux/moduleparam.h> | 30 | #include <linux/moduleparam.h> |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 0fd96c10271d..8599545cdf9e 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -614,13 +614,12 @@ int iscsit_add_reject( | |||
614 | hdr = (struct iscsi_reject *) cmd->pdu; | 614 | hdr = (struct iscsi_reject *) cmd->pdu; |
615 | hdr->reason = reason; | 615 | hdr->reason = reason; |
616 | 616 | ||
617 | cmd->buf_ptr = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); | 617 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
618 | if (!cmd->buf_ptr) { | 618 | if (!cmd->buf_ptr) { |
619 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); | 619 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); |
620 | iscsit_release_cmd(cmd); | 620 | iscsit_release_cmd(cmd); |
621 | return -1; | 621 | return -1; |
622 | } | 622 | } |
623 | memcpy(cmd->buf_ptr, buf, ISCSI_HDR_LEN); | ||
624 | 623 | ||
625 | spin_lock_bh(&conn->cmd_lock); | 624 | spin_lock_bh(&conn->cmd_lock); |
626 | list_add_tail(&cmd->i_list, &conn->conn_cmd_list); | 625 | list_add_tail(&cmd->i_list, &conn->conn_cmd_list); |
@@ -661,13 +660,12 @@ int iscsit_add_reject_from_cmd( | |||
661 | hdr = (struct iscsi_reject *) cmd->pdu; | 660 | hdr = (struct iscsi_reject *) cmd->pdu; |
662 | hdr->reason = reason; | 661 | hdr->reason = reason; |
663 | 662 | ||
664 | cmd->buf_ptr = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); | 663 | cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL); |
665 | if (!cmd->buf_ptr) { | 664 | if (!cmd->buf_ptr) { |
666 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); | 665 | pr_err("Unable to allocate memory for cmd->buf_ptr\n"); |
667 | iscsit_release_cmd(cmd); | 666 | iscsit_release_cmd(cmd); |
668 | return -1; | 667 | return -1; |
669 | } | 668 | } |
670 | memcpy(cmd->buf_ptr, buf, ISCSI_HDR_LEN); | ||
671 | 669 | ||
672 | if (add_to_conn) { | 670 | if (add_to_conn) { |
673 | spin_lock_bh(&conn->cmd_lock); | 671 | spin_lock_bh(&conn->cmd_lock); |
@@ -1017,11 +1015,6 @@ done: | |||
1017 | " non-existent or non-exported iSCSI LUN:" | 1015 | " non-existent or non-exported iSCSI LUN:" |
1018 | " 0x%016Lx\n", get_unaligned_le64(&hdr->lun)); | 1016 | " 0x%016Lx\n", get_unaligned_le64(&hdr->lun)); |
1019 | } | 1017 | } |
1020 | if (ret == PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES) | ||
1021 | return iscsit_add_reject_from_cmd( | ||
1022 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | ||
1023 | 1, 1, buf, cmd); | ||
1024 | |||
1025 | send_check_condition = 1; | 1018 | send_check_condition = 1; |
1026 | goto attach_cmd; | 1019 | goto attach_cmd; |
1027 | } | 1020 | } |
@@ -1044,6 +1037,8 @@ done: | |||
1044 | */ | 1037 | */ |
1045 | send_check_condition = 1; | 1038 | send_check_condition = 1; |
1046 | } else { | 1039 | } else { |
1040 | cmd->data_length = cmd->se_cmd.data_length; | ||
1041 | |||
1047 | if (iscsit_decide_list_to_build(cmd, payload_length) < 0) | 1042 | if (iscsit_decide_list_to_build(cmd, payload_length) < 0) |
1048 | return iscsit_add_reject_from_cmd( | 1043 | return iscsit_add_reject_from_cmd( |
1049 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1044 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
@@ -1123,7 +1118,7 @@ attach_cmd: | |||
1123 | * the backend memory allocation. | 1118 | * the backend memory allocation. |
1124 | */ | 1119 | */ |
1125 | ret = transport_generic_new_cmd(&cmd->se_cmd); | 1120 | ret = transport_generic_new_cmd(&cmd->se_cmd); |
1126 | if ((ret < 0) || (cmd->se_cmd.se_cmd_flags & SCF_SE_CMD_FAILED)) { | 1121 | if (ret < 0) { |
1127 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; | 1122 | immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION; |
1128 | dump_immediate_data = 1; | 1123 | dump_immediate_data = 1; |
1129 | goto after_immediate_data; | 1124 | goto after_immediate_data; |
@@ -1341,7 +1336,7 @@ static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | |||
1341 | 1336 | ||
1342 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); | 1337 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); |
1343 | if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) || | 1338 | if (!(se_cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) || |
1344 | (se_cmd->se_cmd_flags & SCF_SE_CMD_FAILED)) | 1339 | (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION)) |
1345 | dump_unsolicited_data = 1; | 1340 | dump_unsolicited_data = 1; |
1346 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); | 1341 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); |
1347 | 1342 | ||
@@ -2513,10 +2508,10 @@ static int iscsit_send_data_in( | |||
2513 | if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { | 2508 | if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { |
2514 | if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { | 2509 | if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { |
2515 | hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW; | 2510 | hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW; |
2516 | hdr->residual_count = cpu_to_be32(cmd->residual_count); | 2511 | hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); |
2517 | } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { | 2512 | } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { |
2518 | hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW; | 2513 | hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW; |
2519 | hdr->residual_count = cpu_to_be32(cmd->residual_count); | 2514 | hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); |
2520 | } | 2515 | } |
2521 | } | 2516 | } |
2522 | hton24(hdr->dlength, datain.length); | 2517 | hton24(hdr->dlength, datain.length); |
@@ -3018,10 +3013,10 @@ static int iscsit_send_status( | |||
3018 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | 3013 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; |
3019 | if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { | 3014 | if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { |
3020 | hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW; | 3015 | hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW; |
3021 | hdr->residual_count = cpu_to_be32(cmd->residual_count); | 3016 | hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); |
3022 | } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { | 3017 | } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { |
3023 | hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW; | 3018 | hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW; |
3024 | hdr->residual_count = cpu_to_be32(cmd->residual_count); | 3019 | hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); |
3025 | } | 3020 | } |
3026 | hdr->response = cmd->iscsi_response; | 3021 | hdr->response = cmd->iscsi_response; |
3027 | hdr->cmd_status = cmd->se_cmd.scsi_status; | 3022 | hdr->cmd_status = cmd->se_cmd.scsi_status; |
@@ -3133,6 +3128,7 @@ static int iscsit_send_task_mgt_rsp( | |||
3133 | hdr = (struct iscsi_tm_rsp *) cmd->pdu; | 3128 | hdr = (struct iscsi_tm_rsp *) cmd->pdu; |
3134 | memset(hdr, 0, ISCSI_HDR_LEN); | 3129 | memset(hdr, 0, ISCSI_HDR_LEN); |
3135 | hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; | 3130 | hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; |
3131 | hdr->flags = ISCSI_FLAG_CMD_FINAL; | ||
3136 | hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr); | 3132 | hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr); |
3137 | hdr->itt = cpu_to_be32(cmd->init_task_tag); | 3133 | hdr->itt = cpu_to_be32(cmd->init_task_tag); |
3138 | cmd->stat_sn = conn->stat_sn++; | 3134 | cmd->stat_sn = conn->stat_sn++; |
diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c index beb39469e7f1..1cd6ce373b83 100644 --- a/drivers/target/iscsi/iscsi_target_auth.c +++ b/drivers/target/iscsi/iscsi_target_auth.c | |||
@@ -30,9 +30,11 @@ | |||
30 | 30 | ||
31 | static int chap_string_to_hex(unsigned char *dst, unsigned char *src, int len) | 31 | static int chap_string_to_hex(unsigned char *dst, unsigned char *src, int len) |
32 | { | 32 | { |
33 | int j = DIV_ROUND_UP(len, 2); | 33 | int j = DIV_ROUND_UP(len, 2), rc; |
34 | 34 | ||
35 | hex2bin(dst, src, j); | 35 | rc = hex2bin(dst, src, j); |
36 | if (rc < 0) | ||
37 | pr_debug("CHAP string contains non hex digit symbols\n"); | ||
36 | 38 | ||
37 | dst[j] = '\0'; | 39 | dst[j] = '\0'; |
38 | return j; | 40 | return j; |
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 3723d90d5ae5..f1a02dad05a0 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h | |||
@@ -398,7 +398,6 @@ struct iscsi_cmd { | |||
398 | u32 pdu_send_order; | 398 | u32 pdu_send_order; |
399 | /* Current struct iscsi_pdu in struct iscsi_cmd->pdu_list */ | 399 | /* Current struct iscsi_pdu in struct iscsi_cmd->pdu_list */ |
400 | u32 pdu_start; | 400 | u32 pdu_start; |
401 | u32 residual_count; | ||
402 | /* Next struct iscsi_seq to send in struct iscsi_cmd->seq_list */ | 401 | /* Next struct iscsi_seq to send in struct iscsi_cmd->seq_list */ |
403 | u32 seq_send_order; | 402 | u32 seq_send_order; |
404 | /* Number of struct iscsi_seq in struct iscsi_cmd->seq_list */ | 403 | /* Number of struct iscsi_seq in struct iscsi_cmd->seq_list */ |
@@ -535,7 +534,6 @@ struct iscsi_conn { | |||
535 | atomic_t connection_exit; | 534 | atomic_t connection_exit; |
536 | atomic_t connection_recovery; | 535 | atomic_t connection_recovery; |
537 | atomic_t connection_reinstatement; | 536 | atomic_t connection_reinstatement; |
538 | atomic_t connection_wait; | ||
539 | atomic_t connection_wait_rcfr; | 537 | atomic_t connection_wait_rcfr; |
540 | atomic_t sleep_on_conn_wait_comp; | 538 | atomic_t sleep_on_conn_wait_comp; |
541 | atomic_t transport_failed; | 539 | atomic_t transport_failed; |
@@ -643,7 +641,6 @@ struct iscsi_session { | |||
643 | atomic_t session_reinstatement; | 641 | atomic_t session_reinstatement; |
644 | atomic_t session_stop_active; | 642 | atomic_t session_stop_active; |
645 | atomic_t sleep_on_sess_wait_comp; | 643 | atomic_t sleep_on_sess_wait_comp; |
646 | atomic_t transport_wait_cmds; | ||
647 | /* connection list */ | 644 | /* connection list */ |
648 | struct list_head sess_conn_list; | 645 | struct list_head sess_conn_list; |
649 | struct list_head cr_active_list; | 646 | struct list_head cr_active_list; |
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c index c4c68da3e500..101b1beb3bca 100644 --- a/drivers/target/iscsi/iscsi_target_erl1.c +++ b/drivers/target/iscsi/iscsi_target_erl1.c | |||
@@ -938,8 +938,7 @@ int iscsit_execute_cmd(struct iscsi_cmd *cmd, int ooo) | |||
938 | * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well. | 938 | * handle the SCF_SCSI_RESERVATION_CONFLICT case here as well. |
939 | */ | 939 | */ |
940 | if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { | 940 | if (se_cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION) { |
941 | if (se_cmd->se_cmd_flags & | 941 | if (se_cmd->scsi_sense_reason == TCM_RESERVATION_CONFLICT) { |
942 | SCF_SCSI_RESERVATION_CONFLICT) { | ||
943 | cmd->i_state = ISTATE_SEND_STATUS; | 942 | cmd->i_state = ISTATE_SEND_STATUS; |
944 | spin_unlock_bh(&cmd->istate_lock); | 943 | spin_unlock_bh(&cmd->istate_lock); |
945 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, | 944 | iscsit_add_cmd_to_response_queue(cmd, cmd->conn, |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index daad362a93ce..d734bdec24f9 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -224,7 +224,7 @@ static int iscsi_login_zero_tsih_s1( | |||
224 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | 224 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, |
225 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | 225 | ISCSI_LOGIN_STATUS_NO_RESOURCES); |
226 | pr_err("Could not allocate memory for session\n"); | 226 | pr_err("Could not allocate memory for session\n"); |
227 | return -1; | 227 | return -ENOMEM; |
228 | } | 228 | } |
229 | 229 | ||
230 | iscsi_login_set_conn_values(sess, conn, pdu->cid); | 230 | iscsi_login_set_conn_values(sess, conn, pdu->cid); |
@@ -250,7 +250,8 @@ static int iscsi_login_zero_tsih_s1( | |||
250 | pr_err("idr_pre_get() for sess_idr failed\n"); | 250 | pr_err("idr_pre_get() for sess_idr failed\n"); |
251 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | 251 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, |
252 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | 252 | ISCSI_LOGIN_STATUS_NO_RESOURCES); |
253 | return -1; | 253 | kfree(sess); |
254 | return -ENOMEM; | ||
254 | } | 255 | } |
255 | spin_lock(&sess_idr_lock); | 256 | spin_lock(&sess_idr_lock); |
256 | idr_get_new(&sess_idr, NULL, &sess->session_index); | 257 | idr_get_new(&sess_idr, NULL, &sess->session_index); |
@@ -270,14 +271,16 @@ static int iscsi_login_zero_tsih_s1( | |||
270 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | 271 | ISCSI_LOGIN_STATUS_NO_RESOURCES); |
271 | pr_err("Unable to allocate memory for" | 272 | pr_err("Unable to allocate memory for" |
272 | " struct iscsi_sess_ops.\n"); | 273 | " struct iscsi_sess_ops.\n"); |
273 | return -1; | 274 | kfree(sess); |
275 | return -ENOMEM; | ||
274 | } | 276 | } |
275 | 277 | ||
276 | sess->se_sess = transport_init_session(); | 278 | sess->se_sess = transport_init_session(); |
277 | if (!sess->se_sess) { | 279 | if (IS_ERR(sess->se_sess)) { |
278 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | 280 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, |
279 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | 281 | ISCSI_LOGIN_STATUS_NO_RESOURCES); |
280 | return -1; | 282 | kfree(sess); |
283 | return -ENOMEM; | ||
281 | } | 284 | } |
282 | 285 | ||
283 | return 0; | 286 | return 0; |
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 426cd4bf6a9a..98936cb7c294 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c | |||
@@ -981,14 +981,13 @@ struct iscsi_login *iscsi_target_init_negotiation( | |||
981 | return NULL; | 981 | return NULL; |
982 | } | 982 | } |
983 | 983 | ||
984 | login->req = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); | 984 | login->req = kmemdup(login_pdu, ISCSI_HDR_LEN, GFP_KERNEL); |
985 | if (!login->req) { | 985 | if (!login->req) { |
986 | pr_err("Unable to allocate memory for Login Request.\n"); | 986 | pr_err("Unable to allocate memory for Login Request.\n"); |
987 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | 987 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, |
988 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | 988 | ISCSI_LOGIN_STATUS_NO_RESOURCES); |
989 | goto out; | 989 | goto out; |
990 | } | 990 | } |
991 | memcpy(login->req, login_pdu, ISCSI_HDR_LEN); | ||
992 | 991 | ||
993 | login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL); | 992 | login->req_buf = kzalloc(MAX_KEY_VALUE_PAIRS, GFP_KERNEL); |
994 | if (!login->req_buf) { | 993 | if (!login->req_buf) { |
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 3df1c9b8ae6b..81d5832fbbd5 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c | |||
@@ -113,11 +113,9 @@ static struct se_cmd *tcm_loop_allocate_core_cmd( | |||
113 | scsi_bufflen(sc), sc->sc_data_direction, sam_task_attr, | 113 | scsi_bufflen(sc), sc->sc_data_direction, sam_task_attr, |
114 | &tl_cmd->tl_sense_buf[0]); | 114 | &tl_cmd->tl_sense_buf[0]); |
115 | 115 | ||
116 | /* | ||
117 | * Signal BIDI usage with T_TASK(cmd)->t_tasks_bidi | ||
118 | */ | ||
119 | if (scsi_bidi_cmnd(sc)) | 116 | if (scsi_bidi_cmnd(sc)) |
120 | se_cmd->t_tasks_bidi = 1; | 117 | se_cmd->se_cmd_flags |= SCF_BIDI; |
118 | |||
121 | /* | 119 | /* |
122 | * Locate the struct se_lun pointer and attach it to struct se_cmd | 120 | * Locate the struct se_lun pointer and attach it to struct se_cmd |
123 | */ | 121 | */ |
@@ -148,27 +146,13 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd) | |||
148 | * Allocate the necessary tasks to complete the received CDB+data | 146 | * Allocate the necessary tasks to complete the received CDB+data |
149 | */ | 147 | */ |
150 | ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd); | 148 | ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd); |
151 | if (ret == -ENOMEM) { | 149 | if (ret != 0) |
152 | /* Out of Resources */ | 150 | return ret; |
153 | return PYX_TRANSPORT_LU_COMM_FAILURE; | ||
154 | } else if (ret == -EINVAL) { | ||
155 | /* | ||
156 | * Handle case for SAM_STAT_RESERVATION_CONFLICT | ||
157 | */ | ||
158 | if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) | ||
159 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | ||
160 | /* | ||
161 | * Otherwise, return SAM_STAT_CHECK_CONDITION and return | ||
162 | * sense data. | ||
163 | */ | ||
164 | return PYX_TRANSPORT_USE_SENSE_REASON; | ||
165 | } | ||
166 | |||
167 | /* | 151 | /* |
168 | * For BIDI commands, pass in the extra READ buffer | 152 | * For BIDI commands, pass in the extra READ buffer |
169 | * to transport_generic_map_mem_to_cmd() below.. | 153 | * to transport_generic_map_mem_to_cmd() below.. |
170 | */ | 154 | */ |
171 | if (se_cmd->t_tasks_bidi) { | 155 | if (se_cmd->se_cmd_flags & SCF_BIDI) { |
172 | struct scsi_data_buffer *sdb = scsi_in(sc); | 156 | struct scsi_data_buffer *sdb = scsi_in(sc); |
173 | 157 | ||
174 | sgl_bidi = sdb->table.sgl; | 158 | sgl_bidi = sdb->table.sgl; |
@@ -194,12 +178,8 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd) | |||
194 | } | 178 | } |
195 | 179 | ||
196 | /* Tell the core about our preallocated memory */ | 180 | /* Tell the core about our preallocated memory */ |
197 | ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), | 181 | return transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc), |
198 | scsi_sg_count(sc), sgl_bidi, sgl_bidi_count); | 182 | scsi_sg_count(sc), sgl_bidi, sgl_bidi_count); |
199 | if (ret < 0) | ||
200 | return PYX_TRANSPORT_LU_COMM_FAILURE; | ||
201 | |||
202 | return 0; | ||
203 | } | 183 | } |
204 | 184 | ||
205 | /* | 185 | /* |
@@ -1360,17 +1340,16 @@ void tcm_loop_drop_scsi_hba( | |||
1360 | { | 1340 | { |
1361 | struct tcm_loop_hba *tl_hba = container_of(wwn, | 1341 | struct tcm_loop_hba *tl_hba = container_of(wwn, |
1362 | struct tcm_loop_hba, tl_hba_wwn); | 1342 | struct tcm_loop_hba, tl_hba_wwn); |
1363 | int host_no = tl_hba->sh->host_no; | 1343 | |
1344 | pr_debug("TCM_Loop_ConfigFS: Deallocating emulated Target" | ||
1345 | " SAS Address: %s at Linux/SCSI Host ID: %d\n", | ||
1346 | tl_hba->tl_wwn_address, tl_hba->sh->host_no); | ||
1364 | /* | 1347 | /* |
1365 | * Call device_unregister() on the original tl_hba->dev. | 1348 | * Call device_unregister() on the original tl_hba->dev. |
1366 | * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will | 1349 | * tcm_loop_fabric_scsi.c:tcm_loop_release_adapter() will |
1367 | * release *tl_hba; | 1350 | * release *tl_hba; |
1368 | */ | 1351 | */ |
1369 | device_unregister(&tl_hba->dev); | 1352 | device_unregister(&tl_hba->dev); |
1370 | |||
1371 | pr_debug("TCM_Loop_ConfigFS: Deallocated emulated Target" | ||
1372 | " SAS Address: %s at Linux/SCSI Host ID: %d\n", | ||
1373 | config_item_name(&wwn->wwn_group.cg_item), host_no); | ||
1374 | } | 1353 | } |
1375 | 1354 | ||
1376 | /* Start items for tcm_loop_cit */ | 1355 | /* Start items for tcm_loop_cit */ |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 88f2ad43ec8b..1dcbef499d6a 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -191,9 +191,10 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
191 | int alua_access_state, primary = 0, rc; | 191 | int alua_access_state, primary = 0, rc; |
192 | u16 tg_pt_id, rtpi; | 192 | u16 tg_pt_id, rtpi; |
193 | 193 | ||
194 | if (!l_port) | 194 | if (!l_port) { |
195 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 195 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
196 | 196 | return -EINVAL; | |
197 | } | ||
197 | buf = transport_kmap_first_data_page(cmd); | 198 | buf = transport_kmap_first_data_page(cmd); |
198 | 199 | ||
199 | /* | 200 | /* |
@@ -203,7 +204,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
203 | l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; | 204 | l_tg_pt_gp_mem = l_port->sep_alua_tg_pt_gp_mem; |
204 | if (!l_tg_pt_gp_mem) { | 205 | if (!l_tg_pt_gp_mem) { |
205 | pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); | 206 | pr_err("Unable to access l_port->sep_alua_tg_pt_gp_mem\n"); |
206 | rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 207 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
208 | rc = -EINVAL; | ||
207 | goto out; | 209 | goto out; |
208 | } | 210 | } |
209 | spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 211 | spin_lock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
@@ -211,7 +213,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
211 | if (!l_tg_pt_gp) { | 213 | if (!l_tg_pt_gp) { |
212 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); | 214 | spin_unlock(&l_tg_pt_gp_mem->tg_pt_gp_mem_lock); |
213 | pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); | 215 | pr_err("Unable to access *l_tg_pt_gp_mem->tg_pt_gp\n"); |
214 | rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 216 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
217 | rc = -EINVAL; | ||
215 | goto out; | 218 | goto out; |
216 | } | 219 | } |
217 | rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA); | 220 | rc = (l_tg_pt_gp->tg_pt_gp_alua_access_type & TPGS_EXPLICT_ALUA); |
@@ -220,7 +223,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
220 | if (!rc) { | 223 | if (!rc) { |
221 | pr_debug("Unable to process SET_TARGET_PORT_GROUPS" | 224 | pr_debug("Unable to process SET_TARGET_PORT_GROUPS" |
222 | " while TPGS_EXPLICT_ALUA is disabled\n"); | 225 | " while TPGS_EXPLICT_ALUA is disabled\n"); |
223 | rc = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 226 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
227 | rc = -EINVAL; | ||
224 | goto out; | 228 | goto out; |
225 | } | 229 | } |
226 | 230 | ||
@@ -245,7 +249,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
245 | * REQUEST, and the additional sense code set to INVALID | 249 | * REQUEST, and the additional sense code set to INVALID |
246 | * FIELD IN PARAMETER LIST. | 250 | * FIELD IN PARAMETER LIST. |
247 | */ | 251 | */ |
248 | rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 252 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
253 | rc = -EINVAL; | ||
249 | goto out; | 254 | goto out; |
250 | } | 255 | } |
251 | rc = -1; | 256 | rc = -1; |
@@ -298,7 +303,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
298 | * throw an exception with ASCQ: INVALID_PARAMETER_LIST | 303 | * throw an exception with ASCQ: INVALID_PARAMETER_LIST |
299 | */ | 304 | */ |
300 | if (rc != 0) { | 305 | if (rc != 0) { |
301 | rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 306 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
307 | rc = -EINVAL; | ||
302 | goto out; | 308 | goto out; |
303 | } | 309 | } |
304 | } else { | 310 | } else { |
@@ -335,7 +341,8 @@ int target_emulate_set_target_port_groups(struct se_task *task) | |||
335 | * INVALID_PARAMETER_LIST | 341 | * INVALID_PARAMETER_LIST |
336 | */ | 342 | */ |
337 | if (rc != 0) { | 343 | if (rc != 0) { |
338 | rc = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 344 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
345 | rc = -EINVAL; | ||
339 | goto out; | 346 | goto out; |
340 | } | 347 | } |
341 | } | 348 | } |
@@ -1184,7 +1191,6 @@ void core_alua_free_lu_gp(struct t10_alua_lu_gp *lu_gp) | |||
1184 | * struct t10_alua_lu_gp. | 1191 | * struct t10_alua_lu_gp. |
1185 | */ | 1192 | */ |
1186 | spin_lock(&lu_gps_lock); | 1193 | spin_lock(&lu_gps_lock); |
1187 | atomic_set(&lu_gp->lu_gp_shutdown, 1); | ||
1188 | list_del(&lu_gp->lu_gp_node); | 1194 | list_del(&lu_gp->lu_gp_node); |
1189 | alua_lu_gps_count--; | 1195 | alua_lu_gps_count--; |
1190 | spin_unlock(&lu_gps_lock); | 1196 | spin_unlock(&lu_gps_lock); |
@@ -1438,7 +1444,6 @@ struct t10_alua_tg_pt_gp_member *core_alua_allocate_tg_pt_gp_mem( | |||
1438 | 1444 | ||
1439 | tg_pt_gp_mem->tg_pt = port; | 1445 | tg_pt_gp_mem->tg_pt = port; |
1440 | port->sep_alua_tg_pt_gp_mem = tg_pt_gp_mem; | 1446 | port->sep_alua_tg_pt_gp_mem = tg_pt_gp_mem; |
1441 | atomic_set(&port->sep_tg_pt_gp_active, 1); | ||
1442 | 1447 | ||
1443 | return tg_pt_gp_mem; | 1448 | return tg_pt_gp_mem; |
1444 | } | 1449 | } |
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 683ba02b8247..831468b3163d 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c | |||
@@ -478,7 +478,7 @@ target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) | |||
478 | if (cmd->data_length < 60) | 478 | if (cmd->data_length < 60) |
479 | return 0; | 479 | return 0; |
480 | 480 | ||
481 | buf[2] = 0x3c; | 481 | buf[3] = 0x3c; |
482 | /* Set HEADSUP, ORDSUP, SIMPSUP */ | 482 | /* Set HEADSUP, ORDSUP, SIMPSUP */ |
483 | buf[5] = 0x07; | 483 | buf[5] = 0x07; |
484 | 484 | ||
@@ -703,6 +703,7 @@ int target_emulate_inquiry(struct se_task *task) | |||
703 | if (cmd->data_length < 4) { | 703 | if (cmd->data_length < 4) { |
704 | pr_err("SCSI Inquiry payload length: %u" | 704 | pr_err("SCSI Inquiry payload length: %u" |
705 | " too small for EVPD=1\n", cmd->data_length); | 705 | " too small for EVPD=1\n", cmd->data_length); |
706 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
706 | return -EINVAL; | 707 | return -EINVAL; |
707 | } | 708 | } |
708 | 709 | ||
@@ -719,6 +720,7 @@ int target_emulate_inquiry(struct se_task *task) | |||
719 | } | 720 | } |
720 | 721 | ||
721 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); | 722 | pr_err("Unknown VPD Code: 0x%02x\n", cdb[2]); |
723 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | ||
722 | ret = -EINVAL; | 724 | ret = -EINVAL; |
723 | 725 | ||
724 | out_unmap: | 726 | out_unmap: |
@@ -969,7 +971,8 @@ int target_emulate_modesense(struct se_task *task) | |||
969 | default: | 971 | default: |
970 | pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", | 972 | pr_err("MODE SENSE: unimplemented page/subpage: 0x%02x/0x%02x\n", |
971 | cdb[2] & 0x3f, cdb[3]); | 973 | cdb[2] & 0x3f, cdb[3]); |
972 | return PYX_TRANSPORT_UNKNOWN_MODE_PAGE; | 974 | cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE; |
975 | return -EINVAL; | ||
973 | } | 976 | } |
974 | offset += length; | 977 | offset += length; |
975 | 978 | ||
@@ -1027,7 +1030,8 @@ int target_emulate_request_sense(struct se_task *task) | |||
1027 | if (cdb[1] & 0x01) { | 1030 | if (cdb[1] & 0x01) { |
1028 | pr_err("REQUEST_SENSE description emulation not" | 1031 | pr_err("REQUEST_SENSE description emulation not" |
1029 | " supported\n"); | 1032 | " supported\n"); |
1030 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 1033 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
1034 | return -ENOSYS; | ||
1031 | } | 1035 | } |
1032 | 1036 | ||
1033 | buf = transport_kmap_first_data_page(cmd); | 1037 | buf = transport_kmap_first_data_page(cmd); |
@@ -1100,7 +1104,8 @@ int target_emulate_unmap(struct se_task *task) | |||
1100 | if (!dev->transport->do_discard) { | 1104 | if (!dev->transport->do_discard) { |
1101 | pr_err("UNMAP emulation not supported for: %s\n", | 1105 | pr_err("UNMAP emulation not supported for: %s\n", |
1102 | dev->transport->name); | 1106 | dev->transport->name); |
1103 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 1107 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
1108 | return -ENOSYS; | ||
1104 | } | 1109 | } |
1105 | 1110 | ||
1106 | /* First UNMAP block descriptor starts at 8 byte offset */ | 1111 | /* First UNMAP block descriptor starts at 8 byte offset */ |
@@ -1157,7 +1162,8 @@ int target_emulate_write_same(struct se_task *task) | |||
1157 | if (!dev->transport->do_discard) { | 1162 | if (!dev->transport->do_discard) { |
1158 | pr_err("WRITE_SAME emulation not supported" | 1163 | pr_err("WRITE_SAME emulation not supported" |
1159 | " for: %s\n", dev->transport->name); | 1164 | " for: %s\n", dev->transport->name); |
1160 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 1165 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
1166 | return -ENOSYS; | ||
1161 | } | 1167 | } |
1162 | 1168 | ||
1163 | if (cmd->t_task_cdb[0] == WRITE_SAME) | 1169 | if (cmd->t_task_cdb[0] == WRITE_SAME) |
@@ -1193,11 +1199,13 @@ int target_emulate_write_same(struct se_task *task) | |||
1193 | int target_emulate_synchronize_cache(struct se_task *task) | 1199 | int target_emulate_synchronize_cache(struct se_task *task) |
1194 | { | 1200 | { |
1195 | struct se_device *dev = task->task_se_cmd->se_dev; | 1201 | struct se_device *dev = task->task_se_cmd->se_dev; |
1202 | struct se_cmd *cmd = task->task_se_cmd; | ||
1196 | 1203 | ||
1197 | if (!dev->transport->do_sync_cache) { | 1204 | if (!dev->transport->do_sync_cache) { |
1198 | pr_err("SYNCHRONIZE_CACHE emulation not supported" | 1205 | pr_err("SYNCHRONIZE_CACHE emulation not supported" |
1199 | " for: %s\n", dev->transport->name); | 1206 | " for: %s\n", dev->transport->name); |
1200 | return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 1207 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
1208 | return -ENOSYS; | ||
1201 | } | 1209 | } |
1202 | 1210 | ||
1203 | dev->transport->do_sync_cache(task); | 1211 | dev->transport->do_sync_cache(task); |
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index e0c1e8a8dd4e..93d4f6a1b798 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
@@ -67,9 +67,6 @@ static struct config_group target_core_hbagroup; | |||
67 | static struct config_group alua_group; | 67 | static struct config_group alua_group; |
68 | static struct config_group alua_lu_gps_group; | 68 | static struct config_group alua_lu_gps_group; |
69 | 69 | ||
70 | static DEFINE_SPINLOCK(se_device_lock); | ||
71 | static LIST_HEAD(se_dev_list); | ||
72 | |||
73 | static inline struct se_hba * | 70 | static inline struct se_hba * |
74 | item_to_hba(struct config_item *item) | 71 | item_to_hba(struct config_item *item) |
75 | { | 72 | { |
@@ -2741,7 +2738,6 @@ static struct config_group *target_core_make_subdev( | |||
2741 | " struct se_subsystem_dev\n"); | 2738 | " struct se_subsystem_dev\n"); |
2742 | goto unlock; | 2739 | goto unlock; |
2743 | } | 2740 | } |
2744 | INIT_LIST_HEAD(&se_dev->se_dev_node); | ||
2745 | INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); | 2741 | INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); |
2746 | spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); | 2742 | spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); |
2747 | INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); | 2743 | INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); |
@@ -2777,9 +2773,6 @@ static struct config_group *target_core_make_subdev( | |||
2777 | " from allocate_virtdevice()\n"); | 2773 | " from allocate_virtdevice()\n"); |
2778 | goto out; | 2774 | goto out; |
2779 | } | 2775 | } |
2780 | spin_lock(&se_device_lock); | ||
2781 | list_add_tail(&se_dev->se_dev_node, &se_dev_list); | ||
2782 | spin_unlock(&se_device_lock); | ||
2783 | 2776 | ||
2784 | config_group_init_type_name(&se_dev->se_dev_group, name, | 2777 | config_group_init_type_name(&se_dev->se_dev_group, name, |
2785 | &target_core_dev_cit); | 2778 | &target_core_dev_cit); |
@@ -2874,10 +2867,6 @@ static void target_core_drop_subdev( | |||
2874 | mutex_lock(&hba->hba_access_mutex); | 2867 | mutex_lock(&hba->hba_access_mutex); |
2875 | t = hba->transport; | 2868 | t = hba->transport; |
2876 | 2869 | ||
2877 | spin_lock(&se_device_lock); | ||
2878 | list_del(&se_dev->se_dev_node); | ||
2879 | spin_unlock(&se_device_lock); | ||
2880 | |||
2881 | dev_stat_grp = &se_dev->dev_stat_grps.stat_group; | 2870 | dev_stat_grp = &se_dev->dev_stat_grps.stat_group; |
2882 | for (i = 0; dev_stat_grp->default_groups[i]; i++) { | 2871 | for (i = 0; dev_stat_grp->default_groups[i]; i++) { |
2883 | df_item = &dev_stat_grp->default_groups[i]->cg_item; | 2872 | df_item = &dev_stat_grp->default_groups[i]->cg_item; |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index ba5edec2c5f8..9b8639425472 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -104,7 +104,6 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
104 | se_cmd->se_lun = deve->se_lun; | 104 | se_cmd->se_lun = deve->se_lun; |
105 | se_cmd->pr_res_key = deve->pr_res_key; | 105 | se_cmd->pr_res_key = deve->pr_res_key; |
106 | se_cmd->orig_fe_lun = unpacked_lun; | 106 | se_cmd->orig_fe_lun = unpacked_lun; |
107 | se_cmd->se_orig_obj_ptr = se_cmd->se_lun->lun_se_dev; | ||
108 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; | 107 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; |
109 | } | 108 | } |
110 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); | 109 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); |
@@ -137,7 +136,6 @@ int transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
137 | se_lun = &se_sess->se_tpg->tpg_virt_lun0; | 136 | se_lun = &se_sess->se_tpg->tpg_virt_lun0; |
138 | se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0; | 137 | se_cmd->se_lun = &se_sess->se_tpg->tpg_virt_lun0; |
139 | se_cmd->orig_fe_lun = 0; | 138 | se_cmd->orig_fe_lun = 0; |
140 | se_cmd->se_orig_obj_ptr = se_cmd->se_lun->lun_se_dev; | ||
141 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; | 139 | se_cmd->se_cmd_flags |= SCF_SE_LUN_CMD; |
142 | } | 140 | } |
143 | /* | 141 | /* |
@@ -200,7 +198,6 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd, u32 unpacked_lun) | |||
200 | se_lun = deve->se_lun; | 198 | se_lun = deve->se_lun; |
201 | se_cmd->pr_res_key = deve->pr_res_key; | 199 | se_cmd->pr_res_key = deve->pr_res_key; |
202 | se_cmd->orig_fe_lun = unpacked_lun; | 200 | se_cmd->orig_fe_lun = unpacked_lun; |
203 | se_cmd->se_orig_obj_ptr = se_cmd->se_dev; | ||
204 | } | 201 | } |
205 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); | 202 | spin_unlock_irqrestore(&se_sess->se_node_acl->device_list_lock, flags); |
206 | 203 | ||
@@ -708,7 +705,7 @@ done: | |||
708 | 705 | ||
709 | se_task->task_scsi_status = GOOD; | 706 | se_task->task_scsi_status = GOOD; |
710 | transport_complete_task(se_task, 1); | 707 | transport_complete_task(se_task, 1); |
711 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 708 | return 0; |
712 | } | 709 | } |
713 | 710 | ||
714 | /* se_release_device_for_hba(): | 711 | /* se_release_device_for_hba(): |
@@ -957,8 +954,12 @@ int se_dev_set_emulate_dpo(struct se_device *dev, int flag) | |||
957 | return -EINVAL; | 954 | return -EINVAL; |
958 | } | 955 | } |
959 | 956 | ||
960 | pr_err("dpo_emulated not supported\n"); | 957 | if (flag) { |
961 | return -EINVAL; | 958 | pr_err("dpo_emulated not supported\n"); |
959 | return -EINVAL; | ||
960 | } | ||
961 | |||
962 | return 0; | ||
962 | } | 963 | } |
963 | 964 | ||
964 | int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) | 965 | int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) |
@@ -968,7 +969,7 @@ int se_dev_set_emulate_fua_write(struct se_device *dev, int flag) | |||
968 | return -EINVAL; | 969 | return -EINVAL; |
969 | } | 970 | } |
970 | 971 | ||
971 | if (dev->transport->fua_write_emulated == 0) { | 972 | if (flag && dev->transport->fua_write_emulated == 0) { |
972 | pr_err("fua_write_emulated not supported\n"); | 973 | pr_err("fua_write_emulated not supported\n"); |
973 | return -EINVAL; | 974 | return -EINVAL; |
974 | } | 975 | } |
@@ -985,8 +986,12 @@ int se_dev_set_emulate_fua_read(struct se_device *dev, int flag) | |||
985 | return -EINVAL; | 986 | return -EINVAL; |
986 | } | 987 | } |
987 | 988 | ||
988 | pr_err("ua read emulated not supported\n"); | 989 | if (flag) { |
989 | return -EINVAL; | 990 | pr_err("ua read emulated not supported\n"); |
991 | return -EINVAL; | ||
992 | } | ||
993 | |||
994 | return 0; | ||
990 | } | 995 | } |
991 | 996 | ||
992 | int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) | 997 | int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) |
@@ -995,7 +1000,7 @@ int se_dev_set_emulate_write_cache(struct se_device *dev, int flag) | |||
995 | pr_err("Illegal value %d\n", flag); | 1000 | pr_err("Illegal value %d\n", flag); |
996 | return -EINVAL; | 1001 | return -EINVAL; |
997 | } | 1002 | } |
998 | if (dev->transport->write_cache_emulated == 0) { | 1003 | if (flag && dev->transport->write_cache_emulated == 0) { |
999 | pr_err("write_cache_emulated not supported\n"); | 1004 | pr_err("write_cache_emulated not supported\n"); |
1000 | return -EINVAL; | 1005 | return -EINVAL; |
1001 | } | 1006 | } |
@@ -1056,7 +1061,7 @@ int se_dev_set_emulate_tpu(struct se_device *dev, int flag) | |||
1056 | * We expect this value to be non-zero when generic Block Layer | 1061 | * We expect this value to be non-zero when generic Block Layer |
1057 | * Discard supported is detected iblock_create_virtdevice(). | 1062 | * Discard supported is detected iblock_create_virtdevice(). |
1058 | */ | 1063 | */ |
1059 | if (!dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { | 1064 | if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { |
1060 | pr_err("Generic Block Discard not supported\n"); | 1065 | pr_err("Generic Block Discard not supported\n"); |
1061 | return -ENOSYS; | 1066 | return -ENOSYS; |
1062 | } | 1067 | } |
@@ -1077,7 +1082,7 @@ int se_dev_set_emulate_tpws(struct se_device *dev, int flag) | |||
1077 | * We expect this value to be non-zero when generic Block Layer | 1082 | * We expect this value to be non-zero when generic Block Layer |
1078 | * Discard supported is detected iblock_create_virtdevice(). | 1083 | * Discard supported is detected iblock_create_virtdevice(). |
1079 | */ | 1084 | */ |
1080 | if (!dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { | 1085 | if (flag && !dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { |
1081 | pr_err("Generic Block Discard not supported\n"); | 1086 | pr_err("Generic Block Discard not supported\n"); |
1082 | return -ENOSYS; | 1087 | return -ENOSYS; |
1083 | } | 1088 | } |
@@ -1587,7 +1592,6 @@ int core_dev_setup_virtual_lun0(void) | |||
1587 | ret = -ENOMEM; | 1592 | ret = -ENOMEM; |
1588 | goto out; | 1593 | goto out; |
1589 | } | 1594 | } |
1590 | INIT_LIST_HEAD(&se_dev->se_dev_node); | ||
1591 | INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); | 1595 | INIT_LIST_HEAD(&se_dev->t10_wwn.t10_vpd_list); |
1592 | spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); | 1596 | spin_lock_init(&se_dev->t10_wwn.t10_vpd_lock); |
1593 | INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); | 1597 | INIT_LIST_HEAD(&se_dev->t10_pr.registration_list); |
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 67cd6fe05bfa..b4864fba4ef0 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c | |||
@@ -289,9 +289,9 @@ static int fd_do_readv(struct se_task *task) | |||
289 | return -ENOMEM; | 289 | return -ENOMEM; |
290 | } | 290 | } |
291 | 291 | ||
292 | for (i = 0; i < task->task_sg_nents; i++) { | 292 | for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { |
293 | iov[i].iov_len = sg[i].length; | 293 | iov[i].iov_len = sg->length; |
294 | iov[i].iov_base = sg_virt(&sg[i]); | 294 | iov[i].iov_base = sg_virt(sg); |
295 | } | 295 | } |
296 | 296 | ||
297 | old_fs = get_fs(); | 297 | old_fs = get_fs(); |
@@ -342,9 +342,9 @@ static int fd_do_writev(struct se_task *task) | |||
342 | return -ENOMEM; | 342 | return -ENOMEM; |
343 | } | 343 | } |
344 | 344 | ||
345 | for (i = 0; i < task->task_sg_nents; i++) { | 345 | for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { |
346 | iov[i].iov_len = sg[i].length; | 346 | iov[i].iov_len = sg->length; |
347 | iov[i].iov_base = sg_virt(&sg[i]); | 347 | iov[i].iov_base = sg_virt(sg); |
348 | } | 348 | } |
349 | 349 | ||
350 | old_fs = get_fs(); | 350 | old_fs = get_fs(); |
@@ -438,7 +438,7 @@ static int fd_do_task(struct se_task *task) | |||
438 | if (ret > 0 && | 438 | if (ret > 0 && |
439 | dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 && | 439 | dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0 && |
440 | dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && | 440 | dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && |
441 | cmd->t_tasks_fua) { | 441 | (cmd->se_cmd_flags & SCF_FUA)) { |
442 | /* | 442 | /* |
443 | * We might need to be a bit smarter here | 443 | * We might need to be a bit smarter here |
444 | * and return some sense data to let the initiator | 444 | * and return some sense data to let the initiator |
@@ -449,13 +449,15 @@ static int fd_do_task(struct se_task *task) | |||
449 | 449 | ||
450 | } | 450 | } |
451 | 451 | ||
452 | if (ret < 0) | 452 | if (ret < 0) { |
453 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
453 | return ret; | 454 | return ret; |
455 | } | ||
454 | if (ret) { | 456 | if (ret) { |
455 | task->task_scsi_status = GOOD; | 457 | task->task_scsi_status = GOOD; |
456 | transport_complete_task(task, 1); | 458 | transport_complete_task(task, 1); |
457 | } | 459 | } |
458 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 460 | return 0; |
459 | } | 461 | } |
460 | 462 | ||
461 | /* fd_free_task(): (Part of se_subsystem_api_t template) | 463 | /* fd_free_task(): (Part of se_subsystem_api_t template) |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 7698efe29262..4aa992204438 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -531,7 +531,7 @@ static int iblock_do_task(struct se_task *task) | |||
531 | */ | 531 | */ |
532 | if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache == 0 || | 532 | if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache == 0 || |
533 | (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && | 533 | (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0 && |
534 | task->task_se_cmd->t_tasks_fua)) | 534 | (cmd->se_cmd_flags & SCF_FUA))) |
535 | rw = WRITE_FUA; | 535 | rw = WRITE_FUA; |
536 | else | 536 | else |
537 | rw = WRITE; | 537 | rw = WRITE; |
@@ -554,12 +554,15 @@ static int iblock_do_task(struct se_task *task) | |||
554 | else { | 554 | else { |
555 | pr_err("Unsupported SCSI -> BLOCK LBA conversion:" | 555 | pr_err("Unsupported SCSI -> BLOCK LBA conversion:" |
556 | " %u\n", dev->se_sub_dev->se_dev_attrib.block_size); | 556 | " %u\n", dev->se_sub_dev->se_dev_attrib.block_size); |
557 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 557 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
558 | return -ENOSYS; | ||
558 | } | 559 | } |
559 | 560 | ||
560 | bio = iblock_get_bio(task, block_lba, sg_num); | 561 | bio = iblock_get_bio(task, block_lba, sg_num); |
561 | if (!bio) | 562 | if (!bio) { |
562 | return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; | 563 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
564 | return -ENOMEM; | ||
565 | } | ||
563 | 566 | ||
564 | bio_list_init(&list); | 567 | bio_list_init(&list); |
565 | bio_list_add(&list, bio); | 568 | bio_list_add(&list, bio); |
@@ -588,12 +591,13 @@ static int iblock_do_task(struct se_task *task) | |||
588 | submit_bio(rw, bio); | 591 | submit_bio(rw, bio); |
589 | blk_finish_plug(&plug); | 592 | blk_finish_plug(&plug); |
590 | 593 | ||
591 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 594 | return 0; |
592 | 595 | ||
593 | fail: | 596 | fail: |
594 | while ((bio = bio_list_pop(&list))) | 597 | while ((bio = bio_list_pop(&list))) |
595 | bio_put(bio); | 598 | bio_put(bio); |
596 | return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; | 599 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
600 | return -ENOMEM; | ||
597 | } | 601 | } |
598 | 602 | ||
599 | static u32 iblock_get_device_rev(struct se_device *dev) | 603 | static u32 iblock_get_device_rev(struct se_device *dev) |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 5a4ebfc3a54f..95dee7074aeb 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -191,7 +191,7 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) | |||
191 | pr_err("Received legacy SPC-2 RESERVE/RELEASE" | 191 | pr_err("Received legacy SPC-2 RESERVE/RELEASE" |
192 | " while active SPC-3 registrations exist," | 192 | " while active SPC-3 registrations exist," |
193 | " returning RESERVATION_CONFLICT\n"); | 193 | " returning RESERVATION_CONFLICT\n"); |
194 | *ret = PYX_TRANSPORT_RESERVATION_CONFLICT; | 194 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
195 | return true; | 195 | return true; |
196 | } | 196 | } |
197 | 197 | ||
@@ -252,7 +252,8 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
252 | (cmd->t_task_cdb[1] & 0x02)) { | 252 | (cmd->t_task_cdb[1] & 0x02)) { |
253 | pr_err("LongIO and Obselete Bits set, returning" | 253 | pr_err("LongIO and Obselete Bits set, returning" |
254 | " ILLEGAL_REQUEST\n"); | 254 | " ILLEGAL_REQUEST\n"); |
255 | ret = PYX_TRANSPORT_ILLEGAL_REQUEST; | 255 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
256 | ret = -EINVAL; | ||
256 | goto out; | 257 | goto out; |
257 | } | 258 | } |
258 | /* | 259 | /* |
@@ -277,7 +278,8 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
277 | " from %s \n", cmd->se_lun->unpacked_lun, | 278 | " from %s \n", cmd->se_lun->unpacked_lun, |
278 | cmd->se_deve->mapped_lun, | 279 | cmd->se_deve->mapped_lun, |
279 | sess->se_node_acl->initiatorname); | 280 | sess->se_node_acl->initiatorname); |
280 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; | 281 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
282 | ret = -EINVAL; | ||
281 | goto out_unlock; | 283 | goto out_unlock; |
282 | } | 284 | } |
283 | 285 | ||
@@ -1510,7 +1512,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1510 | tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); | 1512 | tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); |
1511 | if (!tidh_new) { | 1513 | if (!tidh_new) { |
1512 | pr_err("Unable to allocate tidh_new\n"); | 1514 | pr_err("Unable to allocate tidh_new\n"); |
1513 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 1515 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1516 | return -EINVAL; | ||
1514 | } | 1517 | } |
1515 | INIT_LIST_HEAD(&tidh_new->dest_list); | 1518 | INIT_LIST_HEAD(&tidh_new->dest_list); |
1516 | tidh_new->dest_tpg = tpg; | 1519 | tidh_new->dest_tpg = tpg; |
@@ -1522,7 +1525,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1522 | sa_res_key, all_tg_pt, aptpl); | 1525 | sa_res_key, all_tg_pt, aptpl); |
1523 | if (!local_pr_reg) { | 1526 | if (!local_pr_reg) { |
1524 | kfree(tidh_new); | 1527 | kfree(tidh_new); |
1525 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 1528 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1529 | return -ENOMEM; | ||
1526 | } | 1530 | } |
1527 | tidh_new->dest_pr_reg = local_pr_reg; | 1531 | tidh_new->dest_pr_reg = local_pr_reg; |
1528 | /* | 1532 | /* |
@@ -1548,7 +1552,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1548 | pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header" | 1552 | pr_err("SPC-3 PR: Illegal tpdl: %u + 28 byte header" |
1549 | " does not equal CDB data_length: %u\n", tpdl, | 1553 | " does not equal CDB data_length: %u\n", tpdl, |
1550 | cmd->data_length); | 1554 | cmd->data_length); |
1551 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 1555 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
1556 | ret = -EINVAL; | ||
1552 | goto out; | 1557 | goto out; |
1553 | } | 1558 | } |
1554 | /* | 1559 | /* |
@@ -1598,7 +1603,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1598 | " for tmp_tpg\n"); | 1603 | " for tmp_tpg\n"); |
1599 | atomic_dec(&tmp_tpg->tpg_pr_ref_count); | 1604 | atomic_dec(&tmp_tpg->tpg_pr_ref_count); |
1600 | smp_mb__after_atomic_dec(); | 1605 | smp_mb__after_atomic_dec(); |
1601 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 1606 | cmd->scsi_sense_reason = |
1607 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1608 | ret = -EINVAL; | ||
1602 | goto out; | 1609 | goto out; |
1603 | } | 1610 | } |
1604 | /* | 1611 | /* |
@@ -1628,7 +1635,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1628 | atomic_dec(&dest_node_acl->acl_pr_ref_count); | 1635 | atomic_dec(&dest_node_acl->acl_pr_ref_count); |
1629 | smp_mb__after_atomic_dec(); | 1636 | smp_mb__after_atomic_dec(); |
1630 | core_scsi3_tpg_undepend_item(tmp_tpg); | 1637 | core_scsi3_tpg_undepend_item(tmp_tpg); |
1631 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 1638 | cmd->scsi_sense_reason = |
1639 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1640 | ret = -EINVAL; | ||
1632 | goto out; | 1641 | goto out; |
1633 | } | 1642 | } |
1634 | 1643 | ||
@@ -1646,7 +1655,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1646 | if (!dest_tpg) { | 1655 | if (!dest_tpg) { |
1647 | pr_err("SPC-3 PR SPEC_I_PT: Unable to locate" | 1656 | pr_err("SPC-3 PR SPEC_I_PT: Unable to locate" |
1648 | " dest_tpg\n"); | 1657 | " dest_tpg\n"); |
1649 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 1658 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
1659 | ret = -EINVAL; | ||
1650 | goto out; | 1660 | goto out; |
1651 | } | 1661 | } |
1652 | #if 0 | 1662 | #if 0 |
@@ -1660,7 +1670,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1660 | " %u for Transport ID: %s\n", tid_len, ptr); | 1670 | " %u for Transport ID: %s\n", tid_len, ptr); |
1661 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1671 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1662 | core_scsi3_tpg_undepend_item(dest_tpg); | 1672 | core_scsi3_tpg_undepend_item(dest_tpg); |
1663 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 1673 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
1674 | ret = -EINVAL; | ||
1664 | goto out; | 1675 | goto out; |
1665 | } | 1676 | } |
1666 | /* | 1677 | /* |
@@ -1678,7 +1689,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1678 | 1689 | ||
1679 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1690 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1680 | core_scsi3_tpg_undepend_item(dest_tpg); | 1691 | core_scsi3_tpg_undepend_item(dest_tpg); |
1681 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 1692 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
1693 | ret = -EINVAL; | ||
1682 | goto out; | 1694 | goto out; |
1683 | } | 1695 | } |
1684 | 1696 | ||
@@ -1690,7 +1702,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1690 | smp_mb__after_atomic_dec(); | 1702 | smp_mb__after_atomic_dec(); |
1691 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1703 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1692 | core_scsi3_tpg_undepend_item(dest_tpg); | 1704 | core_scsi3_tpg_undepend_item(dest_tpg); |
1693 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 1705 | cmd->scsi_sense_reason = |
1706 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1707 | ret = -EINVAL; | ||
1694 | goto out; | 1708 | goto out; |
1695 | } | 1709 | } |
1696 | #if 0 | 1710 | #if 0 |
@@ -1727,7 +1741,9 @@ static int core_scsi3_decode_spec_i_port( | |||
1727 | core_scsi3_lunacl_undepend_item(dest_se_deve); | 1741 | core_scsi3_lunacl_undepend_item(dest_se_deve); |
1728 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1742 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1729 | core_scsi3_tpg_undepend_item(dest_tpg); | 1743 | core_scsi3_tpg_undepend_item(dest_tpg); |
1730 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 1744 | cmd->scsi_sense_reason = |
1745 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1746 | ret = -ENOMEM; | ||
1731 | goto out; | 1747 | goto out; |
1732 | } | 1748 | } |
1733 | INIT_LIST_HEAD(&tidh_new->dest_list); | 1749 | INIT_LIST_HEAD(&tidh_new->dest_list); |
@@ -1759,7 +1775,8 @@ static int core_scsi3_decode_spec_i_port( | |||
1759 | core_scsi3_nodeacl_undepend_item(dest_node_acl); | 1775 | core_scsi3_nodeacl_undepend_item(dest_node_acl); |
1760 | core_scsi3_tpg_undepend_item(dest_tpg); | 1776 | core_scsi3_tpg_undepend_item(dest_tpg); |
1761 | kfree(tidh_new); | 1777 | kfree(tidh_new); |
1762 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 1778 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
1779 | ret = -EINVAL; | ||
1763 | goto out; | 1780 | goto out; |
1764 | } | 1781 | } |
1765 | tidh_new->dest_pr_reg = dest_pr_reg; | 1782 | tidh_new->dest_pr_reg = dest_pr_reg; |
@@ -2098,7 +2115,8 @@ static int core_scsi3_emulate_pro_register( | |||
2098 | 2115 | ||
2099 | if (!se_sess || !se_lun) { | 2116 | if (!se_sess || !se_lun) { |
2100 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2117 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2101 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2118 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2119 | return -EINVAL; | ||
2102 | } | 2120 | } |
2103 | se_tpg = se_sess->se_tpg; | 2121 | se_tpg = se_sess->se_tpg; |
2104 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; | 2122 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; |
@@ -2117,13 +2135,14 @@ static int core_scsi3_emulate_pro_register( | |||
2117 | if (res_key) { | 2135 | if (res_key) { |
2118 | pr_warn("SPC-3 PR: Reservation Key non-zero" | 2136 | pr_warn("SPC-3 PR: Reservation Key non-zero" |
2119 | " for SA REGISTER, returning CONFLICT\n"); | 2137 | " for SA REGISTER, returning CONFLICT\n"); |
2120 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2138 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2139 | return -EINVAL; | ||
2121 | } | 2140 | } |
2122 | /* | 2141 | /* |
2123 | * Do nothing but return GOOD status. | 2142 | * Do nothing but return GOOD status. |
2124 | */ | 2143 | */ |
2125 | if (!sa_res_key) | 2144 | if (!sa_res_key) |
2126 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 2145 | return 0; |
2127 | 2146 | ||
2128 | if (!spec_i_pt) { | 2147 | if (!spec_i_pt) { |
2129 | /* | 2148 | /* |
@@ -2138,7 +2157,8 @@ static int core_scsi3_emulate_pro_register( | |||
2138 | if (ret != 0) { | 2157 | if (ret != 0) { |
2139 | pr_err("Unable to allocate" | 2158 | pr_err("Unable to allocate" |
2140 | " struct t10_pr_registration\n"); | 2159 | " struct t10_pr_registration\n"); |
2141 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 2160 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
2161 | return -EINVAL; | ||
2142 | } | 2162 | } |
2143 | } else { | 2163 | } else { |
2144 | /* | 2164 | /* |
@@ -2197,14 +2217,16 @@ static int core_scsi3_emulate_pro_register( | |||
2197 | " 0x%016Lx\n", res_key, | 2217 | " 0x%016Lx\n", res_key, |
2198 | pr_reg->pr_res_key); | 2218 | pr_reg->pr_res_key); |
2199 | core_scsi3_put_pr_reg(pr_reg); | 2219 | core_scsi3_put_pr_reg(pr_reg); |
2200 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2220 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2221 | return -EINVAL; | ||
2201 | } | 2222 | } |
2202 | } | 2223 | } |
2203 | if (spec_i_pt) { | 2224 | if (spec_i_pt) { |
2204 | pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" | 2225 | pr_err("SPC-3 PR UNREGISTER: SPEC_I_PT" |
2205 | " set while sa_res_key=0\n"); | 2226 | " set while sa_res_key=0\n"); |
2206 | core_scsi3_put_pr_reg(pr_reg); | 2227 | core_scsi3_put_pr_reg(pr_reg); |
2207 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 2228 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
2229 | return -EINVAL; | ||
2208 | } | 2230 | } |
2209 | /* | 2231 | /* |
2210 | * An existing ALL_TG_PT=1 registration being released | 2232 | * An existing ALL_TG_PT=1 registration being released |
@@ -2215,7 +2237,8 @@ static int core_scsi3_emulate_pro_register( | |||
2215 | " registration exists, but ALL_TG_PT=1 bit not" | 2237 | " registration exists, but ALL_TG_PT=1 bit not" |
2216 | " present in received PROUT\n"); | 2238 | " present in received PROUT\n"); |
2217 | core_scsi3_put_pr_reg(pr_reg); | 2239 | core_scsi3_put_pr_reg(pr_reg); |
2218 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 2240 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
2241 | return -EINVAL; | ||
2219 | } | 2242 | } |
2220 | /* | 2243 | /* |
2221 | * Allocate APTPL metadata buffer used for UNREGISTER ops | 2244 | * Allocate APTPL metadata buffer used for UNREGISTER ops |
@@ -2227,7 +2250,9 @@ static int core_scsi3_emulate_pro_register( | |||
2227 | pr_err("Unable to allocate" | 2250 | pr_err("Unable to allocate" |
2228 | " pr_aptpl_buf\n"); | 2251 | " pr_aptpl_buf\n"); |
2229 | core_scsi3_put_pr_reg(pr_reg); | 2252 | core_scsi3_put_pr_reg(pr_reg); |
2230 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2253 | cmd->scsi_sense_reason = |
2254 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2255 | return -EINVAL; | ||
2231 | } | 2256 | } |
2232 | } | 2257 | } |
2233 | /* | 2258 | /* |
@@ -2241,7 +2266,8 @@ static int core_scsi3_emulate_pro_register( | |||
2241 | if (pr_holder < 0) { | 2266 | if (pr_holder < 0) { |
2242 | kfree(pr_aptpl_buf); | 2267 | kfree(pr_aptpl_buf); |
2243 | core_scsi3_put_pr_reg(pr_reg); | 2268 | core_scsi3_put_pr_reg(pr_reg); |
2244 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2269 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2270 | return -EINVAL; | ||
2245 | } | 2271 | } |
2246 | 2272 | ||
2247 | spin_lock(&pr_tmpl->registration_lock); | 2273 | spin_lock(&pr_tmpl->registration_lock); |
@@ -2405,7 +2431,8 @@ static int core_scsi3_pro_reserve( | |||
2405 | 2431 | ||
2406 | if (!se_sess || !se_lun) { | 2432 | if (!se_sess || !se_lun) { |
2407 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2433 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2408 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2434 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2435 | return -EINVAL; | ||
2409 | } | 2436 | } |
2410 | se_tpg = se_sess->se_tpg; | 2437 | se_tpg = se_sess->se_tpg; |
2411 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; | 2438 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; |
@@ -2417,7 +2444,8 @@ static int core_scsi3_pro_reserve( | |||
2417 | if (!pr_reg) { | 2444 | if (!pr_reg) { |
2418 | pr_err("SPC-3 PR: Unable to locate" | 2445 | pr_err("SPC-3 PR: Unable to locate" |
2419 | " PR_REGISTERED *pr_reg for RESERVE\n"); | 2446 | " PR_REGISTERED *pr_reg for RESERVE\n"); |
2420 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2447 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2448 | return -EINVAL; | ||
2421 | } | 2449 | } |
2422 | /* | 2450 | /* |
2423 | * From spc4r17 Section 5.7.9: Reserving: | 2451 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2433,7 +2461,8 @@ static int core_scsi3_pro_reserve( | |||
2433 | " does not match existing SA REGISTER res_key:" | 2461 | " does not match existing SA REGISTER res_key:" |
2434 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 2462 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
2435 | core_scsi3_put_pr_reg(pr_reg); | 2463 | core_scsi3_put_pr_reg(pr_reg); |
2436 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2464 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2465 | return -EINVAL; | ||
2437 | } | 2466 | } |
2438 | /* | 2467 | /* |
2439 | * From spc4r17 Section 5.7.9: Reserving: | 2468 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2448,7 +2477,8 @@ static int core_scsi3_pro_reserve( | |||
2448 | if (scope != PR_SCOPE_LU_SCOPE) { | 2477 | if (scope != PR_SCOPE_LU_SCOPE) { |
2449 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); | 2478 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); |
2450 | core_scsi3_put_pr_reg(pr_reg); | 2479 | core_scsi3_put_pr_reg(pr_reg); |
2451 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 2480 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
2481 | return -EINVAL; | ||
2452 | } | 2482 | } |
2453 | /* | 2483 | /* |
2454 | * See if we have an existing PR reservation holder pointer at | 2484 | * See if we have an existing PR reservation holder pointer at |
@@ -2480,7 +2510,8 @@ static int core_scsi3_pro_reserve( | |||
2480 | 2510 | ||
2481 | spin_unlock(&dev->dev_reservation_lock); | 2511 | spin_unlock(&dev->dev_reservation_lock); |
2482 | core_scsi3_put_pr_reg(pr_reg); | 2512 | core_scsi3_put_pr_reg(pr_reg); |
2483 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2513 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2514 | return -EINVAL; | ||
2484 | } | 2515 | } |
2485 | /* | 2516 | /* |
2486 | * From spc4r17 Section 5.7.9: Reserving: | 2517 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2503,7 +2534,8 @@ static int core_scsi3_pro_reserve( | |||
2503 | 2534 | ||
2504 | spin_unlock(&dev->dev_reservation_lock); | 2535 | spin_unlock(&dev->dev_reservation_lock); |
2505 | core_scsi3_put_pr_reg(pr_reg); | 2536 | core_scsi3_put_pr_reg(pr_reg); |
2506 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2537 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2538 | return -EINVAL; | ||
2507 | } | 2539 | } |
2508 | /* | 2540 | /* |
2509 | * From spc4r17 Section 5.7.9: Reserving: | 2541 | * From spc4r17 Section 5.7.9: Reserving: |
@@ -2517,7 +2549,7 @@ static int core_scsi3_pro_reserve( | |||
2517 | */ | 2549 | */ |
2518 | spin_unlock(&dev->dev_reservation_lock); | 2550 | spin_unlock(&dev->dev_reservation_lock); |
2519 | core_scsi3_put_pr_reg(pr_reg); | 2551 | core_scsi3_put_pr_reg(pr_reg); |
2520 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 2552 | return 0; |
2521 | } | 2553 | } |
2522 | /* | 2554 | /* |
2523 | * Otherwise, our *pr_reg becomes the PR reservation holder for said | 2555 | * Otherwise, our *pr_reg becomes the PR reservation holder for said |
@@ -2574,7 +2606,8 @@ static int core_scsi3_emulate_pro_reserve( | |||
2574 | default: | 2606 | default: |
2575 | pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:" | 2607 | pr_err("SPC-3 PR: Unknown Service Action RESERVE Type:" |
2576 | " 0x%02x\n", type); | 2608 | " 0x%02x\n", type); |
2577 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 2609 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
2610 | return -EINVAL; | ||
2578 | } | 2611 | } |
2579 | 2612 | ||
2580 | return ret; | 2613 | return ret; |
@@ -2630,7 +2663,8 @@ static int core_scsi3_emulate_pro_release( | |||
2630 | 2663 | ||
2631 | if (!se_sess || !se_lun) { | 2664 | if (!se_sess || !se_lun) { |
2632 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 2665 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
2633 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2666 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2667 | return -EINVAL; | ||
2634 | } | 2668 | } |
2635 | /* | 2669 | /* |
2636 | * Locate the existing *pr_reg via struct se_node_acl pointers | 2670 | * Locate the existing *pr_reg via struct se_node_acl pointers |
@@ -2639,7 +2673,8 @@ static int core_scsi3_emulate_pro_release( | |||
2639 | if (!pr_reg) { | 2673 | if (!pr_reg) { |
2640 | pr_err("SPC-3 PR: Unable to locate" | 2674 | pr_err("SPC-3 PR: Unable to locate" |
2641 | " PR_REGISTERED *pr_reg for RELEASE\n"); | 2675 | " PR_REGISTERED *pr_reg for RELEASE\n"); |
2642 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2676 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2677 | return -EINVAL; | ||
2643 | } | 2678 | } |
2644 | /* | 2679 | /* |
2645 | * From spc4r17 Section 5.7.11.2 Releasing: | 2680 | * From spc4r17 Section 5.7.11.2 Releasing: |
@@ -2661,7 +2696,7 @@ static int core_scsi3_emulate_pro_release( | |||
2661 | */ | 2696 | */ |
2662 | spin_unlock(&dev->dev_reservation_lock); | 2697 | spin_unlock(&dev->dev_reservation_lock); |
2663 | core_scsi3_put_pr_reg(pr_reg); | 2698 | core_scsi3_put_pr_reg(pr_reg); |
2664 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 2699 | return 0; |
2665 | } | 2700 | } |
2666 | if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || | 2701 | if ((pr_res_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || |
2667 | (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) | 2702 | (pr_res_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) |
@@ -2675,7 +2710,7 @@ static int core_scsi3_emulate_pro_release( | |||
2675 | */ | 2710 | */ |
2676 | spin_unlock(&dev->dev_reservation_lock); | 2711 | spin_unlock(&dev->dev_reservation_lock); |
2677 | core_scsi3_put_pr_reg(pr_reg); | 2712 | core_scsi3_put_pr_reg(pr_reg); |
2678 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 2713 | return 0; |
2679 | } | 2714 | } |
2680 | /* | 2715 | /* |
2681 | * From spc4r17 Section 5.7.11.2 Releasing: | 2716 | * From spc4r17 Section 5.7.11.2 Releasing: |
@@ -2697,7 +2732,8 @@ static int core_scsi3_emulate_pro_release( | |||
2697 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 2732 | " 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
2698 | spin_unlock(&dev->dev_reservation_lock); | 2733 | spin_unlock(&dev->dev_reservation_lock); |
2699 | core_scsi3_put_pr_reg(pr_reg); | 2734 | core_scsi3_put_pr_reg(pr_reg); |
2700 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2735 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2736 | return -EINVAL; | ||
2701 | } | 2737 | } |
2702 | /* | 2738 | /* |
2703 | * From spc4r17 Section 5.7.11.2 Releasing and above: | 2739 | * From spc4r17 Section 5.7.11.2 Releasing and above: |
@@ -2719,7 +2755,8 @@ static int core_scsi3_emulate_pro_release( | |||
2719 | 2755 | ||
2720 | spin_unlock(&dev->dev_reservation_lock); | 2756 | spin_unlock(&dev->dev_reservation_lock); |
2721 | core_scsi3_put_pr_reg(pr_reg); | 2757 | core_scsi3_put_pr_reg(pr_reg); |
2722 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2758 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2759 | return -EINVAL; | ||
2723 | } | 2760 | } |
2724 | /* | 2761 | /* |
2725 | * In response to a persistent reservation release request from the | 2762 | * In response to a persistent reservation release request from the |
@@ -2802,7 +2839,8 @@ static int core_scsi3_emulate_pro_clear( | |||
2802 | if (!pr_reg_n) { | 2839 | if (!pr_reg_n) { |
2803 | pr_err("SPC-3 PR: Unable to locate" | 2840 | pr_err("SPC-3 PR: Unable to locate" |
2804 | " PR_REGISTERED *pr_reg for CLEAR\n"); | 2841 | " PR_REGISTERED *pr_reg for CLEAR\n"); |
2805 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 2842 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2843 | return -EINVAL; | ||
2806 | } | 2844 | } |
2807 | /* | 2845 | /* |
2808 | * From spc4r17 section 5.7.11.6, Clearing: | 2846 | * From spc4r17 section 5.7.11.6, Clearing: |
@@ -2821,7 +2859,8 @@ static int core_scsi3_emulate_pro_clear( | |||
2821 | " existing SA REGISTER res_key:" | 2859 | " existing SA REGISTER res_key:" |
2822 | " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key); | 2860 | " 0x%016Lx\n", res_key, pr_reg_n->pr_res_key); |
2823 | core_scsi3_put_pr_reg(pr_reg_n); | 2861 | core_scsi3_put_pr_reg(pr_reg_n); |
2824 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 2862 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2863 | return -EINVAL; | ||
2825 | } | 2864 | } |
2826 | /* | 2865 | /* |
2827 | * a) Release the persistent reservation, if any; | 2866 | * a) Release the persistent reservation, if any; |
@@ -2979,8 +3018,10 @@ static int core_scsi3_pro_preempt( | |||
2979 | int all_reg = 0, calling_it_nexus = 0, released_regs = 0; | 3018 | int all_reg = 0, calling_it_nexus = 0, released_regs = 0; |
2980 | int prh_type = 0, prh_scope = 0, ret; | 3019 | int prh_type = 0, prh_scope = 0, ret; |
2981 | 3020 | ||
2982 | if (!se_sess) | 3021 | if (!se_sess) { |
2983 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3022 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3023 | return -EINVAL; | ||
3024 | } | ||
2984 | 3025 | ||
2985 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; | 3026 | se_deve = &se_sess->se_node_acl->device_list[cmd->orig_fe_lun]; |
2986 | pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, | 3027 | pr_reg_n = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, |
@@ -2989,16 +3030,19 @@ static int core_scsi3_pro_preempt( | |||
2989 | pr_err("SPC-3 PR: Unable to locate" | 3030 | pr_err("SPC-3 PR: Unable to locate" |
2990 | " PR_REGISTERED *pr_reg for PREEMPT%s\n", | 3031 | " PR_REGISTERED *pr_reg for PREEMPT%s\n", |
2991 | (abort) ? "_AND_ABORT" : ""); | 3032 | (abort) ? "_AND_ABORT" : ""); |
2992 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 3033 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3034 | return -EINVAL; | ||
2993 | } | 3035 | } |
2994 | if (pr_reg_n->pr_res_key != res_key) { | 3036 | if (pr_reg_n->pr_res_key != res_key) { |
2995 | core_scsi3_put_pr_reg(pr_reg_n); | 3037 | core_scsi3_put_pr_reg(pr_reg_n); |
2996 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 3038 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3039 | return -EINVAL; | ||
2997 | } | 3040 | } |
2998 | if (scope != PR_SCOPE_LU_SCOPE) { | 3041 | if (scope != PR_SCOPE_LU_SCOPE) { |
2999 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); | 3042 | pr_err("SPC-3 PR: Illegal SCOPE: 0x%02x\n", scope); |
3000 | core_scsi3_put_pr_reg(pr_reg_n); | 3043 | core_scsi3_put_pr_reg(pr_reg_n); |
3001 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3044 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3045 | return -EINVAL; | ||
3002 | } | 3046 | } |
3003 | INIT_LIST_HEAD(&preempt_and_abort_list); | 3047 | INIT_LIST_HEAD(&preempt_and_abort_list); |
3004 | 3048 | ||
@@ -3012,7 +3056,8 @@ static int core_scsi3_pro_preempt( | |||
3012 | if (!all_reg && !sa_res_key) { | 3056 | if (!all_reg && !sa_res_key) { |
3013 | spin_unlock(&dev->dev_reservation_lock); | 3057 | spin_unlock(&dev->dev_reservation_lock); |
3014 | core_scsi3_put_pr_reg(pr_reg_n); | 3058 | core_scsi3_put_pr_reg(pr_reg_n); |
3015 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3059 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3060 | return -EINVAL; | ||
3016 | } | 3061 | } |
3017 | /* | 3062 | /* |
3018 | * From spc4r17, section 5.7.11.4.4 Removing Registrations: | 3063 | * From spc4r17, section 5.7.11.4.4 Removing Registrations: |
@@ -3106,7 +3151,8 @@ static int core_scsi3_pro_preempt( | |||
3106 | if (!released_regs) { | 3151 | if (!released_regs) { |
3107 | spin_unlock(&dev->dev_reservation_lock); | 3152 | spin_unlock(&dev->dev_reservation_lock); |
3108 | core_scsi3_put_pr_reg(pr_reg_n); | 3153 | core_scsi3_put_pr_reg(pr_reg_n); |
3109 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 3154 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3155 | return -EINVAL; | ||
3110 | } | 3156 | } |
3111 | /* | 3157 | /* |
3112 | * For an existing all registrants type reservation | 3158 | * For an existing all registrants type reservation |
@@ -3297,7 +3343,8 @@ static int core_scsi3_emulate_pro_preempt( | |||
3297 | default: | 3343 | default: |
3298 | pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" | 3344 | pr_err("SPC-3 PR: Unknown Service Action PREEMPT%s" |
3299 | " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); | 3345 | " Type: 0x%02x\n", (abort) ? "_AND_ABORT" : "", type); |
3300 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 3346 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
3347 | return -EINVAL; | ||
3301 | } | 3348 | } |
3302 | 3349 | ||
3303 | return ret; | 3350 | return ret; |
@@ -3331,7 +3378,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3331 | 3378 | ||
3332 | if (!se_sess || !se_lun) { | 3379 | if (!se_sess || !se_lun) { |
3333 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); | 3380 | pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); |
3334 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3381 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3382 | return -EINVAL; | ||
3335 | } | 3383 | } |
3336 | memset(dest_iport, 0, 64); | 3384 | memset(dest_iport, 0, 64); |
3337 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); | 3385 | memset(i_buf, 0, PR_REG_ISID_ID_LEN); |
@@ -3349,7 +3397,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3349 | if (!pr_reg) { | 3397 | if (!pr_reg) { |
3350 | pr_err("SPC-3 PR: Unable to locate PR_REGISTERED" | 3398 | pr_err("SPC-3 PR: Unable to locate PR_REGISTERED" |
3351 | " *pr_reg for REGISTER_AND_MOVE\n"); | 3399 | " *pr_reg for REGISTER_AND_MOVE\n"); |
3352 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3400 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3401 | return -EINVAL; | ||
3353 | } | 3402 | } |
3354 | /* | 3403 | /* |
3355 | * The provided reservation key much match the existing reservation key | 3404 | * The provided reservation key much match the existing reservation key |
@@ -3360,7 +3409,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3360 | " res_key: 0x%016Lx does not match existing SA REGISTER" | 3409 | " res_key: 0x%016Lx does not match existing SA REGISTER" |
3361 | " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key); | 3410 | " res_key: 0x%016Lx\n", res_key, pr_reg->pr_res_key); |
3362 | core_scsi3_put_pr_reg(pr_reg); | 3411 | core_scsi3_put_pr_reg(pr_reg); |
3363 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 3412 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3413 | return -EINVAL; | ||
3364 | } | 3414 | } |
3365 | /* | 3415 | /* |
3366 | * The service active reservation key needs to be non zero | 3416 | * The service active reservation key needs to be non zero |
@@ -3369,7 +3419,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3369 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero" | 3419 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Received zero" |
3370 | " sa_res_key\n"); | 3420 | " sa_res_key\n"); |
3371 | core_scsi3_put_pr_reg(pr_reg); | 3421 | core_scsi3_put_pr_reg(pr_reg); |
3372 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3422 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3423 | return -EINVAL; | ||
3373 | } | 3424 | } |
3374 | 3425 | ||
3375 | /* | 3426 | /* |
@@ -3392,7 +3443,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3392 | " does not equal CDB data_length: %u\n", tid_len, | 3443 | " does not equal CDB data_length: %u\n", tid_len, |
3393 | cmd->data_length); | 3444 | cmd->data_length); |
3394 | core_scsi3_put_pr_reg(pr_reg); | 3445 | core_scsi3_put_pr_reg(pr_reg); |
3395 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3446 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3447 | return -EINVAL; | ||
3396 | } | 3448 | } |
3397 | 3449 | ||
3398 | spin_lock(&dev->se_port_lock); | 3450 | spin_lock(&dev->se_port_lock); |
@@ -3417,7 +3469,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3417 | atomic_dec(&dest_se_tpg->tpg_pr_ref_count); | 3469 | atomic_dec(&dest_se_tpg->tpg_pr_ref_count); |
3418 | smp_mb__after_atomic_dec(); | 3470 | smp_mb__after_atomic_dec(); |
3419 | core_scsi3_put_pr_reg(pr_reg); | 3471 | core_scsi3_put_pr_reg(pr_reg); |
3420 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3472 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3473 | return -EINVAL; | ||
3421 | } | 3474 | } |
3422 | 3475 | ||
3423 | spin_lock(&dev->se_port_lock); | 3476 | spin_lock(&dev->se_port_lock); |
@@ -3430,7 +3483,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3430 | " fabric ops from Relative Target Port Identifier:" | 3483 | " fabric ops from Relative Target Port Identifier:" |
3431 | " %hu\n", rtpi); | 3484 | " %hu\n", rtpi); |
3432 | core_scsi3_put_pr_reg(pr_reg); | 3485 | core_scsi3_put_pr_reg(pr_reg); |
3433 | return PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3486 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3487 | return -EINVAL; | ||
3434 | } | 3488 | } |
3435 | 3489 | ||
3436 | buf = transport_kmap_first_data_page(cmd); | 3490 | buf = transport_kmap_first_data_page(cmd); |
@@ -3445,14 +3499,16 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3445 | " from fabric: %s\n", proto_ident, | 3499 | " from fabric: %s\n", proto_ident, |
3446 | dest_tf_ops->get_fabric_proto_ident(dest_se_tpg), | 3500 | dest_tf_ops->get_fabric_proto_ident(dest_se_tpg), |
3447 | dest_tf_ops->get_fabric_name()); | 3501 | dest_tf_ops->get_fabric_name()); |
3448 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3502 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3503 | ret = -EINVAL; | ||
3449 | goto out; | 3504 | goto out; |
3450 | } | 3505 | } |
3451 | if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) { | 3506 | if (dest_tf_ops->tpg_parse_pr_out_transport_id == NULL) { |
3452 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not" | 3507 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Fabric does not" |
3453 | " containg a valid tpg_parse_pr_out_transport_id" | 3508 | " containg a valid tpg_parse_pr_out_transport_id" |
3454 | " function pointer\n"); | 3509 | " function pointer\n"); |
3455 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 3510 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3511 | ret = -EINVAL; | ||
3456 | goto out; | 3512 | goto out; |
3457 | } | 3513 | } |
3458 | initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg, | 3514 | initiator_str = dest_tf_ops->tpg_parse_pr_out_transport_id(dest_se_tpg, |
@@ -3460,7 +3516,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3460 | if (!initiator_str) { | 3516 | if (!initiator_str) { |
3461 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" | 3517 | pr_err("SPC-3 PR REGISTER_AND_MOVE: Unable to locate" |
3462 | " initiator_str from Transport ID\n"); | 3518 | " initiator_str from Transport ID\n"); |
3463 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3519 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3520 | ret = -EINVAL; | ||
3464 | goto out; | 3521 | goto out; |
3465 | } | 3522 | } |
3466 | 3523 | ||
@@ -3489,7 +3546,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3489 | pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s" | 3546 | pr_err("SPC-3 PR REGISTER_AND_MOVE: TransportID: %s" |
3490 | " matches: %s on received I_T Nexus\n", initiator_str, | 3547 | " matches: %s on received I_T Nexus\n", initiator_str, |
3491 | pr_reg_nacl->initiatorname); | 3548 | pr_reg_nacl->initiatorname); |
3492 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3549 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3550 | ret = -EINVAL; | ||
3493 | goto out; | 3551 | goto out; |
3494 | } | 3552 | } |
3495 | if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) { | 3553 | if (!strcmp(iport_ptr, pr_reg->pr_reg_isid)) { |
@@ -3497,7 +3555,8 @@ static int core_scsi3_emulate_pro_register_and_move( | |||
3497 | " matches: %s %s on received I_T Nexus\n", | 3555 | " matches: %s %s on received I_T Nexus\n", |
3498 | initiator_str, iport_ptr, pr_reg_nacl->initiatorname, | 3556 | initiator_str, iport_ptr, pr_reg_nacl->initiatorname, |
3499 | pr_reg->pr_reg_isid); | 3557 | pr_reg->pr_reg_isid); |
3500 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3558 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3559 | ret = -EINVAL; | ||
3501 | goto out; | 3560 | goto out; |
3502 | } | 3561 | } |
3503 | after_iport_check: | 3562 | after_iport_check: |
@@ -3517,7 +3576,8 @@ after_iport_check: | |||
3517 | pr_err("Unable to locate %s dest_node_acl for" | 3576 | pr_err("Unable to locate %s dest_node_acl for" |
3518 | " TransportID%s\n", dest_tf_ops->get_fabric_name(), | 3577 | " TransportID%s\n", dest_tf_ops->get_fabric_name(), |
3519 | initiator_str); | 3578 | initiator_str); |
3520 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3579 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3580 | ret = -EINVAL; | ||
3521 | goto out; | 3581 | goto out; |
3522 | } | 3582 | } |
3523 | ret = core_scsi3_nodeacl_depend_item(dest_node_acl); | 3583 | ret = core_scsi3_nodeacl_depend_item(dest_node_acl); |
@@ -3527,7 +3587,8 @@ after_iport_check: | |||
3527 | atomic_dec(&dest_node_acl->acl_pr_ref_count); | 3587 | atomic_dec(&dest_node_acl->acl_pr_ref_count); |
3528 | smp_mb__after_atomic_dec(); | 3588 | smp_mb__after_atomic_dec(); |
3529 | dest_node_acl = NULL; | 3589 | dest_node_acl = NULL; |
3530 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 3590 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3591 | ret = -EINVAL; | ||
3531 | goto out; | 3592 | goto out; |
3532 | } | 3593 | } |
3533 | #if 0 | 3594 | #if 0 |
@@ -3543,7 +3604,8 @@ after_iport_check: | |||
3543 | if (!dest_se_deve) { | 3604 | if (!dest_se_deve) { |
3544 | pr_err("Unable to locate %s dest_se_deve from RTPI:" | 3605 | pr_err("Unable to locate %s dest_se_deve from RTPI:" |
3545 | " %hu\n", dest_tf_ops->get_fabric_name(), rtpi); | 3606 | " %hu\n", dest_tf_ops->get_fabric_name(), rtpi); |
3546 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3607 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3608 | ret = -EINVAL; | ||
3547 | goto out; | 3609 | goto out; |
3548 | } | 3610 | } |
3549 | 3611 | ||
@@ -3553,7 +3615,8 @@ after_iport_check: | |||
3553 | atomic_dec(&dest_se_deve->pr_ref_count); | 3615 | atomic_dec(&dest_se_deve->pr_ref_count); |
3554 | smp_mb__after_atomic_dec(); | 3616 | smp_mb__after_atomic_dec(); |
3555 | dest_se_deve = NULL; | 3617 | dest_se_deve = NULL; |
3556 | ret = PYX_TRANSPORT_LU_COMM_FAILURE; | 3618 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3619 | ret = -EINVAL; | ||
3557 | goto out; | 3620 | goto out; |
3558 | } | 3621 | } |
3559 | #if 0 | 3622 | #if 0 |
@@ -3572,7 +3635,8 @@ after_iport_check: | |||
3572 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation" | 3635 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: No reservation" |
3573 | " currently held\n"); | 3636 | " currently held\n"); |
3574 | spin_unlock(&dev->dev_reservation_lock); | 3637 | spin_unlock(&dev->dev_reservation_lock); |
3575 | ret = PYX_TRANSPORT_INVALID_CDB_FIELD; | 3638 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
3639 | ret = -EINVAL; | ||
3576 | goto out; | 3640 | goto out; |
3577 | } | 3641 | } |
3578 | /* | 3642 | /* |
@@ -3585,7 +3649,8 @@ after_iport_check: | |||
3585 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" | 3649 | pr_warn("SPC-3 PR REGISTER_AND_MOVE: Calling I_T" |
3586 | " Nexus is not reservation holder\n"); | 3650 | " Nexus is not reservation holder\n"); |
3587 | spin_unlock(&dev->dev_reservation_lock); | 3651 | spin_unlock(&dev->dev_reservation_lock); |
3588 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; | 3652 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3653 | ret = -EINVAL; | ||
3589 | goto out; | 3654 | goto out; |
3590 | } | 3655 | } |
3591 | /* | 3656 | /* |
@@ -3603,7 +3668,8 @@ after_iport_check: | |||
3603 | " reservation for type: %s\n", | 3668 | " reservation for type: %s\n", |
3604 | core_scsi3_pr_dump_type(pr_res_holder->pr_res_type)); | 3669 | core_scsi3_pr_dump_type(pr_res_holder->pr_res_type)); |
3605 | spin_unlock(&dev->dev_reservation_lock); | 3670 | spin_unlock(&dev->dev_reservation_lock); |
3606 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; | 3671 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3672 | ret = -EINVAL; | ||
3607 | goto out; | 3673 | goto out; |
3608 | } | 3674 | } |
3609 | pr_res_nacl = pr_res_holder->pr_reg_nacl; | 3675 | pr_res_nacl = pr_res_holder->pr_reg_nacl; |
@@ -3640,7 +3706,8 @@ after_iport_check: | |||
3640 | sa_res_key, 0, aptpl, 2, 1); | 3706 | sa_res_key, 0, aptpl, 2, 1); |
3641 | if (ret != 0) { | 3707 | if (ret != 0) { |
3642 | spin_unlock(&dev->dev_reservation_lock); | 3708 | spin_unlock(&dev->dev_reservation_lock); |
3643 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3709 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3710 | ret = -EINVAL; | ||
3644 | goto out; | 3711 | goto out; |
3645 | } | 3712 | } |
3646 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, | 3713 | dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl, |
@@ -3771,7 +3838,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3771 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" | 3838 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" |
3772 | " SPC-2 reservation is held, returning" | 3839 | " SPC-2 reservation is held, returning" |
3773 | " RESERVATION_CONFLICT\n"); | 3840 | " RESERVATION_CONFLICT\n"); |
3774 | ret = PYX_TRANSPORT_RESERVATION_CONFLICT; | 3841 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
3842 | ret = EINVAL; | ||
3775 | goto out; | 3843 | goto out; |
3776 | } | 3844 | } |
3777 | 3845 | ||
@@ -3779,13 +3847,16 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3779 | * FIXME: A NULL struct se_session pointer means an this is not coming from | 3847 | * FIXME: A NULL struct se_session pointer means an this is not coming from |
3780 | * a $FABRIC_MOD's nexus, but from internal passthrough ops. | 3848 | * a $FABRIC_MOD's nexus, but from internal passthrough ops. |
3781 | */ | 3849 | */ |
3782 | if (!cmd->se_sess) | 3850 | if (!cmd->se_sess) { |
3783 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 3851 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
3852 | return -EINVAL; | ||
3853 | } | ||
3784 | 3854 | ||
3785 | if (cmd->data_length < 24) { | 3855 | if (cmd->data_length < 24) { |
3786 | pr_warn("SPC-PR: Received PR OUT parameter list" | 3856 | pr_warn("SPC-PR: Received PR OUT parameter list" |
3787 | " length too small: %u\n", cmd->data_length); | 3857 | " length too small: %u\n", cmd->data_length); |
3788 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3858 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3859 | ret = -EINVAL; | ||
3789 | goto out; | 3860 | goto out; |
3790 | } | 3861 | } |
3791 | /* | 3862 | /* |
@@ -3820,7 +3891,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3820 | * SPEC_I_PT=1 is only valid for Service action: REGISTER | 3891 | * SPEC_I_PT=1 is only valid for Service action: REGISTER |
3821 | */ | 3892 | */ |
3822 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) { | 3893 | if (spec_i_pt && ((cdb[1] & 0x1f) != PRO_REGISTER)) { |
3823 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3894 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3895 | ret = -EINVAL; | ||
3824 | goto out; | 3896 | goto out; |
3825 | } | 3897 | } |
3826 | 3898 | ||
@@ -3837,7 +3909,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3837 | (cmd->data_length != 24)) { | 3909 | (cmd->data_length != 24)) { |
3838 | pr_warn("SPC-PR: Received PR OUT illegal parameter" | 3910 | pr_warn("SPC-PR: Received PR OUT illegal parameter" |
3839 | " list length: %u\n", cmd->data_length); | 3911 | " list length: %u\n", cmd->data_length); |
3840 | ret = PYX_TRANSPORT_INVALID_PARAMETER_LIST; | 3912 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
3913 | ret = -EINVAL; | ||
3841 | goto out; | 3914 | goto out; |
3842 | } | 3915 | } |
3843 | /* | 3916 | /* |
@@ -3878,7 +3951,8 @@ int target_scsi3_emulate_pr_out(struct se_task *task) | |||
3878 | default: | 3951 | default: |
3879 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" | 3952 | pr_err("Unknown PERSISTENT_RESERVE_OUT service" |
3880 | " action: 0x%02x\n", cdb[1] & 0x1f); | 3953 | " action: 0x%02x\n", cdb[1] & 0x1f); |
3881 | ret = PYX_TRANSPORT_INVALID_CDB_FIELD; | 3954 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
3955 | ret = -EINVAL; | ||
3882 | break; | 3956 | break; |
3883 | } | 3957 | } |
3884 | 3958 | ||
@@ -3906,7 +3980,8 @@ static int core_scsi3_pri_read_keys(struct se_cmd *cmd) | |||
3906 | if (cmd->data_length < 8) { | 3980 | if (cmd->data_length < 8) { |
3907 | pr_err("PRIN SA READ_KEYS SCSI Data Length: %u" | 3981 | pr_err("PRIN SA READ_KEYS SCSI Data Length: %u" |
3908 | " too small\n", cmd->data_length); | 3982 | " too small\n", cmd->data_length); |
3909 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 3983 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
3984 | return -EINVAL; | ||
3910 | } | 3985 | } |
3911 | 3986 | ||
3912 | buf = transport_kmap_first_data_page(cmd); | 3987 | buf = transport_kmap_first_data_page(cmd); |
@@ -3965,7 +4040,8 @@ static int core_scsi3_pri_read_reservation(struct se_cmd *cmd) | |||
3965 | if (cmd->data_length < 8) { | 4040 | if (cmd->data_length < 8) { |
3966 | pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" | 4041 | pr_err("PRIN SA READ_RESERVATIONS SCSI Data Length: %u" |
3967 | " too small\n", cmd->data_length); | 4042 | " too small\n", cmd->data_length); |
3968 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 4043 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
4044 | return -EINVAL; | ||
3969 | } | 4045 | } |
3970 | 4046 | ||
3971 | buf = transport_kmap_first_data_page(cmd); | 4047 | buf = transport_kmap_first_data_page(cmd); |
@@ -4047,7 +4123,8 @@ static int core_scsi3_pri_report_capabilities(struct se_cmd *cmd) | |||
4047 | if (cmd->data_length < 6) { | 4123 | if (cmd->data_length < 6) { |
4048 | pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" | 4124 | pr_err("PRIN SA REPORT_CAPABILITIES SCSI Data Length:" |
4049 | " %u too small\n", cmd->data_length); | 4125 | " %u too small\n", cmd->data_length); |
4050 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 4126 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
4127 | return -EINVAL; | ||
4051 | } | 4128 | } |
4052 | 4129 | ||
4053 | buf = transport_kmap_first_data_page(cmd); | 4130 | buf = transport_kmap_first_data_page(cmd); |
@@ -4108,7 +4185,8 @@ static int core_scsi3_pri_read_full_status(struct se_cmd *cmd) | |||
4108 | if (cmd->data_length < 8) { | 4185 | if (cmd->data_length < 8) { |
4109 | pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" | 4186 | pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" |
4110 | " too small\n", cmd->data_length); | 4187 | " too small\n", cmd->data_length); |
4111 | return PYX_TRANSPORT_INVALID_CDB_FIELD; | 4188 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
4189 | return -EINVAL; | ||
4112 | } | 4190 | } |
4113 | 4191 | ||
4114 | buf = transport_kmap_first_data_page(cmd); | 4192 | buf = transport_kmap_first_data_page(cmd); |
@@ -4255,7 +4333,8 @@ int target_scsi3_emulate_pr_in(struct se_task *task) | |||
4255 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" | 4333 | pr_err("Received PERSISTENT_RESERVE CDB while legacy" |
4256 | " SPC-2 reservation is held, returning" | 4334 | " SPC-2 reservation is held, returning" |
4257 | " RESERVATION_CONFLICT\n"); | 4335 | " RESERVATION_CONFLICT\n"); |
4258 | return PYX_TRANSPORT_RESERVATION_CONFLICT; | 4336 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
4337 | return -EINVAL; | ||
4259 | } | 4338 | } |
4260 | 4339 | ||
4261 | switch (cmd->t_task_cdb[1] & 0x1f) { | 4340 | switch (cmd->t_task_cdb[1] & 0x1f) { |
@@ -4274,7 +4353,8 @@ int target_scsi3_emulate_pr_in(struct se_task *task) | |||
4274 | default: | 4353 | default: |
4275 | pr_err("Unknown PERSISTENT_RESERVE_IN service" | 4354 | pr_err("Unknown PERSISTENT_RESERVE_IN service" |
4276 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); | 4355 | " action: 0x%02x\n", cmd->t_task_cdb[1] & 0x1f); |
4277 | ret = PYX_TRANSPORT_INVALID_CDB_FIELD; | 4356 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; |
4357 | ret = -EINVAL; | ||
4278 | break; | 4358 | break; |
4279 | } | 4359 | } |
4280 | 4360 | ||
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index ed32e1efe429..8b15e56b0384 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -963,6 +963,7 @@ static inline struct bio *pscsi_get_bio(int sg_num) | |||
963 | static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, | 963 | static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, |
964 | struct bio **hbio) | 964 | struct bio **hbio) |
965 | { | 965 | { |
966 | struct se_cmd *cmd = task->task_se_cmd; | ||
966 | struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; | 967 | struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; |
967 | u32 task_sg_num = task->task_sg_nents; | 968 | u32 task_sg_num = task->task_sg_nents; |
968 | struct bio *bio = NULL, *tbio = NULL; | 969 | struct bio *bio = NULL, *tbio = NULL; |
@@ -971,7 +972,7 @@ static int pscsi_map_sg(struct se_task *task, struct scatterlist *task_sg, | |||
971 | u32 data_len = task->task_size, i, len, bytes, off; | 972 | u32 data_len = task->task_size, i, len, bytes, off; |
972 | int nr_pages = (task->task_size + task_sg[0].offset + | 973 | int nr_pages = (task->task_size + task_sg[0].offset + |
973 | PAGE_SIZE - 1) >> PAGE_SHIFT; | 974 | PAGE_SIZE - 1) >> PAGE_SHIFT; |
974 | int nr_vecs = 0, rc, ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; | 975 | int nr_vecs = 0, rc; |
975 | int rw = (task->task_data_direction == DMA_TO_DEVICE); | 976 | int rw = (task->task_data_direction == DMA_TO_DEVICE); |
976 | 977 | ||
977 | *hbio = NULL; | 978 | *hbio = NULL; |
@@ -1058,11 +1059,13 @@ fail: | |||
1058 | bio->bi_next = NULL; | 1059 | bio->bi_next = NULL; |
1059 | bio_endio(bio, 0); /* XXX: should be error */ | 1060 | bio_endio(bio, 0); /* XXX: should be error */ |
1060 | } | 1061 | } |
1061 | return ret; | 1062 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1063 | return -ENOMEM; | ||
1062 | } | 1064 | } |
1063 | 1065 | ||
1064 | static int pscsi_do_task(struct se_task *task) | 1066 | static int pscsi_do_task(struct se_task *task) |
1065 | { | 1067 | { |
1068 | struct se_cmd *cmd = task->task_se_cmd; | ||
1066 | struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; | 1069 | struct pscsi_dev_virt *pdv = task->task_se_cmd->se_dev->dev_ptr; |
1067 | struct pscsi_plugin_task *pt = PSCSI_TASK(task); | 1070 | struct pscsi_plugin_task *pt = PSCSI_TASK(task); |
1068 | struct request *req; | 1071 | struct request *req; |
@@ -1078,7 +1081,9 @@ static int pscsi_do_task(struct se_task *task) | |||
1078 | if (!req || IS_ERR(req)) { | 1081 | if (!req || IS_ERR(req)) { |
1079 | pr_err("PSCSI: blk_get_request() failed: %ld\n", | 1082 | pr_err("PSCSI: blk_get_request() failed: %ld\n", |
1080 | req ? IS_ERR(req) : -ENOMEM); | 1083 | req ? IS_ERR(req) : -ENOMEM); |
1081 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 1084 | cmd->scsi_sense_reason = |
1085 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1086 | return -ENODEV; | ||
1082 | } | 1087 | } |
1083 | } else { | 1088 | } else { |
1084 | BUG_ON(!task->task_size); | 1089 | BUG_ON(!task->task_size); |
@@ -1087,8 +1092,11 @@ static int pscsi_do_task(struct se_task *task) | |||
1087 | * Setup the main struct request for the task->task_sg[] payload | 1092 | * Setup the main struct request for the task->task_sg[] payload |
1088 | */ | 1093 | */ |
1089 | ret = pscsi_map_sg(task, task->task_sg, &hbio); | 1094 | ret = pscsi_map_sg(task, task->task_sg, &hbio); |
1090 | if (ret < 0) | 1095 | if (ret < 0) { |
1091 | return PYX_TRANSPORT_LU_COMM_FAILURE; | 1096 | cmd->scsi_sense_reason = |
1097 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1098 | return ret; | ||
1099 | } | ||
1092 | 1100 | ||
1093 | req = blk_make_request(pdv->pdv_sd->request_queue, hbio, | 1101 | req = blk_make_request(pdv->pdv_sd->request_queue, hbio, |
1094 | GFP_KERNEL); | 1102 | GFP_KERNEL); |
@@ -1115,7 +1123,7 @@ static int pscsi_do_task(struct se_task *task) | |||
1115 | (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG), | 1123 | (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG), |
1116 | pscsi_req_done); | 1124 | pscsi_req_done); |
1117 | 1125 | ||
1118 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | 1126 | return 0; |
1119 | 1127 | ||
1120 | fail: | 1128 | fail: |
1121 | while (hbio) { | 1129 | while (hbio) { |
@@ -1124,7 +1132,8 @@ fail: | |||
1124 | bio->bi_next = NULL; | 1132 | bio->bi_next = NULL; |
1125 | bio_endio(bio, 0); /* XXX: should be error */ | 1133 | bio_endio(bio, 0); /* XXX: should be error */ |
1126 | } | 1134 | } |
1127 | return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; | 1135 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
1136 | return -ENOMEM; | ||
1128 | } | 1137 | } |
1129 | 1138 | ||
1130 | /* pscsi_get_sense_buffer(): | 1139 | /* pscsi_get_sense_buffer(): |
@@ -1198,9 +1207,8 @@ static inline void pscsi_process_SAM_status( | |||
1198 | " 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0], | 1207 | " 0x%02x Result: 0x%08x\n", task, pt->pscsi_cdb[0], |
1199 | pt->pscsi_result); | 1208 | pt->pscsi_result); |
1200 | task->task_scsi_status = SAM_STAT_CHECK_CONDITION; | 1209 | task->task_scsi_status = SAM_STAT_CHECK_CONDITION; |
1201 | task->task_error_status = PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 1210 | task->task_se_cmd->scsi_sense_reason = |
1202 | task->task_se_cmd->transport_error_status = | 1211 | TCM_UNSUPPORTED_SCSI_OPCODE; |
1203 | PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | ||
1204 | transport_complete_task(task, 0); | 1212 | transport_complete_task(task, 0); |
1205 | break; | 1213 | break; |
1206 | } | 1214 | } |
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 5158d3846f19..02e51faa2f4e 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c | |||
@@ -343,235 +343,74 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct rd_dev *rd_dev, u32 page) | |||
343 | return NULL; | 343 | return NULL; |
344 | } | 344 | } |
345 | 345 | ||
346 | /* rd_MEMCPY_read(): | 346 | static int rd_MEMCPY(struct rd_request *req, u32 read_rd) |
347 | * | ||
348 | * | ||
349 | */ | ||
350 | static int rd_MEMCPY_read(struct rd_request *req) | ||
351 | { | 347 | { |
352 | struct se_task *task = &req->rd_task; | 348 | struct se_task *task = &req->rd_task; |
353 | struct rd_dev *dev = req->rd_task.task_se_cmd->se_dev->dev_ptr; | 349 | struct rd_dev *dev = req->rd_task.task_se_cmd->se_dev->dev_ptr; |
354 | struct rd_dev_sg_table *table; | 350 | struct rd_dev_sg_table *table; |
355 | struct scatterlist *sg_d, *sg_s; | 351 | struct scatterlist *rd_sg; |
356 | void *dst, *src; | 352 | struct sg_mapping_iter m; |
357 | u32 i = 0, j = 0, dst_offset = 0, src_offset = 0; | ||
358 | u32 length, page_end = 0, table_sg_end; | ||
359 | u32 rd_offset = req->rd_offset; | 353 | u32 rd_offset = req->rd_offset; |
354 | u32 src_len; | ||
360 | 355 | ||
361 | table = rd_get_sg_table(dev, req->rd_page); | 356 | table = rd_get_sg_table(dev, req->rd_page); |
362 | if (!table) | 357 | if (!table) |
363 | return -EINVAL; | 358 | return -EINVAL; |
364 | 359 | ||
365 | table_sg_end = (table->page_end_offset - req->rd_page); | 360 | rd_sg = &table->sg_table[req->rd_page - table->page_start_offset]; |
366 | sg_d = task->task_sg; | ||
367 | sg_s = &table->sg_table[req->rd_page - table->page_start_offset]; | ||
368 | 361 | ||
369 | pr_debug("RD[%u]: Read LBA: %llu, Size: %u Page: %u, Offset:" | 362 | pr_debug("RD[%u]: %s LBA: %llu, Size: %u Page: %u, Offset: %u\n", |
370 | " %u\n", dev->rd_dev_id, task->task_lba, req->rd_size, | 363 | dev->rd_dev_id, read_rd ? "Read" : "Write", |
371 | req->rd_page, req->rd_offset); | 364 | task->task_lba, req->rd_size, req->rd_page, |
372 | 365 | rd_offset); | |
373 | src_offset = rd_offset; | ||
374 | 366 | ||
367 | src_len = PAGE_SIZE - rd_offset; | ||
368 | sg_miter_start(&m, task->task_sg, task->task_sg_nents, | ||
369 | read_rd ? SG_MITER_TO_SG : SG_MITER_FROM_SG); | ||
375 | while (req->rd_size) { | 370 | while (req->rd_size) { |
376 | if ((sg_d[i].length - dst_offset) < | 371 | u32 len; |
377 | (sg_s[j].length - src_offset)) { | 372 | void *rd_addr; |
378 | length = (sg_d[i].length - dst_offset); | ||
379 | |||
380 | pr_debug("Step 1 - sg_d[%d]: %p length: %d" | ||
381 | " offset: %u sg_s[%d].length: %u\n", i, | ||
382 | &sg_d[i], sg_d[i].length, sg_d[i].offset, j, | ||
383 | sg_s[j].length); | ||
384 | pr_debug("Step 1 - length: %u dst_offset: %u" | ||
385 | " src_offset: %u\n", length, dst_offset, | ||
386 | src_offset); | ||
387 | |||
388 | if (length > req->rd_size) | ||
389 | length = req->rd_size; | ||
390 | |||
391 | dst = sg_virt(&sg_d[i++]) + dst_offset; | ||
392 | BUG_ON(!dst); | ||
393 | |||
394 | src = sg_virt(&sg_s[j]) + src_offset; | ||
395 | BUG_ON(!src); | ||
396 | |||
397 | dst_offset = 0; | ||
398 | src_offset = length; | ||
399 | page_end = 0; | ||
400 | } else { | ||
401 | length = (sg_s[j].length - src_offset); | ||
402 | |||
403 | pr_debug("Step 2 - sg_d[%d]: %p length: %d" | ||
404 | " offset: %u sg_s[%d].length: %u\n", i, | ||
405 | &sg_d[i], sg_d[i].length, sg_d[i].offset, | ||
406 | j, sg_s[j].length); | ||
407 | pr_debug("Step 2 - length: %u dst_offset: %u" | ||
408 | " src_offset: %u\n", length, dst_offset, | ||
409 | src_offset); | ||
410 | |||
411 | if (length > req->rd_size) | ||
412 | length = req->rd_size; | ||
413 | |||
414 | dst = sg_virt(&sg_d[i]) + dst_offset; | ||
415 | BUG_ON(!dst); | ||
416 | |||
417 | if (sg_d[i].length == length) { | ||
418 | i++; | ||
419 | dst_offset = 0; | ||
420 | } else | ||
421 | dst_offset = length; | ||
422 | |||
423 | src = sg_virt(&sg_s[j++]) + src_offset; | ||
424 | BUG_ON(!src); | ||
425 | |||
426 | src_offset = 0; | ||
427 | page_end = 1; | ||
428 | } | ||
429 | 373 | ||
430 | memcpy(dst, src, length); | 374 | sg_miter_next(&m); |
375 | len = min((u32)m.length, src_len); | ||
376 | m.consumed = len; | ||
431 | 377 | ||
432 | pr_debug("page: %u, remaining size: %u, length: %u," | 378 | rd_addr = sg_virt(rd_sg) + rd_offset; |
433 | " i: %u, j: %u\n", req->rd_page, | ||
434 | (req->rd_size - length), length, i, j); | ||
435 | 379 | ||
436 | req->rd_size -= length; | 380 | if (read_rd) |
437 | if (!req->rd_size) | 381 | memcpy(m.addr, rd_addr, len); |
438 | return 0; | 382 | else |
383 | memcpy(rd_addr, m.addr, len); | ||
439 | 384 | ||
440 | if (!page_end) | 385 | req->rd_size -= len; |
386 | if (!req->rd_size) | ||
441 | continue; | 387 | continue; |
442 | 388 | ||
443 | if (++req->rd_page <= table->page_end_offset) { | 389 | src_len -= len; |
444 | pr_debug("page: %u in same page table\n", | 390 | if (src_len) { |
445 | req->rd_page); | 391 | rd_offset += len; |
446 | continue; | 392 | continue; |
447 | } | 393 | } |
448 | 394 | ||
449 | pr_debug("getting new page table for page: %u\n", | 395 | /* rd page completed, next one please */ |
450 | req->rd_page); | 396 | req->rd_page++; |
451 | 397 | rd_offset = 0; | |
452 | table = rd_get_sg_table(dev, req->rd_page); | 398 | src_len = PAGE_SIZE; |
453 | if (!table) | 399 | if (req->rd_page <= table->page_end_offset) { |
454 | return -EINVAL; | 400 | rd_sg++; |
455 | |||
456 | sg_s = &table->sg_table[j = 0]; | ||
457 | } | ||
458 | |||
459 | return 0; | ||
460 | } | ||
461 | |||
462 | /* rd_MEMCPY_write(): | ||
463 | * | ||
464 | * | ||
465 | */ | ||
466 | static int rd_MEMCPY_write(struct rd_request *req) | ||
467 | { | ||
468 | struct se_task *task = &req->rd_task; | ||
469 | struct rd_dev *dev = req->rd_task.task_se_cmd->se_dev->dev_ptr; | ||
470 | struct rd_dev_sg_table *table; | ||
471 | struct scatterlist *sg_d, *sg_s; | ||
472 | void *dst, *src; | ||
473 | u32 i = 0, j = 0, dst_offset = 0, src_offset = 0; | ||
474 | u32 length, page_end = 0, table_sg_end; | ||
475 | u32 rd_offset = req->rd_offset; | ||
476 | |||
477 | table = rd_get_sg_table(dev, req->rd_page); | ||
478 | if (!table) | ||
479 | return -EINVAL; | ||
480 | |||
481 | table_sg_end = (table->page_end_offset - req->rd_page); | ||
482 | sg_d = &table->sg_table[req->rd_page - table->page_start_offset]; | ||
483 | sg_s = task->task_sg; | ||
484 | |||
485 | pr_debug("RD[%d] Write LBA: %llu, Size: %u, Page: %u," | ||
486 | " Offset: %u\n", dev->rd_dev_id, task->task_lba, req->rd_size, | ||
487 | req->rd_page, req->rd_offset); | ||
488 | |||
489 | dst_offset = rd_offset; | ||
490 | |||
491 | while (req->rd_size) { | ||
492 | if ((sg_s[i].length - src_offset) < | ||
493 | (sg_d[j].length - dst_offset)) { | ||
494 | length = (sg_s[i].length - src_offset); | ||
495 | |||
496 | pr_debug("Step 1 - sg_s[%d]: %p length: %d" | ||
497 | " offset: %d sg_d[%d].length: %u\n", i, | ||
498 | &sg_s[i], sg_s[i].length, sg_s[i].offset, | ||
499 | j, sg_d[j].length); | ||
500 | pr_debug("Step 1 - length: %u src_offset: %u" | ||
501 | " dst_offset: %u\n", length, src_offset, | ||
502 | dst_offset); | ||
503 | |||
504 | if (length > req->rd_size) | ||
505 | length = req->rd_size; | ||
506 | |||
507 | src = sg_virt(&sg_s[i++]) + src_offset; | ||
508 | BUG_ON(!src); | ||
509 | |||
510 | dst = sg_virt(&sg_d[j]) + dst_offset; | ||
511 | BUG_ON(!dst); | ||
512 | |||
513 | src_offset = 0; | ||
514 | dst_offset = length; | ||
515 | page_end = 0; | ||
516 | } else { | ||
517 | length = (sg_d[j].length - dst_offset); | ||
518 | |||
519 | pr_debug("Step 2 - sg_s[%d]: %p length: %d" | ||
520 | " offset: %d sg_d[%d].length: %u\n", i, | ||
521 | &sg_s[i], sg_s[i].length, sg_s[i].offset, | ||
522 | j, sg_d[j].length); | ||
523 | pr_debug("Step 2 - length: %u src_offset: %u" | ||
524 | " dst_offset: %u\n", length, src_offset, | ||
525 | dst_offset); | ||
526 | |||
527 | if (length > req->rd_size) | ||
528 | length = req->rd_size; | ||
529 | |||
530 | src = sg_virt(&sg_s[i]) + src_offset; | ||
531 | BUG_ON(!src); | ||
532 | |||
533 | if (sg_s[i].length == length) { | ||
534 | i++; | ||
535 | src_offset = 0; | ||
536 | } else | ||
537 | src_offset = length; | ||
538 | |||
539 | dst = sg_virt(&sg_d[j++]) + dst_offset; | ||
540 | BUG_ON(!dst); | ||
541 | |||
542 | dst_offset = 0; | ||
543 | page_end = 1; | ||
544 | } | ||
545 | |||
546 | memcpy(dst, src, length); | ||
547 | |||
548 | pr_debug("page: %u, remaining size: %u, length: %u," | ||
549 | " i: %u, j: %u\n", req->rd_page, | ||
550 | (req->rd_size - length), length, i, j); | ||
551 | |||
552 | req->rd_size -= length; | ||
553 | if (!req->rd_size) | ||
554 | return 0; | ||
555 | |||
556 | if (!page_end) | ||
557 | continue; | ||
558 | |||
559 | if (++req->rd_page <= table->page_end_offset) { | ||
560 | pr_debug("page: %u in same page table\n", | ||
561 | req->rd_page); | ||
562 | continue; | 401 | continue; |
563 | } | 402 | } |
564 | 403 | ||
565 | pr_debug("getting new page table for page: %u\n", | ||
566 | req->rd_page); | ||
567 | |||
568 | table = rd_get_sg_table(dev, req->rd_page); | 404 | table = rd_get_sg_table(dev, req->rd_page); |
569 | if (!table) | 405 | if (!table) { |
406 | sg_miter_stop(&m); | ||
570 | return -EINVAL; | 407 | return -EINVAL; |
408 | } | ||
571 | 409 | ||
572 | sg_d = &table->sg_table[j = 0]; | 410 | /* since we increment, the first sg entry is correct */ |
411 | rd_sg = table->sg_table; | ||
573 | } | 412 | } |
574 | 413 | sg_miter_stop(&m); | |
575 | return 0; | 414 | return 0; |
576 | } | 415 | } |
577 | 416 | ||
@@ -583,28 +422,21 @@ static int rd_MEMCPY_do_task(struct se_task *task) | |||
583 | { | 422 | { |
584 | struct se_device *dev = task->task_se_cmd->se_dev; | 423 | struct se_device *dev = task->task_se_cmd->se_dev; |
585 | struct rd_request *req = RD_REQ(task); | 424 | struct rd_request *req = RD_REQ(task); |
586 | unsigned long long lba; | 425 | u64 tmp; |
587 | int ret; | 426 | int ret; |
588 | 427 | ||
589 | req->rd_page = (task->task_lba * dev->se_sub_dev->se_dev_attrib.block_size) / PAGE_SIZE; | 428 | tmp = task->task_lba * dev->se_sub_dev->se_dev_attrib.block_size; |
590 | lba = task->task_lba; | 429 | req->rd_offset = do_div(tmp, PAGE_SIZE); |
591 | req->rd_offset = (do_div(lba, | 430 | req->rd_page = tmp; |
592 | (PAGE_SIZE / dev->se_sub_dev->se_dev_attrib.block_size))) * | ||
593 | dev->se_sub_dev->se_dev_attrib.block_size; | ||
594 | req->rd_size = task->task_size; | 431 | req->rd_size = task->task_size; |
595 | 432 | ||
596 | if (task->task_data_direction == DMA_FROM_DEVICE) | 433 | ret = rd_MEMCPY(req, task->task_data_direction == DMA_FROM_DEVICE); |
597 | ret = rd_MEMCPY_read(req); | ||
598 | else | ||
599 | ret = rd_MEMCPY_write(req); | ||
600 | |||
601 | if (ret != 0) | 434 | if (ret != 0) |
602 | return ret; | 435 | return ret; |
603 | 436 | ||
604 | task->task_scsi_status = GOOD; | 437 | task->task_scsi_status = GOOD; |
605 | transport_complete_task(task, 1); | 438 | transport_complete_task(task, 1); |
606 | 439 | return 0; | |
607 | return PYX_TRANSPORT_SENT_TO_TRANSPORT; | ||
608 | } | 440 | } |
609 | 441 | ||
610 | /* rd_free_task(): (Part of se_subsystem_api_t template) | 442 | /* rd_free_task(): (Part of se_subsystem_api_t template) |
diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 217e29df6297..684522805a1f 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c | |||
@@ -345,10 +345,6 @@ static void core_tmr_drain_cmd_list( | |||
345 | " %d t_fe_count: %d\n", (preempt_and_abort_list) ? | 345 | " %d t_fe_count: %d\n", (preempt_and_abort_list) ? |
346 | "Preempt" : "", cmd, cmd->t_state, | 346 | "Preempt" : "", cmd, cmd->t_state, |
347 | atomic_read(&cmd->t_fe_count)); | 347 | atomic_read(&cmd->t_fe_count)); |
348 | /* | ||
349 | * Signal that the command has failed via cmd->se_cmd_flags, | ||
350 | */ | ||
351 | transport_new_cmd_failure(cmd); | ||
352 | 348 | ||
353 | core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, | 349 | core_tmr_handle_tas_abort(tmr_nacl, cmd, tas, |
354 | atomic_read(&cmd->t_fe_count)); | 350 | atomic_read(&cmd->t_fe_count)); |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 3400ae6e93f8..0257658e2e3e 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -61,7 +61,6 @@ | |||
61 | static int sub_api_initialized; | 61 | static int sub_api_initialized; |
62 | 62 | ||
63 | static struct workqueue_struct *target_completion_wq; | 63 | static struct workqueue_struct *target_completion_wq; |
64 | static struct kmem_cache *se_cmd_cache; | ||
65 | static struct kmem_cache *se_sess_cache; | 64 | static struct kmem_cache *se_sess_cache; |
66 | struct kmem_cache *se_tmr_req_cache; | 65 | struct kmem_cache *se_tmr_req_cache; |
67 | struct kmem_cache *se_ua_cache; | 66 | struct kmem_cache *se_ua_cache; |
@@ -82,24 +81,18 @@ static int transport_generic_get_mem(struct se_cmd *cmd); | |||
82 | static void transport_put_cmd(struct se_cmd *cmd); | 81 | static void transport_put_cmd(struct se_cmd *cmd); |
83 | static void transport_remove_cmd_from_queue(struct se_cmd *cmd); | 82 | static void transport_remove_cmd_from_queue(struct se_cmd *cmd); |
84 | static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq); | 83 | static int transport_set_sense_codes(struct se_cmd *cmd, u8 asc, u8 ascq); |
85 | static void transport_generic_request_failure(struct se_cmd *, int, int); | 84 | static void transport_generic_request_failure(struct se_cmd *); |
86 | static void target_complete_ok_work(struct work_struct *work); | 85 | static void target_complete_ok_work(struct work_struct *work); |
87 | 86 | ||
88 | int init_se_kmem_caches(void) | 87 | int init_se_kmem_caches(void) |
89 | { | 88 | { |
90 | se_cmd_cache = kmem_cache_create("se_cmd_cache", | ||
91 | sizeof(struct se_cmd), __alignof__(struct se_cmd), 0, NULL); | ||
92 | if (!se_cmd_cache) { | ||
93 | pr_err("kmem_cache_create for struct se_cmd failed\n"); | ||
94 | goto out; | ||
95 | } | ||
96 | se_tmr_req_cache = kmem_cache_create("se_tmr_cache", | 89 | se_tmr_req_cache = kmem_cache_create("se_tmr_cache", |
97 | sizeof(struct se_tmr_req), __alignof__(struct se_tmr_req), | 90 | sizeof(struct se_tmr_req), __alignof__(struct se_tmr_req), |
98 | 0, NULL); | 91 | 0, NULL); |
99 | if (!se_tmr_req_cache) { | 92 | if (!se_tmr_req_cache) { |
100 | pr_err("kmem_cache_create() for struct se_tmr_req" | 93 | pr_err("kmem_cache_create() for struct se_tmr_req" |
101 | " failed\n"); | 94 | " failed\n"); |
102 | goto out_free_cmd_cache; | 95 | goto out; |
103 | } | 96 | } |
104 | se_sess_cache = kmem_cache_create("se_sess_cache", | 97 | se_sess_cache = kmem_cache_create("se_sess_cache", |
105 | sizeof(struct se_session), __alignof__(struct se_session), | 98 | sizeof(struct se_session), __alignof__(struct se_session), |
@@ -182,8 +175,6 @@ out_free_sess_cache: | |||
182 | kmem_cache_destroy(se_sess_cache); | 175 | kmem_cache_destroy(se_sess_cache); |
183 | out_free_tmr_req_cache: | 176 | out_free_tmr_req_cache: |
184 | kmem_cache_destroy(se_tmr_req_cache); | 177 | kmem_cache_destroy(se_tmr_req_cache); |
185 | out_free_cmd_cache: | ||
186 | kmem_cache_destroy(se_cmd_cache); | ||
187 | out: | 178 | out: |
188 | return -ENOMEM; | 179 | return -ENOMEM; |
189 | } | 180 | } |
@@ -191,7 +182,6 @@ out: | |||
191 | void release_se_kmem_caches(void) | 182 | void release_se_kmem_caches(void) |
192 | { | 183 | { |
193 | destroy_workqueue(target_completion_wq); | 184 | destroy_workqueue(target_completion_wq); |
194 | kmem_cache_destroy(se_cmd_cache); | ||
195 | kmem_cache_destroy(se_tmr_req_cache); | 185 | kmem_cache_destroy(se_tmr_req_cache); |
196 | kmem_cache_destroy(se_sess_cache); | 186 | kmem_cache_destroy(se_sess_cache); |
197 | kmem_cache_destroy(se_ua_cache); | 187 | kmem_cache_destroy(se_ua_cache); |
@@ -680,9 +670,9 @@ void transport_complete_sync_cache(struct se_cmd *cmd, int good) | |||
680 | task->task_scsi_status = GOOD; | 670 | task->task_scsi_status = GOOD; |
681 | } else { | 671 | } else { |
682 | task->task_scsi_status = SAM_STAT_CHECK_CONDITION; | 672 | task->task_scsi_status = SAM_STAT_CHECK_CONDITION; |
683 | task->task_error_status = PYX_TRANSPORT_ILLEGAL_REQUEST; | 673 | task->task_se_cmd->scsi_sense_reason = |
684 | task->task_se_cmd->transport_error_status = | 674 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
685 | PYX_TRANSPORT_ILLEGAL_REQUEST; | 675 | |
686 | } | 676 | } |
687 | 677 | ||
688 | transport_complete_task(task, good); | 678 | transport_complete_task(task, good); |
@@ -693,7 +683,7 @@ static void target_complete_failure_work(struct work_struct *work) | |||
693 | { | 683 | { |
694 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); | 684 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); |
695 | 685 | ||
696 | transport_generic_request_failure(cmd, 1, 1); | 686 | transport_generic_request_failure(cmd); |
697 | } | 687 | } |
698 | 688 | ||
699 | /* transport_complete_task(): | 689 | /* transport_complete_task(): |
@@ -755,10 +745,11 @@ void transport_complete_task(struct se_task *task, int success) | |||
755 | if (cmd->t_tasks_failed) { | 745 | if (cmd->t_tasks_failed) { |
756 | if (!task->task_error_status) { | 746 | if (!task->task_error_status) { |
757 | task->task_error_status = | 747 | task->task_error_status = |
758 | PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 748 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
759 | cmd->transport_error_status = | 749 | cmd->scsi_sense_reason = |
760 | PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; | 750 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
761 | } | 751 | } |
752 | |||
762 | INIT_WORK(&cmd->work, target_complete_failure_work); | 753 | INIT_WORK(&cmd->work, target_complete_failure_work); |
763 | } else { | 754 | } else { |
764 | atomic_set(&cmd->t_transport_complete, 1); | 755 | atomic_set(&cmd->t_transport_complete, 1); |
@@ -1335,23 +1326,17 @@ struct se_device *transport_add_device_to_core_hba( | |||
1335 | dev->se_hba = hba; | 1326 | dev->se_hba = hba; |
1336 | dev->se_sub_dev = se_dev; | 1327 | dev->se_sub_dev = se_dev; |
1337 | dev->transport = transport; | 1328 | dev->transport = transport; |
1338 | atomic_set(&dev->active_cmds, 0); | ||
1339 | INIT_LIST_HEAD(&dev->dev_list); | 1329 | INIT_LIST_HEAD(&dev->dev_list); |
1340 | INIT_LIST_HEAD(&dev->dev_sep_list); | 1330 | INIT_LIST_HEAD(&dev->dev_sep_list); |
1341 | INIT_LIST_HEAD(&dev->dev_tmr_list); | 1331 | INIT_LIST_HEAD(&dev->dev_tmr_list); |
1342 | INIT_LIST_HEAD(&dev->execute_task_list); | 1332 | INIT_LIST_HEAD(&dev->execute_task_list); |
1343 | INIT_LIST_HEAD(&dev->delayed_cmd_list); | 1333 | INIT_LIST_HEAD(&dev->delayed_cmd_list); |
1344 | INIT_LIST_HEAD(&dev->ordered_cmd_list); | ||
1345 | INIT_LIST_HEAD(&dev->state_task_list); | 1334 | INIT_LIST_HEAD(&dev->state_task_list); |
1346 | INIT_LIST_HEAD(&dev->qf_cmd_list); | 1335 | INIT_LIST_HEAD(&dev->qf_cmd_list); |
1347 | spin_lock_init(&dev->execute_task_lock); | 1336 | spin_lock_init(&dev->execute_task_lock); |
1348 | spin_lock_init(&dev->delayed_cmd_lock); | 1337 | spin_lock_init(&dev->delayed_cmd_lock); |
1349 | spin_lock_init(&dev->ordered_cmd_lock); | ||
1350 | spin_lock_init(&dev->state_task_lock); | ||
1351 | spin_lock_init(&dev->dev_alua_lock); | ||
1352 | spin_lock_init(&dev->dev_reservation_lock); | 1338 | spin_lock_init(&dev->dev_reservation_lock); |
1353 | spin_lock_init(&dev->dev_status_lock); | 1339 | spin_lock_init(&dev->dev_status_lock); |
1354 | spin_lock_init(&dev->dev_status_thr_lock); | ||
1355 | spin_lock_init(&dev->se_port_lock); | 1340 | spin_lock_init(&dev->se_port_lock); |
1356 | spin_lock_init(&dev->se_tmr_lock); | 1341 | spin_lock_init(&dev->se_tmr_lock); |
1357 | spin_lock_init(&dev->qf_cmd_lock); | 1342 | spin_lock_init(&dev->qf_cmd_lock); |
@@ -1507,7 +1492,6 @@ void transport_init_se_cmd( | |||
1507 | { | 1492 | { |
1508 | INIT_LIST_HEAD(&cmd->se_lun_node); | 1493 | INIT_LIST_HEAD(&cmd->se_lun_node); |
1509 | INIT_LIST_HEAD(&cmd->se_delayed_node); | 1494 | INIT_LIST_HEAD(&cmd->se_delayed_node); |
1510 | INIT_LIST_HEAD(&cmd->se_ordered_node); | ||
1511 | INIT_LIST_HEAD(&cmd->se_qf_node); | 1495 | INIT_LIST_HEAD(&cmd->se_qf_node); |
1512 | INIT_LIST_HEAD(&cmd->se_queue_node); | 1496 | INIT_LIST_HEAD(&cmd->se_queue_node); |
1513 | INIT_LIST_HEAD(&cmd->se_cmd_list); | 1497 | INIT_LIST_HEAD(&cmd->se_cmd_list); |
@@ -1573,6 +1557,8 @@ int transport_generic_allocate_tasks( | |||
1573 | pr_err("Received SCSI CDB with command_size: %d that" | 1557 | pr_err("Received SCSI CDB with command_size: %d that" |
1574 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", | 1558 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", |
1575 | scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE); | 1559 | scsi_command_size(cdb), SCSI_MAX_VARLEN_CDB_SIZE); |
1560 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1561 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1576 | return -EINVAL; | 1562 | return -EINVAL; |
1577 | } | 1563 | } |
1578 | /* | 1564 | /* |
@@ -1588,6 +1574,9 @@ int transport_generic_allocate_tasks( | |||
1588 | " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", | 1574 | " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", |
1589 | scsi_command_size(cdb), | 1575 | scsi_command_size(cdb), |
1590 | (unsigned long)sizeof(cmd->__t_task_cdb)); | 1576 | (unsigned long)sizeof(cmd->__t_task_cdb)); |
1577 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
1578 | cmd->scsi_sense_reason = | ||
1579 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1591 | return -ENOMEM; | 1580 | return -ENOMEM; |
1592 | } | 1581 | } |
1593 | } else | 1582 | } else |
@@ -1658,11 +1647,9 @@ int transport_handle_cdb_direct( | |||
1658 | * and call transport_generic_request_failure() if necessary.. | 1647 | * and call transport_generic_request_failure() if necessary.. |
1659 | */ | 1648 | */ |
1660 | ret = transport_generic_new_cmd(cmd); | 1649 | ret = transport_generic_new_cmd(cmd); |
1661 | if (ret < 0) { | 1650 | if (ret < 0) |
1662 | cmd->transport_error_status = ret; | 1651 | transport_generic_request_failure(cmd); |
1663 | transport_generic_request_failure(cmd, 0, | 1652 | |
1664 | (cmd->data_direction != DMA_TO_DEVICE)); | ||
1665 | } | ||
1666 | return 0; | 1653 | return 0; |
1667 | } | 1654 | } |
1668 | EXPORT_SYMBOL(transport_handle_cdb_direct); | 1655 | EXPORT_SYMBOL(transport_handle_cdb_direct); |
@@ -1798,20 +1785,16 @@ static int transport_stop_tasks_for_cmd(struct se_cmd *cmd) | |||
1798 | /* | 1785 | /* |
1799 | * Handle SAM-esque emulation for generic transport request failures. | 1786 | * Handle SAM-esque emulation for generic transport request failures. |
1800 | */ | 1787 | */ |
1801 | static void transport_generic_request_failure( | 1788 | static void transport_generic_request_failure(struct se_cmd *cmd) |
1802 | struct se_cmd *cmd, | ||
1803 | int complete, | ||
1804 | int sc) | ||
1805 | { | 1789 | { |
1806 | int ret = 0; | 1790 | int ret = 0; |
1807 | 1791 | ||
1808 | pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" | 1792 | pr_debug("-----[ Storage Engine Exception for cmd: %p ITT: 0x%08x" |
1809 | " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), | 1793 | " CDB: 0x%02x\n", cmd, cmd->se_tfo->get_task_tag(cmd), |
1810 | cmd->t_task_cdb[0]); | 1794 | cmd->t_task_cdb[0]); |
1811 | pr_debug("-----[ i_state: %d t_state: %d transport_error_status: %d\n", | 1795 | pr_debug("-----[ i_state: %d t_state: %d scsi_sense_reason: %d\n", |
1812 | cmd->se_tfo->get_cmd_state(cmd), | 1796 | cmd->se_tfo->get_cmd_state(cmd), |
1813 | cmd->t_state, | 1797 | cmd->t_state, cmd->scsi_sense_reason); |
1814 | cmd->transport_error_status); | ||
1815 | pr_debug("-----[ t_tasks: %d t_task_cdbs_left: %d" | 1798 | pr_debug("-----[ t_tasks: %d t_task_cdbs_left: %d" |
1816 | " t_task_cdbs_sent: %d t_task_cdbs_ex_left: %d --" | 1799 | " t_task_cdbs_sent: %d t_task_cdbs_ex_left: %d --" |
1817 | " t_transport_active: %d t_transport_stop: %d" | 1800 | " t_transport_active: %d t_transport_stop: %d" |
@@ -1829,46 +1812,19 @@ static void transport_generic_request_failure( | |||
1829 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) | 1812 | if (cmd->se_dev->dev_task_attr_type == SAM_TASK_ATTR_EMULATED) |
1830 | transport_complete_task_attr(cmd); | 1813 | transport_complete_task_attr(cmd); |
1831 | 1814 | ||
1832 | if (complete) { | 1815 | switch (cmd->scsi_sense_reason) { |
1833 | cmd->transport_error_status = PYX_TRANSPORT_LU_COMM_FAILURE; | 1816 | case TCM_NON_EXISTENT_LUN: |
1834 | } | 1817 | case TCM_UNSUPPORTED_SCSI_OPCODE: |
1835 | 1818 | case TCM_INVALID_CDB_FIELD: | |
1836 | switch (cmd->transport_error_status) { | 1819 | case TCM_INVALID_PARAMETER_LIST: |
1837 | case PYX_TRANSPORT_UNKNOWN_SAM_OPCODE: | 1820 | case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE: |
1838 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 1821 | case TCM_UNKNOWN_MODE_PAGE: |
1839 | break; | 1822 | case TCM_WRITE_PROTECTED: |
1840 | case PYX_TRANSPORT_REQ_TOO_MANY_SECTORS: | 1823 | case TCM_CHECK_CONDITION_ABORT_CMD: |
1841 | cmd->scsi_sense_reason = TCM_SECTOR_COUNT_TOO_MANY; | 1824 | case TCM_CHECK_CONDITION_UNIT_ATTENTION: |
1842 | break; | 1825 | case TCM_CHECK_CONDITION_NOT_READY: |
1843 | case PYX_TRANSPORT_INVALID_CDB_FIELD: | ||
1844 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
1845 | break; | ||
1846 | case PYX_TRANSPORT_INVALID_PARAMETER_LIST: | ||
1847 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
1848 | break; | ||
1849 | case PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES: | ||
1850 | if (!sc) | ||
1851 | transport_new_cmd_failure(cmd); | ||
1852 | /* | ||
1853 | * Currently for PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES, | ||
1854 | * we force this session to fall back to session | ||
1855 | * recovery. | ||
1856 | */ | ||
1857 | cmd->se_tfo->fall_back_to_erl0(cmd->se_sess); | ||
1858 | cmd->se_tfo->stop_session(cmd->se_sess, 0, 0); | ||
1859 | |||
1860 | goto check_stop; | ||
1861 | case PYX_TRANSPORT_LU_COMM_FAILURE: | ||
1862 | case PYX_TRANSPORT_ILLEGAL_REQUEST: | ||
1863 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
1864 | break; | ||
1865 | case PYX_TRANSPORT_UNKNOWN_MODE_PAGE: | ||
1866 | cmd->scsi_sense_reason = TCM_UNKNOWN_MODE_PAGE; | ||
1867 | break; | ||
1868 | case PYX_TRANSPORT_WRITE_PROTECTED: | ||
1869 | cmd->scsi_sense_reason = TCM_WRITE_PROTECTED; | ||
1870 | break; | 1826 | break; |
1871 | case PYX_TRANSPORT_RESERVATION_CONFLICT: | 1827 | case TCM_RESERVATION_CONFLICT: |
1872 | /* | 1828 | /* |
1873 | * No SENSE Data payload for this case, set SCSI Status | 1829 | * No SENSE Data payload for this case, set SCSI Status |
1874 | * and queue the response to $FABRIC_MOD. | 1830 | * and queue the response to $FABRIC_MOD. |
@@ -1893,15 +1849,9 @@ static void transport_generic_request_failure( | |||
1893 | if (ret == -EAGAIN || ret == -ENOMEM) | 1849 | if (ret == -EAGAIN || ret == -ENOMEM) |
1894 | goto queue_full; | 1850 | goto queue_full; |
1895 | goto check_stop; | 1851 | goto check_stop; |
1896 | case PYX_TRANSPORT_USE_SENSE_REASON: | ||
1897 | /* | ||
1898 | * struct se_cmd->scsi_sense_reason already set | ||
1899 | */ | ||
1900 | break; | ||
1901 | default: | 1852 | default: |
1902 | pr_err("Unknown transport error for CDB 0x%02x: %d\n", | 1853 | pr_err("Unknown transport error for CDB 0x%02x: %d\n", |
1903 | cmd->t_task_cdb[0], | 1854 | cmd->t_task_cdb[0], cmd->scsi_sense_reason); |
1904 | cmd->transport_error_status); | ||
1905 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; | 1855 | cmd->scsi_sense_reason = TCM_UNSUPPORTED_SCSI_OPCODE; |
1906 | break; | 1856 | break; |
1907 | } | 1857 | } |
@@ -1912,14 +1862,10 @@ static void transport_generic_request_failure( | |||
1912 | * transport_send_check_condition_and_sense() after handling | 1862 | * transport_send_check_condition_and_sense() after handling |
1913 | * possible unsoliticied write data payloads. | 1863 | * possible unsoliticied write data payloads. |
1914 | */ | 1864 | */ |
1915 | if (!sc && !cmd->se_tfo->new_cmd_map) | 1865 | ret = transport_send_check_condition_and_sense(cmd, |
1916 | transport_new_cmd_failure(cmd); | 1866 | cmd->scsi_sense_reason, 0); |
1917 | else { | 1867 | if (ret == -EAGAIN || ret == -ENOMEM) |
1918 | ret = transport_send_check_condition_and_sense(cmd, | 1868 | goto queue_full; |
1919 | cmd->scsi_sense_reason, 0); | ||
1920 | if (ret == -EAGAIN || ret == -ENOMEM) | ||
1921 | goto queue_full; | ||
1922 | } | ||
1923 | 1869 | ||
1924 | check_stop: | 1870 | check_stop: |
1925 | transport_lun_remove_cmd(cmd); | 1871 | transport_lun_remove_cmd(cmd); |
@@ -2002,19 +1948,12 @@ static inline int transport_execute_task_attr(struct se_cmd *cmd) | |||
2002 | * to allow the passed struct se_cmd list of tasks to the front of the list. | 1948 | * to allow the passed struct se_cmd list of tasks to the front of the list. |
2003 | */ | 1949 | */ |
2004 | if (cmd->sam_task_attr == MSG_HEAD_TAG) { | 1950 | if (cmd->sam_task_attr == MSG_HEAD_TAG) { |
2005 | atomic_inc(&cmd->se_dev->dev_hoq_count); | ||
2006 | smp_mb__after_atomic_inc(); | ||
2007 | pr_debug("Added HEAD_OF_QUEUE for CDB:" | 1951 | pr_debug("Added HEAD_OF_QUEUE for CDB:" |
2008 | " 0x%02x, se_ordered_id: %u\n", | 1952 | " 0x%02x, se_ordered_id: %u\n", |
2009 | cmd->t_task_cdb[0], | 1953 | cmd->t_task_cdb[0], |
2010 | cmd->se_ordered_id); | 1954 | cmd->se_ordered_id); |
2011 | return 1; | 1955 | return 1; |
2012 | } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { | 1956 | } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { |
2013 | spin_lock(&cmd->se_dev->ordered_cmd_lock); | ||
2014 | list_add_tail(&cmd->se_ordered_node, | ||
2015 | &cmd->se_dev->ordered_cmd_list); | ||
2016 | spin_unlock(&cmd->se_dev->ordered_cmd_lock); | ||
2017 | |||
2018 | atomic_inc(&cmd->se_dev->dev_ordered_sync); | 1957 | atomic_inc(&cmd->se_dev->dev_ordered_sync); |
2019 | smp_mb__after_atomic_inc(); | 1958 | smp_mb__after_atomic_inc(); |
2020 | 1959 | ||
@@ -2076,9 +2015,9 @@ static int transport_execute_tasks(struct se_cmd *cmd) | |||
2076 | { | 2015 | { |
2077 | int add_tasks; | 2016 | int add_tasks; |
2078 | 2017 | ||
2079 | if (se_dev_check_online(cmd->se_orig_obj_ptr) != 0) { | 2018 | if (se_dev_check_online(cmd->se_dev) != 0) { |
2080 | cmd->transport_error_status = PYX_TRANSPORT_LU_COMM_FAILURE; | 2019 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
2081 | transport_generic_request_failure(cmd, 0, 1); | 2020 | transport_generic_request_failure(cmd); |
2082 | return 0; | 2021 | return 0; |
2083 | } | 2022 | } |
2084 | 2023 | ||
@@ -2163,14 +2102,13 @@ check_depth: | |||
2163 | else | 2102 | else |
2164 | error = dev->transport->do_task(task); | 2103 | error = dev->transport->do_task(task); |
2165 | if (error != 0) { | 2104 | if (error != 0) { |
2166 | cmd->transport_error_status = error; | ||
2167 | spin_lock_irqsave(&cmd->t_state_lock, flags); | 2105 | spin_lock_irqsave(&cmd->t_state_lock, flags); |
2168 | task->task_flags &= ~TF_ACTIVE; | 2106 | task->task_flags &= ~TF_ACTIVE; |
2169 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | 2107 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); |
2170 | atomic_set(&cmd->t_transport_sent, 0); | 2108 | atomic_set(&cmd->t_transport_sent, 0); |
2171 | transport_stop_tasks_for_cmd(cmd); | 2109 | transport_stop_tasks_for_cmd(cmd); |
2172 | atomic_inc(&dev->depth_left); | 2110 | atomic_inc(&dev->depth_left); |
2173 | transport_generic_request_failure(cmd, 0, 1); | 2111 | transport_generic_request_failure(cmd); |
2174 | } | 2112 | } |
2175 | 2113 | ||
2176 | goto check_depth; | 2114 | goto check_depth; |
@@ -2178,19 +2116,6 @@ check_depth: | |||
2178 | return 0; | 2116 | return 0; |
2179 | } | 2117 | } |
2180 | 2118 | ||
2181 | void transport_new_cmd_failure(struct se_cmd *se_cmd) | ||
2182 | { | ||
2183 | unsigned long flags; | ||
2184 | /* | ||
2185 | * Any unsolicited data will get dumped for failed command inside of | ||
2186 | * the fabric plugin | ||
2187 | */ | ||
2188 | spin_lock_irqsave(&se_cmd->t_state_lock, flags); | ||
2189 | se_cmd->se_cmd_flags |= SCF_SE_CMD_FAILED; | ||
2190 | se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
2191 | spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); | ||
2192 | } | ||
2193 | |||
2194 | static inline u32 transport_get_sectors_6( | 2119 | static inline u32 transport_get_sectors_6( |
2195 | unsigned char *cdb, | 2120 | unsigned char *cdb, |
2196 | struct se_cmd *cmd, | 2121 | struct se_cmd *cmd, |
@@ -2213,10 +2138,15 @@ static inline u32 transport_get_sectors_6( | |||
2213 | 2138 | ||
2214 | /* | 2139 | /* |
2215 | * Everything else assume TYPE_DISK Sector CDB location. | 2140 | * Everything else assume TYPE_DISK Sector CDB location. |
2216 | * Use 8-bit sector value. | 2141 | * Use 8-bit sector value. SBC-3 says: |
2142 | * | ||
2143 | * A TRANSFER LENGTH field set to zero specifies that 256 | ||
2144 | * logical blocks shall be written. Any other value | ||
2145 | * specifies the number of logical blocks that shall be | ||
2146 | * written. | ||
2217 | */ | 2147 | */ |
2218 | type_disk: | 2148 | type_disk: |
2219 | return (u32)cdb[4]; | 2149 | return cdb[4] ? : 256; |
2220 | } | 2150 | } |
2221 | 2151 | ||
2222 | static inline u32 transport_get_sectors_10( | 2152 | static inline u32 transport_get_sectors_10( |
@@ -2460,27 +2390,6 @@ static int transport_get_sense_data(struct se_cmd *cmd) | |||
2460 | return -1; | 2390 | return -1; |
2461 | } | 2391 | } |
2462 | 2392 | ||
2463 | static int | ||
2464 | transport_handle_reservation_conflict(struct se_cmd *cmd) | ||
2465 | { | ||
2466 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
2467 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; | ||
2468 | cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; | ||
2469 | /* | ||
2470 | * For UA Interlock Code 11b, a RESERVATION CONFLICT will | ||
2471 | * establish a UNIT ATTENTION with PREVIOUS RESERVATION | ||
2472 | * CONFLICT STATUS. | ||
2473 | * | ||
2474 | * See spc4r17, section 7.4.6 Control Mode Page, Table 349 | ||
2475 | */ | ||
2476 | if (cmd->se_sess && | ||
2477 | cmd->se_dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 2) | ||
2478 | core_scsi3_ua_allocate(cmd->se_sess->se_node_acl, | ||
2479 | cmd->orig_fe_lun, 0x2C, | ||
2480 | ASCQ_2CH_PREVIOUS_RESERVATION_CONFLICT_STATUS); | ||
2481 | return -EINVAL; | ||
2482 | } | ||
2483 | |||
2484 | static inline long long transport_dev_end_lba(struct se_device *dev) | 2393 | static inline long long transport_dev_end_lba(struct se_device *dev) |
2485 | { | 2394 | { |
2486 | return dev->transport->get_blocks(dev) + 1; | 2395 | return dev->transport->get_blocks(dev) + 1; |
@@ -2595,8 +2504,12 @@ static int transport_generic_cmd_sequencer( | |||
2595 | */ | 2504 | */ |
2596 | if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type) != 0) { | 2505 | if (su_dev->t10_pr.pr_ops.t10_reservation_check(cmd, &pr_reg_type) != 0) { |
2597 | if (su_dev->t10_pr.pr_ops.t10_seq_non_holder( | 2506 | if (su_dev->t10_pr.pr_ops.t10_seq_non_holder( |
2598 | cmd, cdb, pr_reg_type) != 0) | 2507 | cmd, cdb, pr_reg_type) != 0) { |
2599 | return transport_handle_reservation_conflict(cmd); | 2508 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; |
2509 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; | ||
2510 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
2511 | return -EBUSY; | ||
2512 | } | ||
2600 | /* | 2513 | /* |
2601 | * This means the CDB is allowed for the SCSI Initiator port | 2514 | * This means the CDB is allowed for the SCSI Initiator port |
2602 | * when said port is *NOT* holding the legacy SPC-2 or | 2515 | * when said port is *NOT* holding the legacy SPC-2 or |
@@ -2658,7 +2571,8 @@ static int transport_generic_cmd_sequencer( | |||
2658 | goto out_unsupported_cdb; | 2571 | goto out_unsupported_cdb; |
2659 | size = transport_get_size(sectors, cdb, cmd); | 2572 | size = transport_get_size(sectors, cdb, cmd); |
2660 | cmd->t_task_lba = transport_lba_32(cdb); | 2573 | cmd->t_task_lba = transport_lba_32(cdb); |
2661 | cmd->t_tasks_fua = (cdb[1] & 0x8); | 2574 | if (cdb[1] & 0x8) |
2575 | cmd->se_cmd_flags |= SCF_FUA; | ||
2662 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; | 2576 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; |
2663 | break; | 2577 | break; |
2664 | case WRITE_12: | 2578 | case WRITE_12: |
@@ -2667,7 +2581,8 @@ static int transport_generic_cmd_sequencer( | |||
2667 | goto out_unsupported_cdb; | 2581 | goto out_unsupported_cdb; |
2668 | size = transport_get_size(sectors, cdb, cmd); | 2582 | size = transport_get_size(sectors, cdb, cmd); |
2669 | cmd->t_task_lba = transport_lba_32(cdb); | 2583 | cmd->t_task_lba = transport_lba_32(cdb); |
2670 | cmd->t_tasks_fua = (cdb[1] & 0x8); | 2584 | if (cdb[1] & 0x8) |
2585 | cmd->se_cmd_flags |= SCF_FUA; | ||
2671 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; | 2586 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; |
2672 | break; | 2587 | break; |
2673 | case WRITE_16: | 2588 | case WRITE_16: |
@@ -2676,12 +2591,13 @@ static int transport_generic_cmd_sequencer( | |||
2676 | goto out_unsupported_cdb; | 2591 | goto out_unsupported_cdb; |
2677 | size = transport_get_size(sectors, cdb, cmd); | 2592 | size = transport_get_size(sectors, cdb, cmd); |
2678 | cmd->t_task_lba = transport_lba_64(cdb); | 2593 | cmd->t_task_lba = transport_lba_64(cdb); |
2679 | cmd->t_tasks_fua = (cdb[1] & 0x8); | 2594 | if (cdb[1] & 0x8) |
2595 | cmd->se_cmd_flags |= SCF_FUA; | ||
2680 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; | 2596 | cmd->se_cmd_flags |= SCF_SCSI_DATA_SG_IO_CDB; |
2681 | break; | 2597 | break; |
2682 | case XDWRITEREAD_10: | 2598 | case XDWRITEREAD_10: |
2683 | if ((cmd->data_direction != DMA_TO_DEVICE) || | 2599 | if ((cmd->data_direction != DMA_TO_DEVICE) || |
2684 | !(cmd->t_tasks_bidi)) | 2600 | !(cmd->se_cmd_flags & SCF_BIDI)) |
2685 | goto out_invalid_cdb_field; | 2601 | goto out_invalid_cdb_field; |
2686 | sectors = transport_get_sectors_10(cdb, cmd, §or_ret); | 2602 | sectors = transport_get_sectors_10(cdb, cmd, §or_ret); |
2687 | if (sector_ret) | 2603 | if (sector_ret) |
@@ -2700,7 +2616,8 @@ static int transport_generic_cmd_sequencer( | |||
2700 | * Setup BIDI XOR callback to be run after I/O completion. | 2616 | * Setup BIDI XOR callback to be run after I/O completion. |
2701 | */ | 2617 | */ |
2702 | cmd->transport_complete_callback = &transport_xor_callback; | 2618 | cmd->transport_complete_callback = &transport_xor_callback; |
2703 | cmd->t_tasks_fua = (cdb[1] & 0x8); | 2619 | if (cdb[1] & 0x8) |
2620 | cmd->se_cmd_flags |= SCF_FUA; | ||
2704 | break; | 2621 | break; |
2705 | case VARIABLE_LENGTH_CMD: | 2622 | case VARIABLE_LENGTH_CMD: |
2706 | service_action = get_unaligned_be16(&cdb[8]); | 2623 | service_action = get_unaligned_be16(&cdb[8]); |
@@ -2728,7 +2645,8 @@ static int transport_generic_cmd_sequencer( | |||
2728 | * completion. | 2645 | * completion. |
2729 | */ | 2646 | */ |
2730 | cmd->transport_complete_callback = &transport_xor_callback; | 2647 | cmd->transport_complete_callback = &transport_xor_callback; |
2731 | cmd->t_tasks_fua = (cdb[10] & 0x8); | 2648 | if (cdb[1] & 0x8) |
2649 | cmd->se_cmd_flags |= SCF_FUA; | ||
2732 | break; | 2650 | break; |
2733 | case WRITE_SAME_32: | 2651 | case WRITE_SAME_32: |
2734 | sectors = transport_get_sectors_32(cdb, cmd, §or_ret); | 2652 | sectors = transport_get_sectors_32(cdb, cmd, §or_ret); |
@@ -3171,18 +3089,13 @@ static void transport_complete_task_attr(struct se_cmd *cmd) | |||
3171 | " SIMPLE: %u\n", dev->dev_cur_ordered_id, | 3089 | " SIMPLE: %u\n", dev->dev_cur_ordered_id, |
3172 | cmd->se_ordered_id); | 3090 | cmd->se_ordered_id); |
3173 | } else if (cmd->sam_task_attr == MSG_HEAD_TAG) { | 3091 | } else if (cmd->sam_task_attr == MSG_HEAD_TAG) { |
3174 | atomic_dec(&dev->dev_hoq_count); | ||
3175 | smp_mb__after_atomic_dec(); | ||
3176 | dev->dev_cur_ordered_id++; | 3092 | dev->dev_cur_ordered_id++; |
3177 | pr_debug("Incremented dev_cur_ordered_id: %u for" | 3093 | pr_debug("Incremented dev_cur_ordered_id: %u for" |
3178 | " HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id, | 3094 | " HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id, |
3179 | cmd->se_ordered_id); | 3095 | cmd->se_ordered_id); |
3180 | } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { | 3096 | } else if (cmd->sam_task_attr == MSG_ORDERED_TAG) { |
3181 | spin_lock(&dev->ordered_cmd_lock); | ||
3182 | list_del(&cmd->se_ordered_node); | ||
3183 | atomic_dec(&dev->dev_ordered_sync); | 3097 | atomic_dec(&dev->dev_ordered_sync); |
3184 | smp_mb__after_atomic_dec(); | 3098 | smp_mb__after_atomic_dec(); |
3185 | spin_unlock(&dev->ordered_cmd_lock); | ||
3186 | 3099 | ||
3187 | dev->dev_cur_ordered_id++; | 3100 | dev->dev_cur_ordered_id++; |
3188 | pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED:" | 3101 | pr_debug("Incremented dev_cur_ordered_id: %u for ORDERED:" |
@@ -3495,6 +3408,18 @@ int transport_generic_map_mem_to_cmd( | |||
3495 | 3408 | ||
3496 | if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) || | 3409 | if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) || |
3497 | (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) { | 3410 | (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) { |
3411 | /* | ||
3412 | * Reject SCSI data overflow with map_mem_to_cmd() as incoming | ||
3413 | * scatterlists already have been set to follow what the fabric | ||
3414 | * passes for the original expected data transfer length. | ||
3415 | */ | ||
3416 | if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { | ||
3417 | pr_warn("Rejecting SCSI DATA overflow for fabric using" | ||
3418 | " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); | ||
3419 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | ||
3420 | cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
3421 | return -EINVAL; | ||
3422 | } | ||
3498 | 3423 | ||
3499 | cmd->t_data_sg = sgl; | 3424 | cmd->t_data_sg = sgl; |
3500 | cmd->t_data_nents = sgl_count; | 3425 | cmd->t_data_nents = sgl_count; |
@@ -3813,7 +3738,7 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
3813 | cmd->data_length) { | 3738 | cmd->data_length) { |
3814 | ret = transport_generic_get_mem(cmd); | 3739 | ret = transport_generic_get_mem(cmd); |
3815 | if (ret < 0) | 3740 | if (ret < 0) |
3816 | return ret; | 3741 | goto out_fail; |
3817 | } | 3742 | } |
3818 | 3743 | ||
3819 | /* | 3744 | /* |
@@ -3842,8 +3767,15 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
3842 | task_cdbs = transport_allocate_control_task(cmd); | 3767 | task_cdbs = transport_allocate_control_task(cmd); |
3843 | } | 3768 | } |
3844 | 3769 | ||
3845 | if (task_cdbs <= 0) | 3770 | if (task_cdbs < 0) |
3846 | goto out_fail; | 3771 | goto out_fail; |
3772 | else if (!task_cdbs && (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)) { | ||
3773 | cmd->t_state = TRANSPORT_COMPLETE; | ||
3774 | atomic_set(&cmd->t_transport_active, 1); | ||
3775 | INIT_WORK(&cmd->work, target_complete_ok_work); | ||
3776 | queue_work(target_completion_wq, &cmd->work); | ||
3777 | return 0; | ||
3778 | } | ||
3847 | 3779 | ||
3848 | if (set_counts) { | 3780 | if (set_counts) { |
3849 | atomic_inc(&cmd->t_fe_count); | 3781 | atomic_inc(&cmd->t_fe_count); |
@@ -3929,7 +3861,7 @@ static int transport_generic_write_pending(struct se_cmd *cmd) | |||
3929 | else if (ret < 0) | 3861 | else if (ret < 0) |
3930 | return ret; | 3862 | return ret; |
3931 | 3863 | ||
3932 | return PYX_TRANSPORT_WRITE_PENDING; | 3864 | return 1; |
3933 | 3865 | ||
3934 | queue_full: | 3866 | queue_full: |
3935 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); | 3867 | pr_debug("Handling write_pending QUEUE__FULL: se_cmd: %p\n", cmd); |
@@ -4602,9 +4534,6 @@ void transport_send_task_abort(struct se_cmd *cmd) | |||
4602 | if (cmd->se_tfo->write_pending_status(cmd) != 0) { | 4534 | if (cmd->se_tfo->write_pending_status(cmd) != 0) { |
4603 | atomic_inc(&cmd->t_transport_aborted); | 4535 | atomic_inc(&cmd->t_transport_aborted); |
4604 | smp_mb__after_atomic_inc(); | 4536 | smp_mb__after_atomic_inc(); |
4605 | cmd->scsi_status = SAM_STAT_TASK_ABORTED; | ||
4606 | transport_new_cmd_failure(cmd); | ||
4607 | return; | ||
4608 | } | 4537 | } |
4609 | } | 4538 | } |
4610 | cmd->scsi_status = SAM_STAT_TASK_ABORTED; | 4539 | cmd->scsi_status = SAM_STAT_TASK_ABORTED; |
@@ -4670,8 +4599,6 @@ static int transport_processing_thread(void *param) | |||
4670 | struct se_cmd *cmd; | 4599 | struct se_cmd *cmd; |
4671 | struct se_device *dev = (struct se_device *) param; | 4600 | struct se_device *dev = (struct se_device *) param; |
4672 | 4601 | ||
4673 | set_user_nice(current, -20); | ||
4674 | |||
4675 | while (!kthread_should_stop()) { | 4602 | while (!kthread_should_stop()) { |
4676 | ret = wait_event_interruptible(dev->dev_queue_obj.thread_wq, | 4603 | ret = wait_event_interruptible(dev->dev_queue_obj.thread_wq, |
4677 | atomic_read(&dev->dev_queue_obj.queue_cnt) || | 4604 | atomic_read(&dev->dev_queue_obj.queue_cnt) || |
@@ -4698,18 +4625,13 @@ get_cmd: | |||
4698 | } | 4625 | } |
4699 | ret = cmd->se_tfo->new_cmd_map(cmd); | 4626 | ret = cmd->se_tfo->new_cmd_map(cmd); |
4700 | if (ret < 0) { | 4627 | if (ret < 0) { |
4701 | cmd->transport_error_status = ret; | 4628 | transport_generic_request_failure(cmd); |
4702 | transport_generic_request_failure(cmd, | ||
4703 | 0, (cmd->data_direction != | ||
4704 | DMA_TO_DEVICE)); | ||
4705 | break; | 4629 | break; |
4706 | } | 4630 | } |
4707 | ret = transport_generic_new_cmd(cmd); | 4631 | ret = transport_generic_new_cmd(cmd); |
4708 | if (ret < 0) { | 4632 | if (ret < 0) { |
4709 | cmd->transport_error_status = ret; | 4633 | transport_generic_request_failure(cmd); |
4710 | transport_generic_request_failure(cmd, | 4634 | break; |
4711 | 0, (cmd->data_direction != | ||
4712 | DMA_TO_DEVICE)); | ||
4713 | } | 4635 | } |
4714 | break; | 4636 | break; |
4715 | case TRANSPORT_PROCESS_WRITE: | 4637 | case TRANSPORT_PROCESS_WRITE: |
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 4fac37c4c615..71fc9cea5dc9 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c | |||
@@ -200,7 +200,7 @@ int ft_write_pending(struct se_cmd *se_cmd) | |||
200 | lport = ep->lp; | 200 | lport = ep->lp; |
201 | fp = fc_frame_alloc(lport, sizeof(*txrdy)); | 201 | fp = fc_frame_alloc(lport, sizeof(*txrdy)); |
202 | if (!fp) | 202 | if (!fp) |
203 | return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; | 203 | return -ENOMEM; /* Signal QUEUE_FULL */ |
204 | 204 | ||
205 | txrdy = fc_frame_payload_get(fp, sizeof(*txrdy)); | 205 | txrdy = fc_frame_payload_get(fp, sizeof(*txrdy)); |
206 | memset(txrdy, 0, sizeof(*txrdy)); | 206 | memset(txrdy, 0, sizeof(*txrdy)); |
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index 5f770412ca40..9402b7387cac 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c | |||
@@ -436,8 +436,7 @@ static void ft_del_lport(struct se_wwn *wwn) | |||
436 | struct ft_lport_acl *lacl = container_of(wwn, | 436 | struct ft_lport_acl *lacl = container_of(wwn, |
437 | struct ft_lport_acl, fc_lport_wwn); | 437 | struct ft_lport_acl, fc_lport_wwn); |
438 | 438 | ||
439 | pr_debug("del lport %s\n", | 439 | pr_debug("del lport %s\n", lacl->name); |
440 | config_item_name(&wwn->wwn_group.cg_item)); | ||
441 | mutex_lock(&ft_lport_lock); | 440 | mutex_lock(&ft_lport_lock); |
442 | list_del(&lacl->list); | 441 | list_del(&lacl->list); |
443 | mutex_unlock(&ft_lport_lock); | 442 | mutex_unlock(&ft_lport_lock); |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e8c564a53346..a8078d0638fa 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1458,6 +1458,16 @@ static const struct usb_device_id acm_ids[] = { | |||
1458 | }, | 1458 | }, |
1459 | { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ | 1459 | { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ |
1460 | }, | 1460 | }, |
1461 | /* Motorola H24 HSPA module: */ | ||
1462 | { USB_DEVICE(0x22b8, 0x2d91) }, /* modem */ | ||
1463 | { USB_DEVICE(0x22b8, 0x2d92) }, /* modem + diagnostics */ | ||
1464 | { USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port */ | ||
1465 | { USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics */ | ||
1466 | { USB_DEVICE(0x22b8, 0x2d96) }, /* modem + NMEA */ | ||
1467 | { USB_DEVICE(0x22b8, 0x2d97) }, /* modem + diagnostics + NMEA */ | ||
1468 | { USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port + NMEA */ | ||
1469 | { USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */ | ||
1470 | |||
1461 | { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ | 1471 | { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ |
1462 | .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on | 1472 | .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on |
1463 | data interface instead of | 1473 | data interface instead of |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 717ebc9ff941..600d82348511 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -264,7 +264,7 @@ static int __devinit dwc3_core_init(struct dwc3 *dwc) | |||
264 | ret = -ENODEV; | 264 | ret = -ENODEV; |
265 | goto err0; | 265 | goto err0; |
266 | } | 266 | } |
267 | dwc->revision = reg & DWC3_GSNPSREV_MASK; | 267 | dwc->revision = reg; |
268 | 268 | ||
269 | dwc3_core_soft_reset(dwc); | 269 | dwc3_core_soft_reset(dwc); |
270 | 270 | ||
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 596a0b464e61..4dff83d2f265 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -130,9 +130,6 @@ ep_matches ( | |||
130 | num_req_streams = ep_comp->bmAttributes & 0x1f; | 130 | num_req_streams = ep_comp->bmAttributes & 0x1f; |
131 | if (num_req_streams > ep->max_streams) | 131 | if (num_req_streams > ep->max_streams) |
132 | return 0; | 132 | return 0; |
133 | /* Update the ep_comp descriptor if needed */ | ||
134 | if (num_req_streams != ep->max_streams) | ||
135 | ep_comp->bmAttributes = ep->max_streams; | ||
136 | } | 133 | } |
137 | 134 | ||
138 | } | 135 | } |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index c39d58860fa0..1a6f415c0d02 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -2975,6 +2975,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) | |||
2975 | fsg_common_put(common); | 2975 | fsg_common_put(common); |
2976 | usb_free_descriptors(fsg->function.descriptors); | 2976 | usb_free_descriptors(fsg->function.descriptors); |
2977 | usb_free_descriptors(fsg->function.hs_descriptors); | 2977 | usb_free_descriptors(fsg->function.hs_descriptors); |
2978 | usb_free_descriptors(fsg->function.ss_descriptors); | ||
2978 | kfree(fsg); | 2979 | kfree(fsg); |
2979 | } | 2980 | } |
2980 | 2981 | ||
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index a7dc1e1d45f2..2ac4ac2e4ef9 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | #include "isp1760-hcd.h" | 19 | #include "isp1760-hcd.h" |
20 | 20 | ||
21 | #ifdef CONFIG_OF | 21 | #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_platform.h> | 24 | #include <linux/of_platform.h> |
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | #ifdef CONFIG_OF | 34 | #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) |
35 | struct isp1760 { | 35 | struct isp1760 { |
36 | struct usb_hcd *hcd; | 36 | struct usb_hcd *hcd; |
37 | int rst_gpio; | 37 | int rst_gpio; |
@@ -437,7 +437,7 @@ static int __init isp1760_init(void) | |||
437 | ret = platform_driver_register(&isp1760_plat_driver); | 437 | ret = platform_driver_register(&isp1760_plat_driver); |
438 | if (!ret) | 438 | if (!ret) |
439 | any_ret = 0; | 439 | any_ret = 0; |
440 | #ifdef CONFIG_OF | 440 | #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) |
441 | ret = platform_driver_register(&isp1760_of_driver); | 441 | ret = platform_driver_register(&isp1760_of_driver); |
442 | if (!ret) | 442 | if (!ret) |
443 | any_ret = 0; | 443 | any_ret = 0; |
@@ -457,7 +457,7 @@ module_init(isp1760_init); | |||
457 | static void __exit isp1760_exit(void) | 457 | static void __exit isp1760_exit(void) |
458 | { | 458 | { |
459 | platform_driver_unregister(&isp1760_plat_driver); | 459 | platform_driver_unregister(&isp1760_plat_driver); |
460 | #ifdef CONFIG_OF | 460 | #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) |
461 | platform_driver_unregister(&isp1760_of_driver); | 461 | platform_driver_unregister(&isp1760_of_driver); |
462 | #endif | 462 | #endif |
463 | #ifdef CONFIG_PCI | 463 | #ifdef CONFIG_PCI |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 60ddba8066ea..79cb0af779fa 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -774,6 +774,10 @@ static void musb_ep_program(struct musb *musb, u8 epnum, | |||
774 | if (musb->double_buffer_not_ok) | 774 | if (musb->double_buffer_not_ok) |
775 | musb_writew(epio, MUSB_TXMAXP, | 775 | musb_writew(epio, MUSB_TXMAXP, |
776 | hw_ep->max_packet_sz_tx); | 776 | hw_ep->max_packet_sz_tx); |
777 | else if (can_bulk_split(musb, qh->type)) | ||
778 | musb_writew(epio, MUSB_TXMAXP, packet_sz | ||
779 | | ((hw_ep->max_packet_sz_tx / | ||
780 | packet_sz) - 1) << 11); | ||
777 | else | 781 | else |
778 | musb_writew(epio, MUSB_TXMAXP, | 782 | musb_writew(epio, MUSB_TXMAXP, |
779 | qh->maxpacket | | 783 | qh->maxpacket | |
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 053f86d70009..ad96a3896729 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c | |||
@@ -349,7 +349,7 @@ void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod) | |||
349 | if (mod->irq_attch) | 349 | if (mod->irq_attch) |
350 | intenb1 |= ATTCHE; | 350 | intenb1 |= ATTCHE; |
351 | 351 | ||
352 | if (mod->irq_attch) | 352 | if (mod->irq_dtch) |
353 | intenb1 |= DTCHE; | 353 | intenb1 |= DTCHE; |
354 | 354 | ||
355 | if (mod->irq_sign) | 355 | if (mod->irq_sign) |
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index bade761a1e52..7955de589951 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
@@ -1267,6 +1267,7 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1267 | dev_err(dev, "Failed to create hcd\n"); | 1267 | dev_err(dev, "Failed to create hcd\n"); |
1268 | return -ENOMEM; | 1268 | return -ENOMEM; |
1269 | } | 1269 | } |
1270 | hcd->has_tt = 1; /* for low/full speed */ | ||
1270 | 1271 | ||
1271 | pipe_info = kzalloc(sizeof(*pipe_info) * pipe_size, GFP_KERNEL); | 1272 | pipe_info = kzalloc(sizeof(*pipe_info) * pipe_size, GFP_KERNEL); |
1272 | if (!pipe_info) { | 1273 | if (!pipe_info) { |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e3426602dc82..6dd64534fad0 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -663,7 +663,12 @@ static const struct usb_device_id option_ids[] = { | |||
663 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, | 663 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, |
664 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) }, | 664 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) }, |
665 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) }, | 665 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) }, |
666 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x08) }, | 666 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x10) }, |
667 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x12) }, | ||
668 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x13) }, | ||
669 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) }, /* E398 3G Modem */ | ||
670 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) }, /* E398 3G PC UI Interface */ | ||
671 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) }, /* E398 3G Application Interface */ | ||
667 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, | 672 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, |
668 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, | 673 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, |
669 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, | 674 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, |
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 8e964b91c447..284798aaf8b1 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c | |||
@@ -166,7 +166,7 @@ retry: | |||
166 | /* | 166 | /* |
167 | * Get IO TLB memory from any location. | 167 | * Get IO TLB memory from any location. |
168 | */ | 168 | */ |
169 | xen_io_tlb_start = alloc_bootmem(bytes); | 169 | xen_io_tlb_start = alloc_bootmem_pages(PAGE_ALIGN(bytes)); |
170 | if (!xen_io_tlb_start) { | 170 | if (!xen_io_tlb_start) { |
171 | m = "Cannot allocate Xen-SWIOTLB buffer!\n"; | 171 | m = "Cannot allocate Xen-SWIOTLB buffer!\n"; |
172 | goto error; | 172 | goto error; |
@@ -179,7 +179,7 @@ retry: | |||
179 | bytes, | 179 | bytes, |
180 | xen_io_tlb_nslabs); | 180 | xen_io_tlb_nslabs); |
181 | if (rc) { | 181 | if (rc) { |
182 | free_bootmem(__pa(xen_io_tlb_start), bytes); | 182 | free_bootmem(__pa(xen_io_tlb_start), PAGE_ALIGN(bytes)); |
183 | m = "Failed to get contiguous memory for DMA from Xen!\n"\ | 183 | m = "Failed to get contiguous memory for DMA from Xen!\n"\ |
184 | "You either: don't have the permissions, do not have"\ | 184 | "You either: don't have the permissions, do not have"\ |
185 | " enough free memory under 4GB, or the hypervisor memory"\ | 185 | " enough free memory under 4GB, or the hypervisor memory"\ |
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index b3b8f2f3ad10..ede860f921df 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c | |||
@@ -621,15 +621,6 @@ static struct xenbus_watch *find_watch(const char *token) | |||
621 | return NULL; | 621 | return NULL; |
622 | } | 622 | } |
623 | 623 | ||
624 | static void xs_reset_watches(void) | ||
625 | { | ||
626 | int err; | ||
627 | |||
628 | err = xs_error(xs_single(XBT_NIL, XS_RESET_WATCHES, "", NULL)); | ||
629 | if (err && err != -EEXIST) | ||
630 | printk(KERN_WARNING "xs_reset_watches failed: %d\n", err); | ||
631 | } | ||
632 | |||
633 | /* Register callback to watch this node. */ | 624 | /* Register callback to watch this node. */ |
634 | int register_xenbus_watch(struct xenbus_watch *watch) | 625 | int register_xenbus_watch(struct xenbus_watch *watch) |
635 | { | 626 | { |
@@ -906,9 +897,5 @@ int xs_init(void) | |||
906 | if (IS_ERR(task)) | 897 | if (IS_ERR(task)) |
907 | return PTR_ERR(task); | 898 | return PTR_ERR(task); |
908 | 899 | ||
909 | /* shutdown watches for kexec boot */ | ||
910 | if (xen_hvm_domain()) | ||
911 | xs_reset_watches(); | ||
912 | |||
913 | return 0; | 900 | return 0; |
914 | } | 901 | } |