diff options
Diffstat (limited to 'drivers')
191 files changed, 2456 insertions, 1658 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index d8b3d89db04..919daa7cd5b 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 8004ac30a7a..587cce57ada 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 68b205a9338..1e888c9e85b 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 65cc424359b..148ab944378 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 ae3e167e17a..89ddab127e3 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/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 11b41fd40c2..5ccf142ef0b 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig | |||
| @@ -188,7 +188,7 @@ config BT_MRVL | |||
| 188 | The core driver to support Marvell Bluetooth devices. | 188 | The core driver to support Marvell Bluetooth devices. |
| 189 | 189 | ||
| 190 | This driver is required if you want to support | 190 | This driver is required if you want to support |
| 191 | Marvell Bluetooth devices, such as 8688/8787. | 191 | Marvell Bluetooth devices, such as 8688/8787/8797. |
| 192 | 192 | ||
| 193 | Say Y here to compile Marvell Bluetooth driver | 193 | Say Y here to compile Marvell Bluetooth driver |
| 194 | into the kernel or say M to compile it as module. | 194 | into the kernel or say M to compile it as module. |
| @@ -201,8 +201,8 @@ config BT_MRVL_SDIO | |||
| 201 | The driver for Marvell Bluetooth chipsets with SDIO interface. | 201 | The driver for Marvell Bluetooth chipsets with SDIO interface. |
| 202 | 202 | ||
| 203 | This driver is required if you want to use Marvell Bluetooth | 203 | This driver is required if you want to use Marvell Bluetooth |
| 204 | devices with SDIO interface. Currently SD8688/SD8787 chipsets are | 204 | devices with SDIO interface. Currently SD8688/SD8787/SD8797 |
| 205 | supported. | 205 | chipsets are supported. |
| 206 | 206 | ||
| 207 | Say Y here to compile support for Marvell BT-over-SDIO driver | 207 | Say Y here to compile support for Marvell BT-over-SDIO driver |
| 208 | into the kernel or say M to compile it as module. | 208 | into the kernel or say M to compile it as module. |
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index 9ef48167e2c..27b74b0d547 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
| @@ -65,7 +65,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = { | |||
| 65 | .io_port_1 = 0x01, | 65 | .io_port_1 = 0x01, |
| 66 | .io_port_2 = 0x02, | 66 | .io_port_2 = 0x02, |
| 67 | }; | 67 | }; |
| 68 | static const struct btmrvl_sdio_card_reg btmrvl_reg_8787 = { | 68 | static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = { |
| 69 | .cfg = 0x00, | 69 | .cfg = 0x00, |
| 70 | .host_int_mask = 0x02, | 70 | .host_int_mask = 0x02, |
| 71 | .host_intstatus = 0x03, | 71 | .host_intstatus = 0x03, |
| @@ -92,7 +92,14 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { | |||
| 92 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { | 92 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { |
| 93 | .helper = NULL, | 93 | .helper = NULL, |
| 94 | .firmware = "mrvl/sd8787_uapsta.bin", | 94 | .firmware = "mrvl/sd8787_uapsta.bin", |
| 95 | .reg = &btmrvl_reg_8787, | 95 | .reg = &btmrvl_reg_87xx, |
| 96 | .sd_blksz_fw_dl = 256, | ||
| 97 | }; | ||
| 98 | |||
| 99 | static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = { | ||
| 100 | .helper = NULL, | ||
| 101 | .firmware = "mrvl/sd8797_uapsta.bin", | ||
| 102 | .reg = &btmrvl_reg_87xx, | ||
| 96 | .sd_blksz_fw_dl = 256, | 103 | .sd_blksz_fw_dl = 256, |
| 97 | }; | 104 | }; |
| 98 | 105 | ||
| @@ -103,6 +110,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = { | |||
| 103 | /* Marvell SD8787 Bluetooth device */ | 110 | /* Marvell SD8787 Bluetooth device */ |
| 104 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), | 111 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), |
| 105 | .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, | 112 | .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, |
| 113 | /* Marvell SD8797 Bluetooth device */ | ||
| 114 | { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A), | ||
| 115 | .driver_data = (unsigned long) &btmrvl_sdio_sd8797 }, | ||
| 106 | 116 | ||
| 107 | { } /* Terminating entry */ | 117 | { } /* Terminating entry */ |
| 108 | }; | 118 | }; |
| @@ -1076,3 +1086,4 @@ MODULE_LICENSE("GPL v2"); | |||
| 1076 | MODULE_FIRMWARE("sd8688_helper.bin"); | 1086 | MODULE_FIRMWARE("sd8688_helper.bin"); |
| 1077 | MODULE_FIRMWARE("sd8688.bin"); | 1087 | MODULE_FIRMWARE("sd8688.bin"); |
| 1078 | MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); | 1088 | MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); |
| 1089 | MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); | ||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index fe4ebc375b3..eabc437ce50 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
| @@ -777,9 +777,8 @@ skip_waking: | |||
| 777 | usb_mark_last_busy(data->udev); | 777 | usb_mark_last_busy(data->udev); |
| 778 | } | 778 | } |
| 779 | 779 | ||
| 780 | usb_free_urb(urb); | ||
| 781 | |||
| 782 | done: | 780 | done: |
| 781 | usb_free_urb(urb); | ||
| 783 | return err; | 782 | return err; |
| 784 | } | 783 | } |
| 785 | 784 | ||
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index c811cb10790..2cce44a1d7d 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 bfe723266fd..4da4eb9ae92 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/firmware/sigma.c b/drivers/firmware/sigma.c index f10fc521951..1eedb6f7fda 100644 --- a/drivers/firmware/sigma.c +++ b/drivers/firmware/sigma.c | |||
| @@ -14,13 +14,34 @@ | |||
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/sigma.h> | 15 | #include <linux/sigma.h> |
| 16 | 16 | ||
| 17 | /* Return: 0==OK, <0==error, =1 ==no more actions */ | 17 | static size_t sigma_action_size(struct sigma_action *sa) |
| 18 | { | ||
| 19 | size_t payload = 0; | ||
| 20 | |||
| 21 | switch (sa->instr) { | ||
| 22 | case SIGMA_ACTION_WRITEXBYTES: | ||
| 23 | case SIGMA_ACTION_WRITESINGLE: | ||
| 24 | case SIGMA_ACTION_WRITESAFELOAD: | ||
| 25 | payload = sigma_action_len(sa); | ||
| 26 | break; | ||
| 27 | default: | ||
| 28 | break; | ||
| 29 | } | ||
| 30 | |||
| 31 | payload = ALIGN(payload, 2); | ||
| 32 | |||
| 33 | return payload + sizeof(struct sigma_action); | ||
| 34 | } | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Returns a negative error value in case of an error, 0 if processing of | ||
| 38 | * the firmware should be stopped after this action, 1 otherwise. | ||
| 39 | */ | ||
| 18 | static int | 40 | static int |
| 19 | process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw) | 41 | process_sigma_action(struct i2c_client *client, struct sigma_action *sa) |
| 20 | { | 42 | { |
| 21 | struct sigma_action *sa = (void *)(ssfw->fw->data + ssfw->pos); | ||
| 22 | size_t len = sigma_action_len(sa); | 43 | size_t len = sigma_action_len(sa); |
| 23 | int ret = 0; | 44 | int ret; |
| 24 | 45 | ||
| 25 | pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, | 46 | pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, |
| 26 | sa->instr, sa->addr, len); | 47 | sa->instr, sa->addr, len); |
| @@ -29,44 +50,50 @@ process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw) | |||
| 29 | case SIGMA_ACTION_WRITEXBYTES: | 50 | case SIGMA_ACTION_WRITEXBYTES: |
| 30 | case SIGMA_ACTION_WRITESINGLE: | 51 | case SIGMA_ACTION_WRITESINGLE: |
| 31 | case SIGMA_ACTION_WRITESAFELOAD: | 52 | case SIGMA_ACTION_WRITESAFELOAD: |
| 32 | if (ssfw->fw->size < ssfw->pos + len) | ||
| 33 | return -EINVAL; | ||
| 34 | ret = i2c_master_send(client, (void *)&sa->addr, len); | 53 | ret = i2c_master_send(client, (void *)&sa->addr, len); |
| 35 | if (ret < 0) | 54 | if (ret < 0) |
| 36 | return -EINVAL; | 55 | return -EINVAL; |
| 37 | break; | 56 | break; |
| 38 | |||
| 39 | case SIGMA_ACTION_DELAY: | 57 | case SIGMA_ACTION_DELAY: |
| 40 | ret = 0; | ||
| 41 | udelay(len); | 58 | udelay(len); |
| 42 | len = 0; | 59 | len = 0; |
| 43 | break; | 60 | break; |
| 44 | |||
| 45 | case SIGMA_ACTION_END: | 61 | case SIGMA_ACTION_END: |
| 46 | return 1; | 62 | return 0; |
| 47 | |||
| 48 | default: | 63 | default: |
| 49 | return -EINVAL; | 64 | return -EINVAL; |
| 50 | } | 65 | } |
| 51 | 66 | ||
| 52 | /* when arrive here ret=0 or sent data */ | 67 | return 1; |
| 53 | ssfw->pos += sigma_action_size(sa, len); | ||
| 54 | return ssfw->pos == ssfw->fw->size; | ||
| 55 | } | 68 | } |
| 56 | 69 | ||
| 57 | static int | 70 | static int |
| 58 | process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw) | 71 | process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw) |
| 59 | { | 72 | { |
| 60 | pr_debug("%s: processing %p\n", __func__, ssfw); | 73 | struct sigma_action *sa; |
| 74 | size_t size; | ||
| 75 | int ret; | ||
| 76 | |||
| 77 | while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) { | ||
| 78 | sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos); | ||
| 79 | |||
| 80 | size = sigma_action_size(sa); | ||
| 81 | ssfw->pos += size; | ||
| 82 | if (ssfw->pos > ssfw->fw->size || size == 0) | ||
| 83 | break; | ||
| 84 | |||
| 85 | ret = process_sigma_action(client, sa); | ||
| 61 | 86 | ||
| 62 | while (1) { | ||
| 63 | int ret = process_sigma_action(client, ssfw); | ||
| 64 | pr_debug("%s: action returned %i\n", __func__, ret); | 87 | pr_debug("%s: action returned %i\n", __func__, ret); |
| 65 | if (ret == 1) | 88 | |
| 66 | return 0; | 89 | if (ret <= 0) |
| 67 | else if (ret) | ||
| 68 | return ret; | 90 | return ret; |
| 69 | } | 91 | } |
| 92 | |||
| 93 | if (ssfw->pos != ssfw->fw->size) | ||
| 94 | return -EINVAL; | ||
| 95 | |||
| 96 | return 0; | ||
| 70 | } | 97 | } |
| 71 | 98 | ||
| 72 | int process_sigma_firmware(struct i2c_client *client, const char *name) | 99 | int process_sigma_firmware(struct i2c_client *client, const char *name) |
| @@ -89,16 +116,24 @@ int process_sigma_firmware(struct i2c_client *client, const char *name) | |||
| 89 | 116 | ||
| 90 | /* then verify the header */ | 117 | /* then verify the header */ |
| 91 | ret = -EINVAL; | 118 | ret = -EINVAL; |
| 92 | if (fw->size < sizeof(*ssfw_head)) | 119 | |
| 120 | /* | ||
| 121 | * Reject too small or unreasonable large files. The upper limit has been | ||
| 122 | * chosen a bit arbitrarily, but it should be enough for all practical | ||
| 123 | * purposes and having the limit makes it easier to avoid integer | ||
| 124 | * overflows later in the loading process. | ||
| 125 | */ | ||
| 126 | if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) | ||
| 93 | goto done; | 127 | goto done; |
| 94 | 128 | ||
| 95 | ssfw_head = (void *)fw->data; | 129 | ssfw_head = (void *)fw->data; |
| 96 | if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) | 130 | if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) |
| 97 | goto done; | 131 | goto done; |
| 98 | 132 | ||
| 99 | crc = crc32(0, fw->data, fw->size); | 133 | crc = crc32(0, fw->data + sizeof(*ssfw_head), |
| 134 | fw->size - sizeof(*ssfw_head)); | ||
| 100 | pr_debug("%s: crc=%x\n", __func__, crc); | 135 | pr_debug("%s: crc=%x\n", __func__, crc); |
| 101 | if (crc != ssfw_head->crc) | 136 | if (crc != le32_to_cpu(ssfw_head->crc)) |
| 102 | goto done; | 137 | goto done; |
| 103 | 138 | ||
| 104 | ssfw.pos = sizeof(*ssfw_head); | 139 | ssfw.pos = sizeof(*ssfw_head); |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index dbcb0bcfd8d..4e018d6a763 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
| @@ -18,7 +18,7 @@ obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o | |||
| 18 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | 18 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o |
| 19 | obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o | 19 | obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o |
| 20 | obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o | 20 | obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o |
| 21 | obj-$(CONFIG_MACH_KS8695) += gpio-ks8695.o | 21 | obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o |
| 22 | obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o | 22 | obj-$(CONFIG_GPIO_LANGWELL) += gpio-langwell.o |
| 23 | obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o | 23 | obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o |
| 24 | obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o | 24 | obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o |
diff --git a/drivers/gpio/gpio-da9052.c b/drivers/gpio/gpio-da9052.c index 038f5eb8b13..f8ce29ef9f8 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 ea8e7386925..461958fc226 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 ec3fcf0a7e1..5cd04b65c55 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 093c90bd3c1..4102f63230f 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/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 3969f7553fe..d2619d72cec 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
| @@ -456,6 +456,30 @@ done: | |||
| 456 | EXPORT_SYMBOL(drm_crtc_helper_set_mode); | 456 | EXPORT_SYMBOL(drm_crtc_helper_set_mode); |
| 457 | 457 | ||
| 458 | 458 | ||
| 459 | static int | ||
| 460 | drm_crtc_helper_disable(struct drm_crtc *crtc) | ||
| 461 | { | ||
| 462 | struct drm_device *dev = crtc->dev; | ||
| 463 | struct drm_connector *connector; | ||
| 464 | struct drm_encoder *encoder; | ||
| 465 | |||
| 466 | /* Decouple all encoders and their attached connectors from this crtc */ | ||
| 467 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
| 468 | if (encoder->crtc != crtc) | ||
| 469 | continue; | ||
| 470 | |||
| 471 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 472 | if (connector->encoder != encoder) | ||
| 473 | continue; | ||
| 474 | |||
| 475 | connector->encoder = NULL; | ||
| 476 | } | ||
| 477 | } | ||
| 478 | |||
| 479 | drm_helper_disable_unused_functions(dev); | ||
| 480 | return 0; | ||
| 481 | } | ||
| 482 | |||
| 459 | /** | 483 | /** |
| 460 | * drm_crtc_helper_set_config - set a new config from userspace | 484 | * drm_crtc_helper_set_config - set a new config from userspace |
| 461 | * @crtc: CRTC to setup | 485 | * @crtc: CRTC to setup |
| @@ -510,8 +534,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) | |||
| 510 | (int)set->num_connectors, set->x, set->y); | 534 | (int)set->num_connectors, set->x, set->y); |
| 511 | } else { | 535 | } else { |
| 512 | DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); | 536 | DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); |
| 513 | set->mode = NULL; | 537 | return drm_crtc_helper_disable(set->crtc); |
| 514 | set->num_connectors = 0; | ||
| 515 | } | 538 | } |
| 516 | 539 | ||
| 517 | dev = set->crtc->dev; | 540 | dev = set->crtc->dev; |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d09a6e02dc9..004b048c519 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 a9533c54c93..a9ae374861e 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 15bfa9145d2..a1103fc6597 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 4a9c1b97980..554bef7a3b9 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 3693e83a97f..c681dc149d2 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 b080cc82400..a26d5b0a369 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 e77a863a383..d809b038ca8 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 4d0358fad93..92b041b66e4 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 bd9a604b73d..a1b4343814e 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 42f165a520d..e44191132ac 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 21f60b7d69a..04d79fd1dc9 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 3003fb25aef..f7b9268df26 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/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index ddbabefb427..b12fd2c8081 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
| @@ -369,3 +369,48 @@ nouveau_finish_page_flip(struct nouveau_channel *chan, | |||
| 369 | spin_unlock_irqrestore(&dev->event_lock, flags); | 369 | spin_unlock_irqrestore(&dev->event_lock, flags); |
| 370 | return 0; | 370 | return 0; |
| 371 | } | 371 | } |
| 372 | |||
| 373 | int | ||
| 374 | nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, | ||
| 375 | struct drm_mode_create_dumb *args) | ||
| 376 | { | ||
| 377 | struct nouveau_bo *bo; | ||
| 378 | int ret; | ||
| 379 | |||
| 380 | args->pitch = roundup(args->width * (args->bpp / 8), 256); | ||
| 381 | args->size = args->pitch * args->height; | ||
| 382 | args->size = roundup(args->size, PAGE_SIZE); | ||
| 383 | |||
| 384 | ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo); | ||
| 385 | if (ret) | ||
| 386 | return ret; | ||
| 387 | |||
| 388 | ret = drm_gem_handle_create(file_priv, bo->gem, &args->handle); | ||
| 389 | drm_gem_object_unreference_unlocked(bo->gem); | ||
| 390 | return ret; | ||
| 391 | } | ||
| 392 | |||
| 393 | int | ||
| 394 | nouveau_display_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev, | ||
| 395 | uint32_t handle) | ||
| 396 | { | ||
| 397 | return drm_gem_handle_delete(file_priv, handle); | ||
| 398 | } | ||
| 399 | |||
| 400 | int | ||
| 401 | nouveau_display_dumb_map_offset(struct drm_file *file_priv, | ||
| 402 | struct drm_device *dev, | ||
| 403 | uint32_t handle, uint64_t *poffset) | ||
| 404 | { | ||
| 405 | struct drm_gem_object *gem; | ||
| 406 | |||
| 407 | gem = drm_gem_object_lookup(dev, file_priv, handle); | ||
| 408 | if (gem) { | ||
| 409 | struct nouveau_bo *bo = gem->driver_private; | ||
| 410 | *poffset = bo->bo.addr_space_offset; | ||
| 411 | drm_gem_object_unreference_unlocked(gem); | ||
| 412 | return 0; | ||
| 413 | } | ||
| 414 | |||
| 415 | return -ENOENT; | ||
| 416 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 9f7bb129526..9791d13c9e3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
| @@ -433,6 +433,10 @@ static struct drm_driver driver = { | |||
| 433 | .gem_open_object = nouveau_gem_object_open, | 433 | .gem_open_object = nouveau_gem_object_open, |
| 434 | .gem_close_object = nouveau_gem_object_close, | 434 | .gem_close_object = nouveau_gem_object_close, |
| 435 | 435 | ||
| 436 | .dumb_create = nouveau_display_dumb_create, | ||
| 437 | .dumb_map_offset = nouveau_display_dumb_map_offset, | ||
| 438 | .dumb_destroy = nouveau_display_dumb_destroy, | ||
| 439 | |||
| 436 | .name = DRIVER_NAME, | 440 | .name = DRIVER_NAME, |
| 437 | .desc = DRIVER_DESC, | 441 | .desc = DRIVER_DESC, |
| 438 | #ifdef GIT_REVISION | 442 | #ifdef GIT_REVISION |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 29837da1098..4c0be3a4ed8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
| @@ -1418,6 +1418,12 @@ int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
| 1418 | struct drm_pending_vblank_event *event); | 1418 | struct drm_pending_vblank_event *event); |
| 1419 | int nouveau_finish_page_flip(struct nouveau_channel *, | 1419 | int nouveau_finish_page_flip(struct nouveau_channel *, |
| 1420 | struct nouveau_page_flip_state *); | 1420 | struct nouveau_page_flip_state *); |
| 1421 | int nouveau_display_dumb_create(struct drm_file *, struct drm_device *, | ||
| 1422 | struct drm_mode_create_dumb *args); | ||
| 1423 | int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *, | ||
| 1424 | uint32_t handle, uint64_t *offset); | ||
| 1425 | int nouveau_display_dumb_destroy(struct drm_file *, struct drm_device *, | ||
| 1426 | uint32_t handle); | ||
| 1421 | 1427 | ||
| 1422 | /* nv10_gpio.c */ | 1428 | /* nv10_gpio.c */ |
| 1423 | int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); | 1429 | int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 02222c540ae..960c0ae0c0c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
| @@ -680,7 +680,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) | |||
| 680 | return ret; | 680 | return ret; |
| 681 | } | 681 | } |
| 682 | 682 | ||
| 683 | ret = drm_mm_init(&chan->ramin_heap, base, size); | 683 | ret = drm_mm_init(&chan->ramin_heap, base, size - base); |
| 684 | if (ret) { | 684 | if (ret) { |
| 685 | NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret); | 685 | NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret); |
| 686 | nouveau_gpuobj_ref(NULL, &chan->ramin); | 686 | nouveau_gpuobj_ref(NULL, &chan->ramin); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index b75258a9fe4..c8a463b76c8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
| @@ -67,7 +67,10 @@ nouveau_sgdma_clear(struct ttm_backend *be) | |||
| 67 | pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages], | 67 | pci_unmap_page(dev->pdev, nvbe->pages[nvbe->nr_pages], |
| 68 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 68 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
| 69 | } | 69 | } |
| 70 | nvbe->unmap_pages = false; | ||
| 70 | } | 71 | } |
| 72 | |||
| 73 | nvbe->pages = NULL; | ||
| 71 | } | 74 | } |
| 72 | 75 | ||
| 73 | static void | 76 | static void |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index d23ca00e7d6..06de250fe61 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
| @@ -616,7 +616,7 @@ nv50_display_unk10_handler(struct drm_device *dev) | |||
| 616 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 616 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 617 | struct nv50_display *disp = nv50_display(dev); | 617 | struct nv50_display *disp = nv50_display(dev); |
| 618 | u32 unk30 = nv_rd32(dev, 0x610030), mc; | 618 | u32 unk30 = nv_rd32(dev, 0x610030), mc; |
| 619 | int i, crtc, or, type = OUTPUT_ANY; | 619 | int i, crtc, or = 0, type = OUTPUT_ANY; |
| 620 | 620 | ||
| 621 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); | 621 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); |
| 622 | disp->irq.dcb = NULL; | 622 | disp->irq.dcb = NULL; |
| @@ -708,7 +708,7 @@ nv50_display_unk20_handler(struct drm_device *dev) | |||
| 708 | struct nv50_display *disp = nv50_display(dev); | 708 | struct nv50_display *disp = nv50_display(dev); |
| 709 | u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc = 0; | 709 | u32 unk30 = nv_rd32(dev, 0x610030), tmp, pclk, script, mc = 0; |
| 710 | struct dcb_entry *dcb; | 710 | struct dcb_entry *dcb; |
| 711 | int i, crtc, or, type = OUTPUT_ANY; | 711 | int i, crtc, or = 0, type = OUTPUT_ANY; |
| 712 | 712 | ||
| 713 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); | 713 | NV_DEBUG_KMS(dev, "0x610030: 0x%08x\n", unk30); |
| 714 | dcb = disp->irq.dcb; | 714 | dcb = disp->irq.dcb; |
diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c index a74e501afd2..ecfafd70cf0 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.c +++ b/drivers/gpu/drm/nouveau/nvc0_graph.c | |||
| @@ -381,6 +381,8 @@ nvc0_graph_init_gpc_0(struct drm_device *dev) | |||
| 381 | u8 tpnr[GPC_MAX]; | 381 | u8 tpnr[GPC_MAX]; |
| 382 | int i, gpc, tpc; | 382 | int i, gpc, tpc; |
| 383 | 383 | ||
| 384 | nv_wr32(dev, TP_UNIT(0, 0, 0x5c), 1); /* affects TFB offset queries */ | ||
| 385 | |||
| 384 | /* | 386 | /* |
| 385 | * TP ROP UNKVAL(magic_not_rop_nr) | 387 | * TP ROP UNKVAL(magic_not_rop_nr) |
| 386 | * 450: 4/0/0/0 2 3 | 388 | * 450: 4/0/0/0 2 3 |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index 23d63b4b3d7..cb006a718e7 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
| @@ -780,7 +780,7 @@ nvd0_sor_dpms(struct drm_encoder *encoder, int mode) | |||
| 780 | continue; | 780 | continue; |
| 781 | 781 | ||
| 782 | if (nv_partner != nv_encoder && | 782 | if (nv_partner != nv_encoder && |
| 783 | nv_partner->dcb->or == nv_encoder->or) { | 783 | nv_partner->dcb->or == nv_encoder->dcb->or) { |
| 784 | if (nv_partner->last_dpms == DRM_MODE_DPMS_ON) | 784 | if (nv_partner->last_dpms == DRM_MODE_DPMS_ON) |
| 785 | return; | 785 | return; |
| 786 | break; | 786 | break; |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 87631fede1f..2b97262e3ab 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -1107,9 +1107,40 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
| 1107 | return -EINVAL; | 1107 | return -EINVAL; |
| 1108 | } | 1108 | } |
| 1109 | 1109 | ||
| 1110 | if (tiling_flags & RADEON_TILING_MACRO) | 1110 | if (tiling_flags & RADEON_TILING_MACRO) { |
| 1111 | if (rdev->family >= CHIP_CAYMAN) | ||
| 1112 | tmp = rdev->config.cayman.tile_config; | ||
| 1113 | else | ||
| 1114 | tmp = rdev->config.evergreen.tile_config; | ||
| 1115 | |||
| 1116 | switch ((tmp & 0xf0) >> 4) { | ||
| 1117 | case 0: /* 4 banks */ | ||
| 1118 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_4_BANK); | ||
| 1119 | break; | ||
| 1120 | case 1: /* 8 banks */ | ||
| 1121 | default: | ||
| 1122 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_8_BANK); | ||
| 1123 | break; | ||
| 1124 | case 2: /* 16 banks */ | ||
| 1125 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(EVERGREEN_ADDR_SURF_16_BANK); | ||
| 1126 | break; | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | switch ((tmp & 0xf000) >> 12) { | ||
| 1130 | case 0: /* 1KB rows */ | ||
| 1131 | default: | ||
| 1132 | fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB); | ||
| 1133 | break; | ||
| 1134 | case 1: /* 2KB rows */ | ||
| 1135 | fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB); | ||
| 1136 | break; | ||
| 1137 | case 2: /* 4KB rows */ | ||
| 1138 | fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB); | ||
| 1139 | break; | ||
| 1140 | } | ||
| 1141 | |||
| 1111 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); | 1142 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); |
| 1112 | else if (tiling_flags & RADEON_TILING_MICRO) | 1143 | } else if (tiling_flags & RADEON_TILING_MICRO) |
| 1113 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); | 1144 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); |
| 1114 | 1145 | ||
| 1115 | switch (radeon_crtc->crtc_id) { | 1146 | switch (radeon_crtc->crtc_id) { |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 1d603a3335d..5e00d1670aa 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
| @@ -82,6 +82,7 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | |||
| 82 | { | 82 | { |
| 83 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | 83 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; |
| 84 | u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset); | 84 | u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset); |
| 85 | int i; | ||
| 85 | 86 | ||
| 86 | /* Lock the graphics update lock */ | 87 | /* Lock the graphics update lock */ |
| 87 | tmp |= EVERGREEN_GRPH_UPDATE_LOCK; | 88 | tmp |= EVERGREEN_GRPH_UPDATE_LOCK; |
| @@ -99,7 +100,11 @@ u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | |||
| 99 | (u32)crtc_base); | 100 | (u32)crtc_base); |
| 100 | 101 | ||
| 101 | /* Wait for update_pending to go high. */ | 102 | /* Wait for update_pending to go high. */ |
| 102 | while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)); | 103 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 104 | if (RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING) | ||
| 105 | break; | ||
| 106 | udelay(1); | ||
| 107 | } | ||
| 103 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); | 108 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); |
| 104 | 109 | ||
| 105 | /* Unlock the lock, so double-buffering can take place inside vblank */ | 110 | /* Unlock the lock, so double-buffering can take place inside vblank */ |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 38e1bda73d3..cd4590aae15 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
| @@ -38,6 +38,7 @@ struct evergreen_cs_track { | |||
| 38 | u32 group_size; | 38 | u32 group_size; |
| 39 | u32 nbanks; | 39 | u32 nbanks; |
| 40 | u32 npipes; | 40 | u32 npipes; |
| 41 | u32 row_size; | ||
| 41 | /* value we track */ | 42 | /* value we track */ |
| 42 | u32 nsamples; | 43 | u32 nsamples; |
| 43 | u32 cb_color_base_last[12]; | 44 | u32 cb_color_base_last[12]; |
| @@ -77,6 +78,44 @@ struct evergreen_cs_track { | |||
| 77 | struct radeon_bo *db_s_write_bo; | 78 | struct radeon_bo *db_s_write_bo; |
| 78 | }; | 79 | }; |
| 79 | 80 | ||
| 81 | static u32 evergreen_cs_get_aray_mode(u32 tiling_flags) | ||
| 82 | { | ||
| 83 | if (tiling_flags & RADEON_TILING_MACRO) | ||
| 84 | return ARRAY_2D_TILED_THIN1; | ||
| 85 | else if (tiling_flags & RADEON_TILING_MICRO) | ||
| 86 | return ARRAY_1D_TILED_THIN1; | ||
| 87 | else | ||
| 88 | return ARRAY_LINEAR_GENERAL; | ||
| 89 | } | ||
| 90 | |||
| 91 | static u32 evergreen_cs_get_num_banks(u32 nbanks) | ||
| 92 | { | ||
| 93 | switch (nbanks) { | ||
| 94 | case 2: | ||
| 95 | return ADDR_SURF_2_BANK; | ||
| 96 | case 4: | ||
| 97 | return ADDR_SURF_4_BANK; | ||
| 98 | case 8: | ||
| 99 | default: | ||
| 100 | return ADDR_SURF_8_BANK; | ||
| 101 | case 16: | ||
| 102 | return ADDR_SURF_16_BANK; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | static u32 evergreen_cs_get_tile_split(u32 row_size) | ||
| 107 | { | ||
| 108 | switch (row_size) { | ||
| 109 | case 1: | ||
| 110 | default: | ||
| 111 | return ADDR_SURF_TILE_SPLIT_1KB; | ||
| 112 | case 2: | ||
| 113 | return ADDR_SURF_TILE_SPLIT_2KB; | ||
| 114 | case 4: | ||
| 115 | return ADDR_SURF_TILE_SPLIT_4KB; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 80 | static void evergreen_cs_track_init(struct evergreen_cs_track *track) | 119 | static void evergreen_cs_track_init(struct evergreen_cs_track *track) |
| 81 | { | 120 | { |
| 82 | int i; | 121 | int i; |
| @@ -490,12 +529,11 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
| 490 | } | 529 | } |
| 491 | ib[idx] &= ~Z_ARRAY_MODE(0xf); | 530 | ib[idx] &= ~Z_ARRAY_MODE(0xf); |
| 492 | track->db_z_info &= ~Z_ARRAY_MODE(0xf); | 531 | track->db_z_info &= ~Z_ARRAY_MODE(0xf); |
| 532 | ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); | ||
| 533 | track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); | ||
| 493 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 534 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { |
| 494 | ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 535 | ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); |
| 495 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 536 | ib[idx] |= DB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); |
| 496 | } else { | ||
| 497 | ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
| 498 | track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
| 499 | } | 537 | } |
| 500 | } | 538 | } |
| 501 | break; | 539 | break; |
| @@ -618,13 +656,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
| 618 | "0x%04X\n", reg); | 656 | "0x%04X\n", reg); |
| 619 | return -EINVAL; | 657 | return -EINVAL; |
| 620 | } | 658 | } |
| 621 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 659 | ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); |
| 622 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 660 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); |
| 623 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
| 624 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | ||
| 625 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
| 626 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
| 627 | } | ||
| 628 | } | 661 | } |
| 629 | break; | 662 | break; |
| 630 | case CB_COLOR8_INFO: | 663 | case CB_COLOR8_INFO: |
| @@ -640,13 +673,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
| 640 | "0x%04X\n", reg); | 673 | "0x%04X\n", reg); |
| 641 | return -EINVAL; | 674 | return -EINVAL; |
| 642 | } | 675 | } |
| 643 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 676 | ib[idx] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); |
| 644 | ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 677 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); |
| 645 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | ||
| 646 | } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | ||
| 647 | ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
| 648 | track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | ||
| 649 | } | ||
| 650 | } | 678 | } |
| 651 | break; | 679 | break; |
| 652 | case CB_COLOR0_PITCH: | 680 | case CB_COLOR0_PITCH: |
| @@ -701,6 +729,16 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
| 701 | case CB_COLOR9_ATTRIB: | 729 | case CB_COLOR9_ATTRIB: |
| 702 | case CB_COLOR10_ATTRIB: | 730 | case CB_COLOR10_ATTRIB: |
| 703 | case CB_COLOR11_ATTRIB: | 731 | case CB_COLOR11_ATTRIB: |
| 732 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
| 733 | if (r) { | ||
| 734 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
| 735 | "0x%04X\n", reg); | ||
| 736 | return -EINVAL; | ||
| 737 | } | ||
| 738 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
| 739 | ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); | ||
| 740 | ib[idx] |= CB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); | ||
| 741 | } | ||
| 704 | break; | 742 | break; |
| 705 | case CB_COLOR0_DIM: | 743 | case CB_COLOR0_DIM: |
| 706 | case CB_COLOR1_DIM: | 744 | case CB_COLOR1_DIM: |
| @@ -1318,10 +1356,14 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
| 1318 | } | 1356 | } |
| 1319 | ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | 1357 | ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); |
| 1320 | if (!p->keep_tiling_flags) { | 1358 | if (!p->keep_tiling_flags) { |
| 1321 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 1359 | ib[idx+1+(i*8)+1] |= |
| 1322 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); | 1360 | TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); |
| 1323 | else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 1361 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { |
| 1324 | ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); | 1362 | ib[idx+1+(i*8)+6] |= |
| 1363 | TEX_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); | ||
| 1364 | ib[idx+1+(i*8)+7] |= | ||
| 1365 | TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); | ||
| 1366 | } | ||
| 1325 | } | 1367 | } |
| 1326 | texture = reloc->robj; | 1368 | texture = reloc->robj; |
| 1327 | /* tex mip base */ | 1369 | /* tex mip base */ |
| @@ -1422,6 +1464,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) | |||
| 1422 | { | 1464 | { |
| 1423 | struct radeon_cs_packet pkt; | 1465 | struct radeon_cs_packet pkt; |
| 1424 | struct evergreen_cs_track *track; | 1466 | struct evergreen_cs_track *track; |
| 1467 | u32 tmp; | ||
| 1425 | int r; | 1468 | int r; |
| 1426 | 1469 | ||
| 1427 | if (p->track == NULL) { | 1470 | if (p->track == NULL) { |
| @@ -1430,9 +1473,63 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) | |||
| 1430 | if (track == NULL) | 1473 | if (track == NULL) |
| 1431 | return -ENOMEM; | 1474 | return -ENOMEM; |
| 1432 | evergreen_cs_track_init(track); | 1475 | evergreen_cs_track_init(track); |
| 1433 | track->npipes = p->rdev->config.evergreen.tiling_npipes; | 1476 | if (p->rdev->family >= CHIP_CAYMAN) |
| 1434 | track->nbanks = p->rdev->config.evergreen.tiling_nbanks; | 1477 | tmp = p->rdev->config.cayman.tile_config; |
| 1435 | track->group_size = p->rdev->config.evergreen.tiling_group_size; | 1478 | else |
| 1479 | tmp = p->rdev->config.evergreen.tile_config; | ||
| 1480 | |||
| 1481 | switch (tmp & 0xf) { | ||
| 1482 | case 0: | ||
| 1483 | track->npipes = 1; | ||
| 1484 | break; | ||
| 1485 | case 1: | ||
| 1486 | default: | ||
| 1487 | track->npipes = 2; | ||
| 1488 | break; | ||
| 1489 | case 2: | ||
| 1490 | track->npipes = 4; | ||
| 1491 | break; | ||
| 1492 | case 3: | ||
| 1493 | track->npipes = 8; | ||
| 1494 | break; | ||
| 1495 | } | ||
| 1496 | |||
| 1497 | switch ((tmp & 0xf0) >> 4) { | ||
| 1498 | case 0: | ||
| 1499 | track->nbanks = 4; | ||
| 1500 | break; | ||
| 1501 | case 1: | ||
| 1502 | default: | ||
| 1503 | track->nbanks = 8; | ||
| 1504 | break; | ||
| 1505 | case 2: | ||
| 1506 | track->nbanks = 16; | ||
| 1507 | break; | ||
| 1508 | } | ||
| 1509 | |||
| 1510 | switch ((tmp & 0xf00) >> 8) { | ||
| 1511 | case 0: | ||
| 1512 | track->group_size = 256; | ||
| 1513 | break; | ||
| 1514 | case 1: | ||
| 1515 | default: | ||
| 1516 | track->group_size = 512; | ||
| 1517 | break; | ||
| 1518 | } | ||
| 1519 | |||
| 1520 | switch ((tmp & 0xf000) >> 12) { | ||
| 1521 | case 0: | ||
| 1522 | track->row_size = 1; | ||
| 1523 | break; | ||
| 1524 | case 1: | ||
| 1525 | default: | ||
| 1526 | track->row_size = 2; | ||
| 1527 | break; | ||
| 1528 | case 2: | ||
| 1529 | track->row_size = 4; | ||
| 1530 | break; | ||
| 1531 | } | ||
| 1532 | |||
| 1436 | p->track = track; | 1533 | p->track = track; |
| 1437 | } | 1534 | } |
| 1438 | do { | 1535 | do { |
diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index c781c92c345..7d7f2155e34 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h | |||
| @@ -42,6 +42,17 @@ | |||
| 42 | # define EVERGREEN_GRPH_DEPTH_8BPP 0 | 42 | # define EVERGREEN_GRPH_DEPTH_8BPP 0 |
| 43 | # define EVERGREEN_GRPH_DEPTH_16BPP 1 | 43 | # define EVERGREEN_GRPH_DEPTH_16BPP 1 |
| 44 | # define EVERGREEN_GRPH_DEPTH_32BPP 2 | 44 | # define EVERGREEN_GRPH_DEPTH_32BPP 2 |
| 45 | # define EVERGREEN_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2) | ||
| 46 | # define EVERGREEN_ADDR_SURF_2_BANK 0 | ||
| 47 | # define EVERGREEN_ADDR_SURF_4_BANK 1 | ||
| 48 | # define EVERGREEN_ADDR_SURF_8_BANK 2 | ||
| 49 | # define EVERGREEN_ADDR_SURF_16_BANK 3 | ||
| 50 | # define EVERGREEN_GRPH_Z(x) (((x) & 0x3) << 4) | ||
| 51 | # define EVERGREEN_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6) | ||
| 52 | # define EVERGREEN_ADDR_SURF_BANK_WIDTH_1 0 | ||
| 53 | # define EVERGREEN_ADDR_SURF_BANK_WIDTH_2 1 | ||
| 54 | # define EVERGREEN_ADDR_SURF_BANK_WIDTH_4 2 | ||
| 55 | # define EVERGREEN_ADDR_SURF_BANK_WIDTH_8 3 | ||
| 45 | # define EVERGREEN_GRPH_FORMAT(x) (((x) & 0x7) << 8) | 56 | # define EVERGREEN_GRPH_FORMAT(x) (((x) & 0x7) << 8) |
| 46 | /* 8 BPP */ | 57 | /* 8 BPP */ |
| 47 | # define EVERGREEN_GRPH_FORMAT_INDEXED 0 | 58 | # define EVERGREEN_GRPH_FORMAT_INDEXED 0 |
| @@ -61,6 +72,24 @@ | |||
| 61 | # define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5 | 72 | # define EVERGREEN_GRPH_FORMAT_8B_BGRA1010102 5 |
| 62 | # define EVERGREEN_GRPH_FORMAT_RGB111110 6 | 73 | # define EVERGREEN_GRPH_FORMAT_RGB111110 6 |
| 63 | # define EVERGREEN_GRPH_FORMAT_BGR101111 7 | 74 | # define EVERGREEN_GRPH_FORMAT_BGR101111 7 |
| 75 | # define EVERGREEN_GRPH_BANK_HEIGHT(x) (((x) & 0x3) << 11) | ||
| 76 | # define EVERGREEN_ADDR_SURF_BANK_HEIGHT_1 0 | ||
| 77 | # define EVERGREEN_ADDR_SURF_BANK_HEIGHT_2 1 | ||
| 78 | # define EVERGREEN_ADDR_SURF_BANK_HEIGHT_4 2 | ||
| 79 | # define EVERGREEN_ADDR_SURF_BANK_HEIGHT_8 3 | ||
| 80 | # define EVERGREEN_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13) | ||
| 81 | # define EVERGREEN_ADDR_SURF_TILE_SPLIT_64B 0 | ||
| 82 | # define EVERGREEN_ADDR_SURF_TILE_SPLIT_128B 1 | ||
| 83 | # define EVERGREEN_ADDR_SURF_TILE_SPLIT_256B 2 | ||
| 84 | # define EVERGREEN_ADDR_SURF_TILE_SPLIT_512B 3 | ||
| 85 | # define EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB 4 | ||
| 86 | # define EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB 5 | ||
| 87 | # define EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB 6 | ||
| 88 | # define EVERGREEN_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18) | ||
| 89 | # define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1 0 | ||
| 90 | # define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2 1 | ||
| 91 | # define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4 2 | ||
| 92 | # define EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8 3 | ||
| 64 | # define EVERGREEN_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) | 93 | # define EVERGREEN_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) |
| 65 | # define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL 0 | 94 | # define EVERGREEN_GRPH_ARRAY_LINEAR_GENERAL 0 |
| 66 | # define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED 1 | 95 | # define EVERGREEN_GRPH_ARRAY_LINEAR_ALIGNED 1 |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index b937c49054d..e00039e59a7 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
| @@ -899,6 +899,10 @@ | |||
| 899 | #define DB_HTILE_DATA_BASE 0x28014 | 899 | #define DB_HTILE_DATA_BASE 0x28014 |
| 900 | #define DB_Z_INFO 0x28040 | 900 | #define DB_Z_INFO 0x28040 |
| 901 | # define Z_ARRAY_MODE(x) ((x) << 4) | 901 | # define Z_ARRAY_MODE(x) ((x) << 4) |
| 902 | # define DB_TILE_SPLIT(x) (((x) & 0x7) << 8) | ||
| 903 | # define DB_NUM_BANKS(x) (((x) & 0x3) << 12) | ||
| 904 | # define DB_BANK_WIDTH(x) (((x) & 0x3) << 16) | ||
| 905 | # define DB_BANK_HEIGHT(x) (((x) & 0x3) << 20) | ||
| 902 | #define DB_STENCIL_INFO 0x28044 | 906 | #define DB_STENCIL_INFO 0x28044 |
| 903 | #define DB_Z_READ_BASE 0x28048 | 907 | #define DB_Z_READ_BASE 0x28048 |
| 904 | #define DB_STENCIL_READ_BASE 0x2804c | 908 | #define DB_STENCIL_READ_BASE 0x2804c |
| @@ -951,6 +955,29 @@ | |||
| 951 | # define CB_SF_EXPORT_FULL 0 | 955 | # define CB_SF_EXPORT_FULL 0 |
| 952 | # define CB_SF_EXPORT_NORM 1 | 956 | # define CB_SF_EXPORT_NORM 1 |
| 953 | #define CB_COLOR0_ATTRIB 0x28c74 | 957 | #define CB_COLOR0_ATTRIB 0x28c74 |
| 958 | # define CB_TILE_SPLIT(x) (((x) & 0x7) << 5) | ||
| 959 | # define ADDR_SURF_TILE_SPLIT_64B 0 | ||
| 960 | # define ADDR_SURF_TILE_SPLIT_128B 1 | ||
| 961 | # define ADDR_SURF_TILE_SPLIT_256B 2 | ||
| 962 | # define ADDR_SURF_TILE_SPLIT_512B 3 | ||
| 963 | # define ADDR_SURF_TILE_SPLIT_1KB 4 | ||
| 964 | # define ADDR_SURF_TILE_SPLIT_2KB 5 | ||
| 965 | # define ADDR_SURF_TILE_SPLIT_4KB 6 | ||
| 966 | # define CB_NUM_BANKS(x) (((x) & 0x3) << 10) | ||
| 967 | # define ADDR_SURF_2_BANK 0 | ||
| 968 | # define ADDR_SURF_4_BANK 1 | ||
| 969 | # define ADDR_SURF_8_BANK 2 | ||
| 970 | # define ADDR_SURF_16_BANK 3 | ||
| 971 | # define CB_BANK_WIDTH(x) (((x) & 0x3) << 13) | ||
| 972 | # define ADDR_SURF_BANK_WIDTH_1 0 | ||
| 973 | # define ADDR_SURF_BANK_WIDTH_2 1 | ||
| 974 | # define ADDR_SURF_BANK_WIDTH_4 2 | ||
| 975 | # define ADDR_SURF_BANK_WIDTH_8 3 | ||
| 976 | # define CB_BANK_HEIGHT(x) (((x) & 0x3) << 16) | ||
| 977 | # define ADDR_SURF_BANK_HEIGHT_1 0 | ||
| 978 | # define ADDR_SURF_BANK_HEIGHT_2 1 | ||
| 979 | # define ADDR_SURF_BANK_HEIGHT_4 2 | ||
| 980 | # define ADDR_SURF_BANK_HEIGHT_8 3 | ||
| 954 | #define CB_COLOR0_DIM 0x28c78 | 981 | #define CB_COLOR0_DIM 0x28c78 |
| 955 | /* only CB0-7 blocks have these regs */ | 982 | /* only CB0-7 blocks have these regs */ |
| 956 | #define CB_COLOR0_CMASK 0x28c7c | 983 | #define CB_COLOR0_CMASK 0x28c7c |
| @@ -1137,7 +1164,11 @@ | |||
| 1137 | # define SQ_SEL_1 5 | 1164 | # define SQ_SEL_1 5 |
| 1138 | #define SQ_TEX_RESOURCE_WORD5_0 0x30014 | 1165 | #define SQ_TEX_RESOURCE_WORD5_0 0x30014 |
| 1139 | #define SQ_TEX_RESOURCE_WORD6_0 0x30018 | 1166 | #define SQ_TEX_RESOURCE_WORD6_0 0x30018 |
| 1167 | # define TEX_TILE_SPLIT(x) (((x) & 0x7) << 29) | ||
| 1140 | #define SQ_TEX_RESOURCE_WORD7_0 0x3001c | 1168 | #define SQ_TEX_RESOURCE_WORD7_0 0x3001c |
| 1169 | # define TEX_BANK_WIDTH(x) (((x) & 0x3) << 8) | ||
| 1170 | # define TEX_BANK_HEIGHT(x) (((x) & 0x3) << 10) | ||
| 1171 | # define TEX_NUM_BANKS(x) (((x) & 0x3) << 16) | ||
| 1141 | 1172 | ||
| 1142 | #define SQ_VTX_CONSTANT_WORD0_0 0x30000 | 1173 | #define SQ_VTX_CONSTANT_WORD0_0 0x30000 |
| 1143 | #define SQ_VTX_CONSTANT_WORD1_0 0x30004 | 1174 | #define SQ_VTX_CONSTANT_WORD1_0 0x30004 |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index ad158ea4990..bfc08f6320f 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -187,13 +187,18 @@ u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | |||
| 187 | { | 187 | { |
| 188 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | 188 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; |
| 189 | u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; | 189 | u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; |
| 190 | int i; | ||
| 190 | 191 | ||
| 191 | /* Lock the graphics update lock */ | 192 | /* Lock the graphics update lock */ |
| 192 | /* update the scanout addresses */ | 193 | /* update the scanout addresses */ |
| 193 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); | 194 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); |
| 194 | 195 | ||
| 195 | /* Wait for update_pending to go high. */ | 196 | /* Wait for update_pending to go high. */ |
| 196 | while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)); | 197 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 198 | if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET) | ||
| 199 | break; | ||
| 200 | udelay(1); | ||
| 201 | } | ||
| 197 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); | 202 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); |
| 198 | 203 | ||
| 199 | /* Unlock the lock, so double-buffering can take place inside vblank */ | 204 | /* Unlock the lock, so double-buffering can take place inside vblank */ |
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c index 3f6636bb2d7..3516a6081dc 100644 --- a/drivers/gpu/drm/radeon/radeon_acpi.c +++ b/drivers/gpu/drm/radeon/radeon_acpi.c | |||
| @@ -35,7 +35,8 @@ static int radeon_atif_call(acpi_handle handle) | |||
| 35 | 35 | ||
| 36 | /* Fail only if calling the method fails and ATIF is supported */ | 36 | /* Fail only if calling the method fails and ATIF is supported */ |
| 37 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 37 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
| 38 | printk(KERN_DEBUG "failed to evaluate ATIF got %s\n", acpi_format_exception(status)); | 38 | DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n", |
| 39 | acpi_format_exception(status)); | ||
| 39 | kfree(buffer.pointer); | 40 | kfree(buffer.pointer); |
| 40 | return 1; | 41 | return 1; |
| 41 | } | 42 | } |
| @@ -50,13 +51,13 @@ int radeon_acpi_init(struct radeon_device *rdev) | |||
| 50 | acpi_handle handle; | 51 | acpi_handle handle; |
| 51 | int ret; | 52 | int ret; |
| 52 | 53 | ||
| 53 | /* No need to proceed if we're sure that ATIF is not supported */ | ||
| 54 | if (!ASIC_IS_AVIVO(rdev) || !rdev->bios) | ||
| 55 | return 0; | ||
| 56 | |||
| 57 | /* Get the device handle */ | 54 | /* Get the device handle */ |
| 58 | handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); | 55 | handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); |
| 59 | 56 | ||
| 57 | /* No need to proceed if we're sure that ATIF is not supported */ | ||
| 58 | if (!ASIC_IS_AVIVO(rdev) || !rdev->bios || !handle) | ||
| 59 | return 0; | ||
| 60 | |||
| 60 | /* Call the ATIF method */ | 61 | /* Call the ATIF method */ |
| 61 | ret = radeon_atif_call(handle); | 62 | ret = radeon_atif_call(handle); |
| 62 | if (ret) | 63 | if (ret) |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 06e413e6a92..4b27efa4405 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/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 481b99e89f6..b1053d64042 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
| @@ -62,6 +62,7 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | |||
| 62 | { | 62 | { |
| 63 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | 63 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; |
| 64 | u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); | 64 | u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); |
| 65 | int i; | ||
| 65 | 66 | ||
| 66 | /* Lock the graphics update lock */ | 67 | /* Lock the graphics update lock */ |
| 67 | tmp |= AVIVO_D1GRPH_UPDATE_LOCK; | 68 | tmp |= AVIVO_D1GRPH_UPDATE_LOCK; |
| @@ -74,7 +75,11 @@ u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | |||
| 74 | (u32)crtc_base); | 75 | (u32)crtc_base); |
| 75 | 76 | ||
| 76 | /* Wait for update_pending to go high. */ | 77 | /* Wait for update_pending to go high. */ |
| 77 | while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); | 78 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 79 | if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) | ||
| 80 | break; | ||
| 81 | udelay(1); | ||
| 82 | } | ||
| 78 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); | 83 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); |
| 79 | 84 | ||
| 80 | /* Unlock the lock, so double-buffering can take place inside vblank */ | 85 | /* Unlock the lock, so double-buffering can take place inside vblank */ |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index a983f410ab8..23ae1c60ab3 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -47,6 +47,7 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | |||
| 47 | { | 47 | { |
| 48 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | 48 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; |
| 49 | u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); | 49 | u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); |
| 50 | int i; | ||
| 50 | 51 | ||
| 51 | /* Lock the graphics update lock */ | 52 | /* Lock the graphics update lock */ |
| 52 | tmp |= AVIVO_D1GRPH_UPDATE_LOCK; | 53 | tmp |= AVIVO_D1GRPH_UPDATE_LOCK; |
| @@ -66,7 +67,11 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | |||
| 66 | (u32)crtc_base); | 67 | (u32)crtc_base); |
| 67 | 68 | ||
| 68 | /* Wait for update_pending to go high. */ | 69 | /* Wait for update_pending to go high. */ |
| 69 | while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); | 70 | for (i = 0; i < rdev->usec_timeout; i++) { |
| 71 | if (RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) | ||
| 72 | break; | ||
| 73 | udelay(1); | ||
| 74 | } | ||
| 70 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); | 75 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); |
| 71 | 76 | ||
| 72 | /* Unlock the lock, so double-buffering can take place inside vblank */ | 77 | /* Unlock the lock, so double-buffering can take place inside vblank */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 3f6343502d1..5ff561d4e0b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c | |||
| @@ -140,7 +140,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, | |||
| 140 | goto out_clips; | 140 | goto out_clips; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); | 143 | clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); |
| 144 | if (clips == NULL) { | 144 | if (clips == NULL) { |
| 145 | DRM_ERROR("Failed to allocate clip rect list.\n"); | 145 | DRM_ERROR("Failed to allocate clip rect list.\n"); |
| 146 | ret = -ENOMEM; | 146 | ret = -ENOMEM; |
| @@ -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 880e285d757..37d40545ed7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
| @@ -1809,7 +1809,8 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | |||
| 1809 | } | 1809 | } |
| 1810 | 1810 | ||
| 1811 | rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); | 1811 | rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); |
| 1812 | rects = kzalloc(rects_size, GFP_KERNEL); | 1812 | rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect), |
| 1813 | GFP_KERNEL); | ||
| 1813 | if (unlikely(!rects)) { | 1814 | if (unlikely(!rects)) { |
| 1814 | ret = -ENOMEM; | 1815 | ret = -ENOMEM; |
| 1815 | goto out_unlock; | 1816 | goto out_unlock; |
| @@ -1824,10 +1825,10 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | |||
| 1824 | } | 1825 | } |
| 1825 | 1826 | ||
| 1826 | for (i = 0; i < arg->num_outputs; ++i) { | 1827 | for (i = 0; i < arg->num_outputs; ++i) { |
| 1827 | if (rects->x < 0 || | 1828 | if (rects[i].x < 0 || |
| 1828 | rects->y < 0 || | 1829 | rects[i].y < 0 || |
| 1829 | rects->x + rects->w > mode_config->max_width || | 1830 | rects[i].x + rects[i].w > mode_config->max_width || |
| 1830 | rects->y + rects->h > mode_config->max_height) { | 1831 | rects[i].y + rects[i].h > mode_config->max_height) { |
| 1831 | DRM_ERROR("Invalid GUI layout.\n"); | 1832 | DRM_ERROR("Invalid GUI layout.\n"); |
| 1832 | ret = -EINVAL; | 1833 | ret = -EINVAL; |
| 1833 | goto out_free; | 1834 | goto out_free; |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 848a56c0279..af353842f75 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1771,8 +1771,8 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
| 1771 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, | 1771 | { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, |
| 1772 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, | 1772 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, |
| 1773 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) }, | 1773 | { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) }, |
| 1774 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) }, | ||
| 1774 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, | 1775 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, |
| 1775 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) }, | ||
| 1776 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, | 1776 | { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, |
| 1777 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) }, | 1777 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) }, |
| 1778 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) }, | 1778 | { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) }, |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 06ce996b8b6..4a441a6f996 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
| @@ -266,7 +266,7 @@ | |||
| 266 | #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 | 266 | #define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 |
| 267 | 267 | ||
| 268 | #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc | 268 | #define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc |
| 269 | #define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0001 | 269 | #define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003 |
| 270 | 270 | ||
| 271 | #define USB_VENDOR_ID_GLAB 0x06c2 | 271 | #define USB_VENDOR_ID_GLAB 0x06c2 |
| 272 | #define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 | 272 | #define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 |
diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c index 7a48b1eb423..5253d23361d 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/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index c0c7820d4c4..bdc447fd476 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; |
| @@ -3524,7 +3527,7 @@ found: | |||
| 3524 | return 0; | 3527 | return 0; |
| 3525 | } | 3528 | } |
| 3526 | 3529 | ||
| 3527 | int dmar_parse_rmrr_atsr_dev(void) | 3530 | int __init dmar_parse_rmrr_atsr_dev(void) |
| 3528 | { | 3531 | { |
| 3529 | struct dmar_rmrr_unit *rmrr, *rmrr_n; | 3532 | struct dmar_rmrr_unit *rmrr, *rmrr_n; |
| 3530 | struct dmar_atsr_unit *atsr, *atsr_n; | 3533 | struct dmar_atsr_unit *atsr, *atsr_n; |
| @@ -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/iommu/intr_remapping.c b/drivers/iommu/intr_remapping.c index 07c9f189f31..6777ca04947 100644 --- a/drivers/iommu/intr_remapping.c +++ b/drivers/iommu/intr_remapping.c | |||
| @@ -773,7 +773,7 @@ int __init parse_ioapics_under_ir(void) | |||
| 773 | return ir_supported; | 773 | return ir_supported; |
| 774 | } | 774 | } |
| 775 | 775 | ||
| 776 | int ir_dev_scope_init(void) | 776 | int __init ir_dev_scope_init(void) |
| 777 | { | 777 | { |
| 778 | if (!intr_remapping_enabled) | 778 | if (!intr_remapping_enabled) |
| 779 | return 0; | 779 | return 0; |
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c index 33ec9e46777..9021182c4b7 100644 --- a/drivers/isdn/divert/divert_procfs.c +++ b/drivers/isdn/divert/divert_procfs.c | |||
| @@ -242,6 +242,12 @@ static int isdn_divert_ioctl_unlocked(struct file *file, uint cmd, ulong arg) | |||
| 242 | case IIOCDOCFINT: | 242 | case IIOCDOCFINT: |
| 243 | if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid)) | 243 | if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid)) |
| 244 | return (-EINVAL); /* invalid driver */ | 244 | return (-EINVAL); /* invalid driver */ |
| 245 | if (strnlen(dioctl.cf_ctrl.msn, sizeof(dioctl.cf_ctrl.msn)) == | ||
| 246 | sizeof(dioctl.cf_ctrl.msn)) | ||
| 247 | return -EINVAL; | ||
| 248 | if (strnlen(dioctl.cf_ctrl.fwd_nr, sizeof(dioctl.cf_ctrl.fwd_nr)) == | ||
| 249 | sizeof(dioctl.cf_ctrl.fwd_nr)) | ||
| 250 | return -EINVAL; | ||
| 245 | if ((i = cf_command(dioctl.cf_ctrl.drvid, | 251 | if ((i = cf_command(dioctl.cf_ctrl.drvid, |
| 246 | (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2, | 252 | (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2, |
| 247 | dioctl.cf_ctrl.cfproc, | 253 | dioctl.cf_ctrl.cfproc, |
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 1f73d7f7e02..2339d7396b9 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c | |||
| @@ -2756,6 +2756,9 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg) | |||
| 2756 | char *c, | 2756 | char *c, |
| 2757 | *e; | 2757 | *e; |
| 2758 | 2758 | ||
| 2759 | if (strnlen(cfg->drvid, sizeof(cfg->drvid)) == | ||
| 2760 | sizeof(cfg->drvid)) | ||
| 2761 | return -EINVAL; | ||
| 2759 | drvidx = -1; | 2762 | drvidx = -1; |
| 2760 | chidx = -1; | 2763 | chidx = -1; |
| 2761 | strcpy(drvid, cfg->drvid); | 2764 | strcpy(drvid, cfg->drvid); |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 7878712721b..b6907118283 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 84acfe7d10e..ee981737edf 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 297e2609217..31670f8d6b6 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/mmc/card/block.c b/drivers/mmc/card/block.c index a1cb21f9530..1e0e27cbe98 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 5278ffb20e7..950b97d7412 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/mmc.c b/drivers/mmc/core/mmc.c index dbf421a6279..d240427c124 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 325ea61e12d..8e0fbe99404 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 101cd31c822..d5fe43d53c5 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 4b920b7621c..87b6f079b6e 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 | ||
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 3d00e722efc..cb60c4197e0 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
| @@ -644,8 +644,6 @@ static int sdhci_s3c_resume(struct platform_device *dev) | |||
| 644 | static struct platform_driver sdhci_s3c_driver = { | 644 | static struct platform_driver sdhci_s3c_driver = { |
| 645 | .probe = sdhci_s3c_probe, | 645 | .probe = sdhci_s3c_probe, |
| 646 | .remove = __devexit_p(sdhci_s3c_remove), | 646 | .remove = __devexit_p(sdhci_s3c_remove), |
| 647 | .suspend = sdhci_s3c_suspend, | ||
| 648 | .resume = sdhci_s3c_resume, | ||
| 649 | .driver = { | 647 | .driver = { |
| 650 | .owner = THIS_MODULE, | 648 | .owner = THIS_MODULE, |
| 651 | .name = "s3c-sdhci", | 649 | .name = "s3c-sdhci", |
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 369366c8e20..d5505f3fe2a 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 d85a60cda16..4208b395806 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/net/arcnet/Kconfig b/drivers/net/arcnet/Kconfig index a73d9dc80ff..84fb6349a59 100644 --- a/drivers/net/arcnet/Kconfig +++ b/drivers/net/arcnet/Kconfig | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | menuconfig ARCNET | 5 | menuconfig ARCNET |
| 6 | depends on NETDEVICES && (ISA || PCI || PCMCIA) | 6 | depends on NETDEVICES && (ISA || PCI || PCMCIA) |
| 7 | bool "ARCnet support" | 7 | tristate "ARCnet support" |
| 8 | ---help--- | 8 | ---help--- |
| 9 | If you have a network card of this type, say Y and check out the | 9 | If you have a network card of this type, say Y and check out the |
| 10 | (arguably) beautiful poetry in | 10 | (arguably) beautiful poetry in |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b0c57725648..7f8756825b8 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -2553,30 +2553,6 @@ re_arm: | |||
| 2553 | } | 2553 | } |
| 2554 | } | 2554 | } |
| 2555 | 2555 | ||
| 2556 | static __be32 bond_glean_dev_ip(struct net_device *dev) | ||
| 2557 | { | ||
| 2558 | struct in_device *idev; | ||
| 2559 | struct in_ifaddr *ifa; | ||
| 2560 | __be32 addr = 0; | ||
| 2561 | |||
| 2562 | if (!dev) | ||
| 2563 | return 0; | ||
| 2564 | |||
| 2565 | rcu_read_lock(); | ||
| 2566 | idev = __in_dev_get_rcu(dev); | ||
| 2567 | if (!idev) | ||
| 2568 | goto out; | ||
| 2569 | |||
| 2570 | ifa = idev->ifa_list; | ||
| 2571 | if (!ifa) | ||
| 2572 | goto out; | ||
| 2573 | |||
| 2574 | addr = ifa->ifa_local; | ||
| 2575 | out: | ||
| 2576 | rcu_read_unlock(); | ||
| 2577 | return addr; | ||
| 2578 | } | ||
| 2579 | |||
| 2580 | static int bond_has_this_ip(struct bonding *bond, __be32 ip) | 2556 | static int bond_has_this_ip(struct bonding *bond, __be32 ip) |
| 2581 | { | 2557 | { |
| 2582 | struct vlan_entry *vlan; | 2558 | struct vlan_entry *vlan; |
| @@ -3322,6 +3298,10 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, | |||
| 3322 | struct bonding *bond; | 3298 | struct bonding *bond; |
| 3323 | struct vlan_entry *vlan; | 3299 | struct vlan_entry *vlan; |
| 3324 | 3300 | ||
| 3301 | /* we only care about primary address */ | ||
| 3302 | if(ifa->ifa_flags & IFA_F_SECONDARY) | ||
| 3303 | return NOTIFY_DONE; | ||
| 3304 | |||
| 3325 | list_for_each_entry(bond, &bn->dev_list, bond_list) { | 3305 | list_for_each_entry(bond, &bn->dev_list, bond_list) { |
| 3326 | if (bond->dev == event_dev) { | 3306 | if (bond->dev == event_dev) { |
| 3327 | switch (event) { | 3307 | switch (event) { |
| @@ -3329,7 +3309,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, | |||
| 3329 | bond->master_ip = ifa->ifa_local; | 3309 | bond->master_ip = ifa->ifa_local; |
| 3330 | return NOTIFY_OK; | 3310 | return NOTIFY_OK; |
| 3331 | case NETDEV_DOWN: | 3311 | case NETDEV_DOWN: |
| 3332 | bond->master_ip = bond_glean_dev_ip(bond->dev); | 3312 | bond->master_ip = 0; |
| 3333 | return NOTIFY_OK; | 3313 | return NOTIFY_OK; |
| 3334 | default: | 3314 | default: |
| 3335 | return NOTIFY_DONE; | 3315 | return NOTIFY_DONE; |
| @@ -3345,8 +3325,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, | |||
| 3345 | vlan->vlan_ip = ifa->ifa_local; | 3325 | vlan->vlan_ip = ifa->ifa_local; |
| 3346 | return NOTIFY_OK; | 3326 | return NOTIFY_OK; |
| 3347 | case NETDEV_DOWN: | 3327 | case NETDEV_DOWN: |
| 3348 | vlan->vlan_ip = | 3328 | vlan->vlan_ip = 0; |
| 3349 | bond_glean_dev_ip(vlan_dev); | ||
| 3350 | return NOTIFY_OK; | 3329 | return NOTIFY_OK; |
| 3351 | default: | 3330 | default: |
| 3352 | return NOTIFY_DONE; | 3331 | return NOTIFY_DONE; |
diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c index 905bce0b3a4..2c7f5036f57 100644 --- a/drivers/net/can/sja1000/peak_pci.c +++ b/drivers/net/can/sja1000/peak_pci.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 23 | #include <linux/version.h> | ||
| 24 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 25 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
| 26 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 4cf835dbc12..3fb66d09ece 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c | |||
| @@ -608,7 +608,7 @@ static void b44_tx(struct b44 *bp) | |||
| 608 | skb->len, | 608 | skb->len, |
| 609 | DMA_TO_DEVICE); | 609 | DMA_TO_DEVICE); |
| 610 | rp->skb = NULL; | 610 | rp->skb = NULL; |
| 611 | dev_kfree_skb(skb); | 611 | dev_kfree_skb_irq(skb); |
| 612 | } | 612 | } |
| 613 | 613 | ||
| 614 | bp->tx_cons = cons; | 614 | bp->tx_cons = cons; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index bce203fa4b9..882f48f0a03 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
| @@ -10327,6 +10327,43 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy, | |||
| 10327 | return 0; | 10327 | return 0; |
| 10328 | } | 10328 | } |
| 10329 | 10329 | ||
| 10330 | |||
| 10331 | static void bnx2x_5461x_set_link_led(struct bnx2x_phy *phy, | ||
| 10332 | struct link_params *params, u8 mode) | ||
| 10333 | { | ||
| 10334 | struct bnx2x *bp = params->bp; | ||
| 10335 | u16 temp; | ||
| 10336 | |||
| 10337 | bnx2x_cl22_write(bp, phy, | ||
| 10338 | MDIO_REG_GPHY_SHADOW, | ||
| 10339 | MDIO_REG_GPHY_SHADOW_LED_SEL1); | ||
| 10340 | bnx2x_cl22_read(bp, phy, | ||
| 10341 | MDIO_REG_GPHY_SHADOW, | ||
| 10342 | &temp); | ||
| 10343 | temp &= 0xff00; | ||
| 10344 | |||
| 10345 | DP(NETIF_MSG_LINK, "54618x set link led (mode=%x)\n", mode); | ||
| 10346 | switch (mode) { | ||
| 10347 | case LED_MODE_FRONT_PANEL_OFF: | ||
| 10348 | case LED_MODE_OFF: | ||
| 10349 | temp |= 0x00ee; | ||
| 10350 | break; | ||
| 10351 | case LED_MODE_OPER: | ||
| 10352 | temp |= 0x0001; | ||
| 10353 | break; | ||
| 10354 | case LED_MODE_ON: | ||
| 10355 | temp |= 0x00ff; | ||
| 10356 | break; | ||
| 10357 | default: | ||
| 10358 | break; | ||
| 10359 | } | ||
| 10360 | bnx2x_cl22_write(bp, phy, | ||
| 10361 | MDIO_REG_GPHY_SHADOW, | ||
| 10362 | MDIO_REG_GPHY_SHADOW_WR_ENA | temp); | ||
| 10363 | return; | ||
| 10364 | } | ||
| 10365 | |||
| 10366 | |||
| 10330 | static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy, | 10367 | static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy, |
| 10331 | struct link_params *params) | 10368 | struct link_params *params) |
| 10332 | { | 10369 | { |
| @@ -11103,7 +11140,7 @@ static struct bnx2x_phy phy_54618se = { | |||
| 11103 | .config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback, | 11140 | .config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback, |
| 11104 | .format_fw_ver = (format_fw_ver_t)NULL, | 11141 | .format_fw_ver = (format_fw_ver_t)NULL, |
| 11105 | .hw_reset = (hw_reset_t)NULL, | 11142 | .hw_reset = (hw_reset_t)NULL, |
| 11106 | .set_link_led = (set_link_led_t)NULL, | 11143 | .set_link_led = (set_link_led_t)bnx2x_5461x_set_link_led, |
| 11107 | .phy_specific_func = (phy_specific_func_t)NULL | 11144 | .phy_specific_func = (phy_specific_func_t)NULL |
| 11108 | }; | 11145 | }; |
| 11109 | /*****************************************************************/ | 11146 | /*****************************************************************/ |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index fc7bd0f23c0..e58073ef33b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | |||
| @@ -6990,6 +6990,7 @@ Theotherbitsarereservedandshouldbezero*/ | |||
| 6990 | #define MDIO_REG_INTR_MASK 0x1b | 6990 | #define MDIO_REG_INTR_MASK 0x1b |
| 6991 | #define MDIO_REG_INTR_MASK_LINK_STATUS (0x1 << 1) | 6991 | #define MDIO_REG_INTR_MASK_LINK_STATUS (0x1 << 1) |
| 6992 | #define MDIO_REG_GPHY_SHADOW 0x1c | 6992 | #define MDIO_REG_GPHY_SHADOW 0x1c |
| 6993 | #define MDIO_REG_GPHY_SHADOW_LED_SEL1 (0x0d << 10) | ||
| 6993 | #define MDIO_REG_GPHY_SHADOW_LED_SEL2 (0x0e << 10) | 6994 | #define MDIO_REG_GPHY_SHADOW_LED_SEL2 (0x0e << 10) |
| 6994 | #define MDIO_REG_GPHY_SHADOW_WR_ENA (0x1 << 15) | 6995 | #define MDIO_REG_GPHY_SHADOW_WR_ENA (0x1 << 15) |
| 6995 | #define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED (0x1e << 10) | 6996 | #define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED (0x1e << 10) |
diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c index 438f4580bf6..2a22f525635 100644 --- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c | |||
| @@ -613,7 +613,7 @@ static int dm9000_set_wol(struct net_device *dev, struct ethtool_wolinfo *w) | |||
| 613 | 613 | ||
| 614 | if (!dm->wake_state) | 614 | if (!dm->wake_state) |
| 615 | irq_set_irq_wake(dm->irq_wake, 1); | 615 | irq_set_irq_wake(dm->irq_wake, 1); |
| 616 | else if (dm->wake_state & !opts) | 616 | else if (dm->wake_state && !opts) |
| 617 | irq_set_irq_wake(dm->irq_wake, 0); | 617 | irq_set_irq_wake(dm->irq_wake, 0); |
| 618 | } | 618 | } |
| 619 | 619 | ||
diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig index c520cfd3b29..5272f9d4dda 100644 --- a/drivers/net/ethernet/freescale/Kconfig +++ b/drivers/net/ethernet/freescale/Kconfig | |||
| @@ -24,6 +24,7 @@ config FEC | |||
| 24 | bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)" | 24 | bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)" |
| 25 | depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \ | 25 | depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \ |
| 26 | ARCH_MXC || ARCH_MXS) | 26 | ARCH_MXC || ARCH_MXS) |
| 27 | default ARCH_MXC || ARCH_MXS if ARM | ||
| 27 | select PHYLIB | 28 | select PHYLIB |
| 28 | ---help--- | 29 | ---help--- |
| 29 | Say Y here if you want to use the built-in 10/100 Fast ethernet | 30 | Say Y here if you want to use the built-in 10/100 Fast ethernet |
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 1124ce0a159..c136230d50b 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c | |||
| @@ -232,6 +232,7 @@ struct fec_enet_private { | |||
| 232 | struct platform_device *pdev; | 232 | struct platform_device *pdev; |
| 233 | 233 | ||
| 234 | int opened; | 234 | int opened; |
| 235 | int dev_id; | ||
| 235 | 236 | ||
| 236 | /* Phylib and MDIO interface */ | 237 | /* Phylib and MDIO interface */ |
| 237 | struct mii_bus *mii_bus; | 238 | struct mii_bus *mii_bus; |
| @@ -837,7 +838,7 @@ static void __inline__ fec_get_mac(struct net_device *ndev) | |||
| 837 | 838 | ||
| 838 | /* Adjust MAC if using macaddr */ | 839 | /* Adjust MAC if using macaddr */ |
| 839 | if (iap == macaddr) | 840 | if (iap == macaddr) |
| 840 | ndev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->pdev->id; | 841 | ndev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->dev_id; |
| 841 | } | 842 | } |
| 842 | 843 | ||
| 843 | /* ------------------------------------------------------------------------- */ | 844 | /* ------------------------------------------------------------------------- */ |
| @@ -953,7 +954,7 @@ static int fec_enet_mii_probe(struct net_device *ndev) | |||
| 953 | char mdio_bus_id[MII_BUS_ID_SIZE]; | 954 | char mdio_bus_id[MII_BUS_ID_SIZE]; |
| 954 | char phy_name[MII_BUS_ID_SIZE + 3]; | 955 | char phy_name[MII_BUS_ID_SIZE + 3]; |
| 955 | int phy_id; | 956 | int phy_id; |
| 956 | int dev_id = fep->pdev->id; | 957 | int dev_id = fep->dev_id; |
| 957 | 958 | ||
| 958 | fep->phy_dev = NULL; | 959 | fep->phy_dev = NULL; |
| 959 | 960 | ||
| @@ -1031,7 +1032,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) | |||
| 1031 | * mdio interface in board design, and need to be configured by | 1032 | * mdio interface in board design, and need to be configured by |
| 1032 | * fec0 mii_bus. | 1033 | * fec0 mii_bus. |
| 1033 | */ | 1034 | */ |
| 1034 | if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id > 0) { | 1035 | if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && fep->dev_id > 0) { |
| 1035 | /* fec1 uses fec0 mii_bus */ | 1036 | /* fec1 uses fec0 mii_bus */ |
| 1036 | fep->mii_bus = fec0_mii_bus; | 1037 | fep->mii_bus = fec0_mii_bus; |
| 1037 | return 0; | 1038 | return 0; |
| @@ -1063,7 +1064,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) | |||
| 1063 | fep->mii_bus->read = fec_enet_mdio_read; | 1064 | fep->mii_bus->read = fec_enet_mdio_read; |
| 1064 | fep->mii_bus->write = fec_enet_mdio_write; | 1065 | fep->mii_bus->write = fec_enet_mdio_write; |
| 1065 | fep->mii_bus->reset = fec_enet_mdio_reset; | 1066 | fep->mii_bus->reset = fec_enet_mdio_reset; |
| 1066 | snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id + 1); | 1067 | snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%x", fep->dev_id + 1); |
| 1067 | fep->mii_bus->priv = fep; | 1068 | fep->mii_bus->priv = fep; |
| 1068 | fep->mii_bus->parent = &pdev->dev; | 1069 | fep->mii_bus->parent = &pdev->dev; |
| 1069 | 1070 | ||
| @@ -1521,6 +1522,7 @@ fec_probe(struct platform_device *pdev) | |||
| 1521 | int i, irq, ret = 0; | 1522 | int i, irq, ret = 0; |
| 1522 | struct resource *r; | 1523 | struct resource *r; |
| 1523 | const struct of_device_id *of_id; | 1524 | const struct of_device_id *of_id; |
| 1525 | static int dev_id; | ||
| 1524 | 1526 | ||
| 1525 | of_id = of_match_device(fec_dt_ids, &pdev->dev); | 1527 | of_id = of_match_device(fec_dt_ids, &pdev->dev); |
| 1526 | if (of_id) | 1528 | if (of_id) |
| @@ -1548,6 +1550,7 @@ fec_probe(struct platform_device *pdev) | |||
| 1548 | 1550 | ||
| 1549 | fep->hwp = ioremap(r->start, resource_size(r)); | 1551 | fep->hwp = ioremap(r->start, resource_size(r)); |
| 1550 | fep->pdev = pdev; | 1552 | fep->pdev = pdev; |
| 1553 | fep->dev_id = dev_id++; | ||
| 1551 | 1554 | ||
| 1552 | if (!fep->hwp) { | 1555 | if (!fep->hwp) { |
| 1553 | ret = -ENOMEM; | 1556 | ret = -ENOMEM; |
diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c index 52f4e8ad48e..4d9f84b8ab9 100644 --- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c +++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c | |||
| @@ -183,28 +183,10 @@ void fsl_pq_mdio_bus_name(char *name, struct device_node *np) | |||
| 183 | } | 183 | } |
| 184 | EXPORT_SYMBOL_GPL(fsl_pq_mdio_bus_name); | 184 | EXPORT_SYMBOL_GPL(fsl_pq_mdio_bus_name); |
| 185 | 185 | ||
| 186 | /* Scan the bus in reverse, looking for an empty spot */ | ||
| 187 | static int fsl_pq_mdio_find_free(struct mii_bus *new_bus) | ||
| 188 | { | ||
| 189 | int i; | ||
| 190 | |||
| 191 | for (i = PHY_MAX_ADDR; i > 0; i--) { | ||
| 192 | u32 phy_id; | ||
| 193 | |||
| 194 | if (get_phy_id(new_bus, i, &phy_id)) | ||
| 195 | return -1; | ||
| 196 | |||
| 197 | if (phy_id == 0xffffffff) | ||
| 198 | break; | ||
| 199 | } | ||
| 200 | |||
| 201 | return i; | ||
| 202 | } | ||
| 203 | |||
| 204 | 186 | ||
| 205 | #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) | ||
| 206 | static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np) | 187 | static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np) |
| 207 | { | 188 | { |
| 189 | #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) | ||
| 208 | struct gfar __iomem *enet_regs; | 190 | struct gfar __iomem *enet_regs; |
| 209 | 191 | ||
| 210 | /* | 192 | /* |
| @@ -220,15 +202,15 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct devi | |||
| 220 | } else if (of_device_is_compatible(np, "fsl,etsec2-mdio") || | 202 | } else if (of_device_is_compatible(np, "fsl,etsec2-mdio") || |
| 221 | of_device_is_compatible(np, "fsl,etsec2-tbi")) { | 203 | of_device_is_compatible(np, "fsl,etsec2-tbi")) { |
| 222 | return of_iomap(np, 1); | 204 | return of_iomap(np, 1); |
| 223 | } else | 205 | } |
| 224 | return NULL; | ||
| 225 | } | ||
| 226 | #endif | 206 | #endif |
| 207 | return NULL; | ||
| 208 | } | ||
| 227 | 209 | ||
| 228 | 210 | ||
| 229 | #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) | ||
| 230 | static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) | 211 | static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) |
| 231 | { | 212 | { |
| 213 | #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) | ||
| 232 | struct device_node *np = NULL; | 214 | struct device_node *np = NULL; |
| 233 | int err = 0; | 215 | int err = 0; |
| 234 | 216 | ||
| @@ -261,9 +243,10 @@ static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) | |||
| 261 | return err; | 243 | return err; |
| 262 | else | 244 | else |
| 263 | return -EINVAL; | 245 | return -EINVAL; |
| 264 | } | 246 | #else |
| 247 | return -ENODEV; | ||
| 265 | #endif | 248 | #endif |
| 266 | 249 | } | |
| 267 | 250 | ||
| 268 | static int fsl_pq_mdio_probe(struct platform_device *ofdev) | 251 | static int fsl_pq_mdio_probe(struct platform_device *ofdev) |
| 269 | { | 252 | { |
| @@ -339,19 +322,13 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) | |||
| 339 | of_device_is_compatible(np, "fsl,etsec2-mdio") || | 322 | of_device_is_compatible(np, "fsl,etsec2-mdio") || |
| 340 | of_device_is_compatible(np, "fsl,etsec2-tbi") || | 323 | of_device_is_compatible(np, "fsl,etsec2-tbi") || |
| 341 | of_device_is_compatible(np, "gianfar")) { | 324 | of_device_is_compatible(np, "gianfar")) { |
| 342 | #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) | ||
| 343 | tbipa = get_gfar_tbipa(regs, np); | 325 | tbipa = get_gfar_tbipa(regs, np); |
| 344 | if (!tbipa) { | 326 | if (!tbipa) { |
| 345 | err = -EINVAL; | 327 | err = -EINVAL; |
| 346 | goto err_free_irqs; | 328 | goto err_free_irqs; |
| 347 | } | 329 | } |
| 348 | #else | ||
| 349 | err = -ENODEV; | ||
| 350 | goto err_free_irqs; | ||
| 351 | #endif | ||
| 352 | } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || | 330 | } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || |
| 353 | of_device_is_compatible(np, "ucc_geth_phy")) { | 331 | of_device_is_compatible(np, "ucc_geth_phy")) { |
| 354 | #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) | ||
| 355 | u32 id; | 332 | u32 id; |
| 356 | static u32 mii_mng_master; | 333 | static u32 mii_mng_master; |
| 357 | 334 | ||
| @@ -364,10 +341,6 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) | |||
| 364 | mii_mng_master = id; | 341 | mii_mng_master = id; |
| 365 | ucc_set_qe_mux_mii_mng(id - 1); | 342 | ucc_set_qe_mux_mii_mng(id - 1); |
| 366 | } | 343 | } |
| 367 | #else | ||
| 368 | err = -ENODEV; | ||
| 369 | goto err_free_irqs; | ||
| 370 | #endif | ||
| 371 | } else { | 344 | } else { |
| 372 | err = -ENODEV; | 345 | err = -ENODEV; |
| 373 | goto err_free_irqs; | 346 | goto err_free_irqs; |
| @@ -386,16 +359,6 @@ static int fsl_pq_mdio_probe(struct platform_device *ofdev) | |||
| 386 | } | 359 | } |
| 387 | 360 | ||
| 388 | if (tbiaddr == -1) { | 361 | if (tbiaddr == -1) { |
| 389 | out_be32(tbipa, 0); | ||
| 390 | |||
| 391 | tbiaddr = fsl_pq_mdio_find_free(new_bus); | ||
| 392 | } | ||
| 393 | |||
| 394 | /* | ||
| 395 | * We define TBIPA at 0 to be illegal, opting to fail for boards that | ||
| 396 | * have PHYs at 1-31, rather than change tbipa and rescan. | ||
| 397 | */ | ||
| 398 | if (tbiaddr == 0) { | ||
| 399 | err = -EBUSY; | 362 | err = -EBUSY; |
| 400 | 363 | ||
| 401 | goto err_free_irqs; | 364 | goto err_free_irqs; |
diff --git a/drivers/net/ethernet/ibm/ehea/ehea.h b/drivers/net/ethernet/ibm/ehea/ehea.h index 410d6a1984e..6650068c996 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea.h +++ b/drivers/net/ethernet/ibm/ehea/ehea.h | |||
| @@ -61,9 +61,9 @@ | |||
| 61 | #ifdef EHEA_SMALL_QUEUES | 61 | #ifdef EHEA_SMALL_QUEUES |
| 62 | #define EHEA_MAX_CQE_COUNT 1023 | 62 | #define EHEA_MAX_CQE_COUNT 1023 |
| 63 | #define EHEA_DEF_ENTRIES_SQ 1023 | 63 | #define EHEA_DEF_ENTRIES_SQ 1023 |
| 64 | #define EHEA_DEF_ENTRIES_RQ1 4095 | 64 | #define EHEA_DEF_ENTRIES_RQ1 1023 |
| 65 | #define EHEA_DEF_ENTRIES_RQ2 1023 | 65 | #define EHEA_DEF_ENTRIES_RQ2 1023 |
| 66 | #define EHEA_DEF_ENTRIES_RQ3 1023 | 66 | #define EHEA_DEF_ENTRIES_RQ3 511 |
| 67 | #else | 67 | #else |
| 68 | #define EHEA_MAX_CQE_COUNT 4080 | 68 | #define EHEA_MAX_CQE_COUNT 4080 |
| 69 | #define EHEA_DEF_ENTRIES_SQ 4080 | 69 | #define EHEA_DEF_ENTRIES_SQ 4080 |
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 37b70f7052b..bfeccbfde23 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c | |||
| @@ -371,7 +371,8 @@ static void ehea_update_stats(struct work_struct *work) | |||
| 371 | out_herr: | 371 | out_herr: |
| 372 | free_page((unsigned long)cb2); | 372 | free_page((unsigned long)cb2); |
| 373 | resched: | 373 | resched: |
| 374 | schedule_delayed_work(&port->stats_work, msecs_to_jiffies(1000)); | 374 | schedule_delayed_work(&port->stats_work, |
| 375 | round_jiffies_relative(msecs_to_jiffies(1000))); | ||
| 375 | } | 376 | } |
| 376 | 377 | ||
| 377 | static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes) | 378 | static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes) |
| @@ -2434,7 +2435,8 @@ static int ehea_open(struct net_device *dev) | |||
| 2434 | } | 2435 | } |
| 2435 | 2436 | ||
| 2436 | mutex_unlock(&port->port_lock); | 2437 | mutex_unlock(&port->port_lock); |
| 2437 | schedule_delayed_work(&port->stats_work, msecs_to_jiffies(1000)); | 2438 | schedule_delayed_work(&port->stats_work, |
| 2439 | round_jiffies_relative(msecs_to_jiffies(1000))); | ||
| 2438 | 2440 | ||
| 2439 | return ret; | 2441 | return ret; |
| 2440 | } | 2442 | } |
diff --git a/drivers/net/ethernet/ibm/iseries_veth.c b/drivers/net/ethernet/ibm/iseries_veth.c index 4326681df38..acc31af6594 100644 --- a/drivers/net/ethernet/ibm/iseries_veth.c +++ b/drivers/net/ethernet/ibm/iseries_veth.c | |||
| @@ -1421,7 +1421,7 @@ static void veth_receive(struct veth_lpar_connection *cnx, | |||
| 1421 | 1421 | ||
| 1422 | /* FIXME: do we need this? */ | 1422 | /* FIXME: do we need this? */ |
| 1423 | memset(local_list, 0, sizeof(local_list)); | 1423 | memset(local_list, 0, sizeof(local_list)); |
| 1424 | memset(remote_list, 0, sizeof(VETH_MAX_FRAMES_PER_MSG)); | 1424 | memset(remote_list, 0, sizeof(remote_list)); |
| 1425 | 1425 | ||
| 1426 | /* a 0 address marks the end of the valid entries */ | 1426 | /* a 0 address marks the end of the valid entries */ |
| 1427 | if (senddata->addr[startchunk] == 0) | 1427 | if (senddata->addr[startchunk] == 0) |
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 7becff1f387..76b84573566 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c | |||
| @@ -1745,6 +1745,112 @@ jme_phy_off(struct jme_adapter *jme) | |||
| 1745 | } | 1745 | } |
| 1746 | 1746 | ||
| 1747 | static int | 1747 | static int |
| 1748 | jme_phy_specreg_read(struct jme_adapter *jme, u32 specreg) | ||
| 1749 | { | ||
| 1750 | u32 phy_addr; | ||
| 1751 | |||
| 1752 | phy_addr = JM_PHY_SPEC_REG_READ | specreg; | ||
| 1753 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_ADDR_REG, | ||
| 1754 | phy_addr); | ||
| 1755 | return jme_mdio_read(jme->dev, jme->mii_if.phy_id, | ||
| 1756 | JM_PHY_SPEC_DATA_REG); | ||
| 1757 | } | ||
| 1758 | |||
| 1759 | static void | ||
| 1760 | jme_phy_specreg_write(struct jme_adapter *jme, u32 ext_reg, u32 phy_data) | ||
| 1761 | { | ||
| 1762 | u32 phy_addr; | ||
| 1763 | |||
| 1764 | phy_addr = JM_PHY_SPEC_REG_WRITE | ext_reg; | ||
| 1765 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_DATA_REG, | ||
| 1766 | phy_data); | ||
| 1767 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_ADDR_REG, | ||
| 1768 | phy_addr); | ||
| 1769 | } | ||
| 1770 | |||
| 1771 | static int | ||
| 1772 | jme_phy_calibration(struct jme_adapter *jme) | ||
| 1773 | { | ||
| 1774 | u32 ctrl1000, phy_data; | ||
| 1775 | |||
| 1776 | jme_phy_off(jme); | ||
| 1777 | jme_phy_on(jme); | ||
| 1778 | /* Enabel PHY test mode 1 */ | ||
| 1779 | ctrl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000); | ||
| 1780 | ctrl1000 &= ~PHY_GAD_TEST_MODE_MSK; | ||
| 1781 | ctrl1000 |= PHY_GAD_TEST_MODE_1; | ||
| 1782 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, ctrl1000); | ||
| 1783 | |||
| 1784 | phy_data = jme_phy_specreg_read(jme, JM_PHY_EXT_COMM_2_REG); | ||
| 1785 | phy_data &= ~JM_PHY_EXT_COMM_2_CALI_MODE_0; | ||
| 1786 | phy_data |= JM_PHY_EXT_COMM_2_CALI_LATCH | | ||
| 1787 | JM_PHY_EXT_COMM_2_CALI_ENABLE; | ||
| 1788 | jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_2_REG, phy_data); | ||
| 1789 | msleep(20); | ||
| 1790 | phy_data = jme_phy_specreg_read(jme, JM_PHY_EXT_COMM_2_REG); | ||
| 1791 | phy_data &= ~(JM_PHY_EXT_COMM_2_CALI_ENABLE | | ||
| 1792 | JM_PHY_EXT_COMM_2_CALI_MODE_0 | | ||
| 1793 | JM_PHY_EXT_COMM_2_CALI_LATCH); | ||
| 1794 | jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_2_REG, phy_data); | ||
| 1795 | |||
| 1796 | /* Disable PHY test mode */ | ||
| 1797 | ctrl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000); | ||
| 1798 | ctrl1000 &= ~PHY_GAD_TEST_MODE_MSK; | ||
| 1799 | jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, ctrl1000); | ||
| 1800 | return 0; | ||
| 1801 | } | ||
| 1802 | |||
| 1803 | static int | ||
| 1804 | jme_phy_setEA(struct jme_adapter *jme) | ||
| 1805 | { | ||
| 1806 | u32 phy_comm0 = 0, phy_comm1 = 0; | ||
| 1807 | u8 nic_ctrl; | ||
| 1808 | |||
| 1809 | pci_read_config_byte(jme->pdev, PCI_PRIV_SHARE_NICCTRL, &nic_ctrl); | ||
| 1810 | if ((nic_ctrl & 0x3) == JME_FLAG_PHYEA_ENABLE) | ||
| 1811 | return 0; | ||
| 1812 | |||
| 1813 | switch (jme->pdev->device) { | ||
| 1814 | case PCI_DEVICE_ID_JMICRON_JMC250: | ||
| 1815 | if (((jme->chip_main_rev == 5) && | ||
| 1816 | ((jme->chip_sub_rev == 0) || (jme->chip_sub_rev == 1) || | ||
| 1817 | (jme->chip_sub_rev == 3))) || | ||
| 1818 | (jme->chip_main_rev >= 6)) { | ||
| 1819 | phy_comm0 = 0x008A; | ||
| 1820 | phy_comm1 = 0x4109; | ||
| 1821 | } | ||
| 1822 | if ((jme->chip_main_rev == 3) && | ||
| 1823 | ((jme->chip_sub_rev == 1) || (jme->chip_sub_rev == 2))) | ||
| 1824 | phy_comm0 = 0xE088; | ||
| 1825 | break; | ||
| 1826 | case PCI_DEVICE_ID_JMICRON_JMC260: | ||
| 1827 | if (((jme->chip_main_rev == 5) && | ||
| 1828 | ((jme->chip_sub_rev == 0) || (jme->chip_sub_rev == 1) || | ||
| 1829 | (jme->chip_sub_rev == 3))) || | ||
| 1830 | (jme->chip_main_rev >= 6)) { | ||
| 1831 | phy_comm0 = 0x008A; | ||
| 1832 | phy_comm1 = 0x4109; | ||
| 1833 | } | ||
| 1834 | if ((jme->chip_main_rev == 3) && | ||
| 1835 | ((jme->chip_sub_rev == 1) || (jme->chip_sub_rev == 2))) | ||
| 1836 | phy_comm0 = 0xE088; | ||
| 1837 | if ((jme->chip_main_rev == 2) && (jme->chip_sub_rev == 0)) | ||
| 1838 | phy_comm0 = 0x608A; | ||
| 1839 | if ((jme->chip_main_rev == 2) && (jme->chip_sub_rev == 2)) | ||
| 1840 | phy_comm0 = 0x408A; | ||
| 1841 | break; | ||
| 1842 | default: | ||
| 1843 | return -ENODEV; | ||
| 1844 | } | ||
| 1845 | if (phy_comm0) | ||
| 1846 | jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_0_REG, phy_comm0); | ||
| 1847 | if (phy_comm1) | ||
| 1848 | jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_1_REG, phy_comm1); | ||
| 1849 | |||
| 1850 | return 0; | ||
| 1851 | } | ||
| 1852 | |||
| 1853 | static int | ||
| 1748 | jme_open(struct net_device *netdev) | 1854 | jme_open(struct net_device *netdev) |
| 1749 | { | 1855 | { |
| 1750 | struct jme_adapter *jme = netdev_priv(netdev); | 1856 | struct jme_adapter *jme = netdev_priv(netdev); |
| @@ -1769,7 +1875,8 @@ jme_open(struct net_device *netdev) | |||
| 1769 | jme_set_settings(netdev, &jme->old_ecmd); | 1875 | jme_set_settings(netdev, &jme->old_ecmd); |
| 1770 | else | 1876 | else |
| 1771 | jme_reset_phy_processor(jme); | 1877 | jme_reset_phy_processor(jme); |
| 1772 | 1878 | jme_phy_calibration(jme); | |
| 1879 | jme_phy_setEA(jme); | ||
| 1773 | jme_reset_link(jme); | 1880 | jme_reset_link(jme); |
| 1774 | 1881 | ||
| 1775 | return 0; | 1882 | return 0; |
| @@ -3184,7 +3291,8 @@ jme_resume(struct device *dev) | |||
| 3184 | jme_set_settings(netdev, &jme->old_ecmd); | 3291 | jme_set_settings(netdev, &jme->old_ecmd); |
| 3185 | else | 3292 | else |
| 3186 | jme_reset_phy_processor(jme); | 3293 | jme_reset_phy_processor(jme); |
| 3187 | 3294 | jme_phy_calibration(jme); | |
| 3295 | jme_phy_setEA(jme); | ||
| 3188 | jme_start_irq(jme); | 3296 | jme_start_irq(jme); |
| 3189 | netif_device_attach(netdev); | 3297 | netif_device_attach(netdev); |
| 3190 | 3298 | ||
| @@ -3239,4 +3347,3 @@ MODULE_DESCRIPTION("JMicron JMC2x0 PCI Express Ethernet driver"); | |||
| 3239 | MODULE_LICENSE("GPL"); | 3347 | MODULE_LICENSE("GPL"); |
| 3240 | MODULE_VERSION(DRV_VERSION); | 3348 | MODULE_VERSION(DRV_VERSION); |
| 3241 | MODULE_DEVICE_TABLE(pci, jme_pci_tbl); | 3349 | MODULE_DEVICE_TABLE(pci, jme_pci_tbl); |
| 3242 | |||
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h index 02ea27c1dcb..4304072bd3c 100644 --- a/drivers/net/ethernet/jme.h +++ b/drivers/net/ethernet/jme.h | |||
| @@ -760,6 +760,25 @@ enum jme_rxmcs_bits { | |||
| 760 | RXMCS_CHECKSUM, | 760 | RXMCS_CHECKSUM, |
| 761 | }; | 761 | }; |
| 762 | 762 | ||
| 763 | /* Extern PHY common register 2 */ | ||
| 764 | |||
| 765 | #define PHY_GAD_TEST_MODE_1 0x00002000 | ||
| 766 | #define PHY_GAD_TEST_MODE_MSK 0x0000E000 | ||
| 767 | #define JM_PHY_SPEC_REG_READ 0x00004000 | ||
| 768 | #define JM_PHY_SPEC_REG_WRITE 0x00008000 | ||
| 769 | #define PHY_CALIBRATION_DELAY 20 | ||
| 770 | #define JM_PHY_SPEC_ADDR_REG 0x1E | ||
| 771 | #define JM_PHY_SPEC_DATA_REG 0x1F | ||
| 772 | |||
| 773 | #define JM_PHY_EXT_COMM_0_REG 0x30 | ||
| 774 | #define JM_PHY_EXT_COMM_1_REG 0x31 | ||
| 775 | #define JM_PHY_EXT_COMM_2_REG 0x32 | ||
| 776 | #define JM_PHY_EXT_COMM_2_CALI_ENABLE 0x01 | ||
| 777 | #define JM_PHY_EXT_COMM_2_CALI_MODE_0 0x02 | ||
| 778 | #define JM_PHY_EXT_COMM_2_CALI_LATCH 0x10 | ||
| 779 | #define PCI_PRIV_SHARE_NICCTRL 0xF5 | ||
| 780 | #define JME_FLAG_PHYEA_ENABLE 0x2 | ||
| 781 | |||
| 763 | /* | 782 | /* |
| 764 | * Wakeup Frame setup interface registers | 783 | * Wakeup Frame setup interface registers |
| 765 | */ | 784 | */ |
diff --git a/drivers/net/ethernet/pasemi/Makefile b/drivers/net/ethernet/pasemi/Makefile index 05db5434baf..90497ffb1ac 100644 --- a/drivers/net/ethernet/pasemi/Makefile +++ b/drivers/net/ethernet/pasemi/Makefile | |||
| @@ -2,4 +2,5 @@ | |||
| 2 | # Makefile for the A Semi network device drivers. | 2 | # Makefile for the A Semi network device drivers. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o pasemi_mac_ethtool.o | 5 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o |
| 6 | pasemi_mac_driver-objs := pasemi_mac.o pasemi_mac_ethtool.o | ||
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge.h b/drivers/net/ethernet/qlogic/qlge/qlge.h index 8731f79c9ef..b8478aab050 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge.h +++ b/drivers/net/ethernet/qlogic/qlge/qlge.h | |||
| @@ -58,10 +58,8 @@ | |||
| 58 | 58 | ||
| 59 | 59 | ||
| 60 | #define TX_DESC_PER_IOCB 8 | 60 | #define TX_DESC_PER_IOCB 8 |
| 61 | /* The maximum number of frags we handle is based | 61 | |
| 62 | * on PAGE_SIZE... | 62 | #if ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2) > 0 |
| 63 | */ | ||
| 64 | #if (PAGE_SHIFT == 12) || (PAGE_SHIFT == 13) /* 4k & 8k pages */ | ||
| 65 | #define TX_DESC_PER_OAL ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2) | 63 | #define TX_DESC_PER_OAL ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2) |
| 66 | #else /* all other page sizes */ | 64 | #else /* all other page sizes */ |
| 67 | #define TX_DESC_PER_OAL 0 | 65 | #define TX_DESC_PER_OAL 0 |
| @@ -1353,7 +1351,7 @@ struct tx_ring_desc { | |||
| 1353 | struct ob_mac_iocb_req *queue_entry; | 1351 | struct ob_mac_iocb_req *queue_entry; |
| 1354 | u32 index; | 1352 | u32 index; |
| 1355 | struct oal oal; | 1353 | struct oal oal; |
| 1356 | struct map_list map[MAX_SKB_FRAGS + 1]; | 1354 | struct map_list map[MAX_SKB_FRAGS + 2]; |
| 1357 | int map_cnt; | 1355 | int map_cnt; |
| 1358 | struct tx_ring_desc *next; | 1356 | struct tx_ring_desc *next; |
| 1359 | }; | 1357 | }; |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 6f06aa10f0d..67bf0781999 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
| @@ -1183,11 +1183,13 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) | |||
| 1183 | return value; | 1183 | return value; |
| 1184 | } | 1184 | } |
| 1185 | 1185 | ||
| 1186 | static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) | 1186 | static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) |
| 1187 | { | 1187 | { |
| 1188 | RTL_W16(IntrMask, 0x0000); | 1188 | void __iomem *ioaddr = tp->mmio_addr; |
| 1189 | 1189 | ||
| 1190 | RTL_W16(IntrStatus, 0xffff); | 1190 | RTL_W16(IntrMask, 0x0000); |
| 1191 | RTL_W16(IntrStatus, tp->intr_event); | ||
| 1192 | RTL_R8(ChipCmd); | ||
| 1191 | } | 1193 | } |
| 1192 | 1194 | ||
| 1193 | static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) | 1195 | static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp) |
| @@ -3933,8 +3935,6 @@ static void rtl_hw_reset(struct rtl8169_private *tp) | |||
| 3933 | break; | 3935 | break; |
| 3934 | udelay(100); | 3936 | udelay(100); |
| 3935 | } | 3937 | } |
| 3936 | |||
| 3937 | rtl8169_init_ring_indexes(tp); | ||
| 3938 | } | 3938 | } |
| 3939 | 3939 | ||
| 3940 | static int __devinit | 3940 | static int __devinit |
| @@ -4339,7 +4339,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) | |||
| 4339 | void __iomem *ioaddr = tp->mmio_addr; | 4339 | void __iomem *ioaddr = tp->mmio_addr; |
| 4340 | 4340 | ||
| 4341 | /* Disable interrupts */ | 4341 | /* Disable interrupts */ |
| 4342 | rtl8169_irq_mask_and_ack(ioaddr); | 4342 | rtl8169_irq_mask_and_ack(tp); |
| 4343 | 4343 | ||
| 4344 | rtl_rx_close(tp); | 4344 | rtl_rx_close(tp); |
| 4345 | 4345 | ||
| @@ -4885,8 +4885,7 @@ static void rtl_hw_start_8168(struct net_device *dev) | |||
| 4885 | RTL_W16(IntrMitigate, 0x5151); | 4885 | RTL_W16(IntrMitigate, 0x5151); |
| 4886 | 4886 | ||
| 4887 | /* Work around for RxFIFO overflow. */ | 4887 | /* Work around for RxFIFO overflow. */ |
| 4888 | if (tp->mac_version == RTL_GIGA_MAC_VER_11 || | 4888 | if (tp->mac_version == RTL_GIGA_MAC_VER_11) { |
| 4889 | tp->mac_version == RTL_GIGA_MAC_VER_22) { | ||
| 4890 | tp->intr_event |= RxFIFOOver | PCSTimeout; | 4889 | tp->intr_event |= RxFIFOOver | PCSTimeout; |
| 4891 | tp->intr_event &= ~RxOverflow; | 4890 | tp->intr_event &= ~RxOverflow; |
| 4892 | } | 4891 | } |
| @@ -5076,6 +5075,11 @@ static void rtl_hw_start_8101(struct net_device *dev) | |||
| 5076 | void __iomem *ioaddr = tp->mmio_addr; | 5075 | void __iomem *ioaddr = tp->mmio_addr; |
| 5077 | struct pci_dev *pdev = tp->pci_dev; | 5076 | struct pci_dev *pdev = tp->pci_dev; |
| 5078 | 5077 | ||
| 5078 | if (tp->mac_version >= RTL_GIGA_MAC_VER_30) { | ||
| 5079 | tp->intr_event &= ~RxFIFOOver; | ||
| 5080 | tp->napi_event &= ~RxFIFOOver; | ||
| 5081 | } | ||
| 5082 | |||
| 5079 | if (tp->mac_version == RTL_GIGA_MAC_VER_13 || | 5083 | if (tp->mac_version == RTL_GIGA_MAC_VER_13 || |
| 5080 | tp->mac_version == RTL_GIGA_MAC_VER_16) { | 5084 | tp->mac_version == RTL_GIGA_MAC_VER_16) { |
| 5081 | int cap = pci_pcie_cap(pdev); | 5085 | int cap = pci_pcie_cap(pdev); |
| @@ -5342,7 +5346,7 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) | |||
| 5342 | /* Wait for any pending NAPI task to complete */ | 5346 | /* Wait for any pending NAPI task to complete */ |
| 5343 | napi_disable(&tp->napi); | 5347 | napi_disable(&tp->napi); |
| 5344 | 5348 | ||
| 5345 | rtl8169_irq_mask_and_ack(ioaddr); | 5349 | rtl8169_irq_mask_and_ack(tp); |
| 5346 | 5350 | ||
| 5347 | tp->intr_mask = 0xffff; | 5351 | tp->intr_mask = 0xffff; |
| 5348 | RTL_W16(IntrMask, tp->intr_event); | 5352 | RTL_W16(IntrMask, tp->intr_event); |
| @@ -5389,14 +5393,16 @@ static void rtl8169_reset_task(struct work_struct *work) | |||
| 5389 | if (!netif_running(dev)) | 5393 | if (!netif_running(dev)) |
| 5390 | goto out_unlock; | 5394 | goto out_unlock; |
| 5391 | 5395 | ||
| 5396 | rtl8169_hw_reset(tp); | ||
| 5397 | |||
| 5392 | rtl8169_wait_for_quiescence(dev); | 5398 | rtl8169_wait_for_quiescence(dev); |
| 5393 | 5399 | ||
| 5394 | for (i = 0; i < NUM_RX_DESC; i++) | 5400 | for (i = 0; i < NUM_RX_DESC; i++) |
| 5395 | rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz); | 5401 | rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz); |
| 5396 | 5402 | ||
| 5397 | rtl8169_tx_clear(tp); | 5403 | rtl8169_tx_clear(tp); |
| 5404 | rtl8169_init_ring_indexes(tp); | ||
| 5398 | 5405 | ||
| 5399 | rtl8169_hw_reset(tp); | ||
| 5400 | rtl_hw_start(dev); | 5406 | rtl_hw_start(dev); |
| 5401 | netif_wake_queue(dev); | 5407 | netif_wake_queue(dev); |
| 5402 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); | 5408 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); |
| @@ -5407,11 +5413,6 @@ out_unlock: | |||
| 5407 | 5413 | ||
| 5408 | static void rtl8169_tx_timeout(struct net_device *dev) | 5414 | static void rtl8169_tx_timeout(struct net_device *dev) |
| 5409 | { | 5415 | { |
| 5410 | struct rtl8169_private *tp = netdev_priv(dev); | ||
| 5411 | |||
| 5412 | rtl8169_hw_reset(tp); | ||
| 5413 | |||
| 5414 | /* Let's wait a bit while any (async) irq lands on */ | ||
| 5415 | rtl8169_schedule_work(dev, rtl8169_reset_task); | 5416 | rtl8169_schedule_work(dev, rtl8169_reset_task); |
| 5416 | } | 5417 | } |
| 5417 | 5418 | ||
| @@ -5804,6 +5805,10 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
| 5804 | */ | 5805 | */ |
| 5805 | status = RTL_R16(IntrStatus); | 5806 | status = RTL_R16(IntrStatus); |
| 5806 | while (status && status != 0xffff) { | 5807 | while (status && status != 0xffff) { |
| 5808 | status &= tp->intr_event; | ||
| 5809 | if (!status) | ||
| 5810 | break; | ||
| 5811 | |||
| 5807 | handled = 1; | 5812 | handled = 1; |
| 5808 | 5813 | ||
| 5809 | /* Handle all of the error cases first. These will reset | 5814 | /* Handle all of the error cases first. These will reset |
| @@ -5818,27 +5823,9 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
| 5818 | switch (tp->mac_version) { | 5823 | switch (tp->mac_version) { |
| 5819 | /* Work around for rx fifo overflow */ | 5824 | /* Work around for rx fifo overflow */ |
| 5820 | case RTL_GIGA_MAC_VER_11: | 5825 | case RTL_GIGA_MAC_VER_11: |
| 5821 | case RTL_GIGA_MAC_VER_22: | ||
| 5822 | case RTL_GIGA_MAC_VER_26: | ||
| 5823 | netif_stop_queue(dev); | 5826 | netif_stop_queue(dev); |
| 5824 | rtl8169_tx_timeout(dev); | 5827 | rtl8169_tx_timeout(dev); |
| 5825 | goto done; | 5828 | goto done; |
| 5826 | /* Testers needed. */ | ||
| 5827 | case RTL_GIGA_MAC_VER_17: | ||
| 5828 | case RTL_GIGA_MAC_VER_19: | ||
| 5829 | case RTL_GIGA_MAC_VER_20: | ||
| 5830 | case RTL_GIGA_MAC_VER_21: | ||
| 5831 | case RTL_GIGA_MAC_VER_23: | ||
| 5832 | case RTL_GIGA_MAC_VER_24: | ||
| 5833 | case RTL_GIGA_MAC_VER_27: | ||
| 5834 | case RTL_GIGA_MAC_VER_28: | ||
| 5835 | case RTL_GIGA_MAC_VER_31: | ||
| 5836 | /* Experimental science. Pktgen proof. */ | ||
| 5837 | case RTL_GIGA_MAC_VER_12: | ||
| 5838 | case RTL_GIGA_MAC_VER_25: | ||
| 5839 | if (status == RxFIFOOver) | ||
| 5840 | goto done; | ||
| 5841 | break; | ||
| 5842 | default: | 5829 | default: |
| 5843 | break; | 5830 | break; |
| 5844 | } | 5831 | } |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 8ea770a89f2..72cd190b9c1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
| @@ -781,10 +781,15 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv) | |||
| 781 | unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | | 781 | unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET | |
| 782 | MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; | 782 | MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET; |
| 783 | 783 | ||
| 784 | /* Do not manage MMC IRQ (FIXME) */ | 784 | /* Mask MMC irq, counters are managed in SW and registers |
| 785 | * are cleared on each READ eventually. */ | ||
| 785 | dwmac_mmc_intr_all_mask(priv->ioaddr); | 786 | dwmac_mmc_intr_all_mask(priv->ioaddr); |
| 786 | dwmac_mmc_ctrl(priv->ioaddr, mode); | 787 | |
| 787 | memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); | 788 | if (priv->dma_cap.rmon) { |
| 789 | dwmac_mmc_ctrl(priv->ioaddr, mode); | ||
| 790 | memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); | ||
| 791 | } else | ||
| 792 | pr_info(" No MAC Management Counters available"); | ||
| 788 | } | 793 | } |
| 789 | 794 | ||
| 790 | static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) | 795 | static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) |
| @@ -1012,8 +1017,7 @@ static int stmmac_open(struct net_device *dev) | |||
| 1012 | memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); | 1017 | memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats)); |
| 1013 | priv->xstats.threshold = tc; | 1018 | priv->xstats.threshold = tc; |
| 1014 | 1019 | ||
| 1015 | if (priv->dma_cap.rmon) | 1020 | stmmac_mmc_setup(priv); |
| 1016 | stmmac_mmc_setup(priv); | ||
| 1017 | 1021 | ||
| 1018 | /* Start the ball rolling... */ | 1022 | /* Start the ball rolling... */ |
| 1019 | DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); | 1023 | DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); |
diff --git a/drivers/net/ethernet/tile/tilepro.c b/drivers/net/ethernet/tile/tilepro.c index 10826d8a2a2..1187a1169eb 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/phy/Kconfig b/drivers/net/phy/Kconfig index bb88e12101c..a70244306c9 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | menuconfig PHYLIB | 5 | menuconfig PHYLIB |
| 6 | bool "PHY Device support and infrastructure" | 6 | tristate "PHY Device support and infrastructure" |
| 7 | depends on !S390 | 7 | depends on !S390 |
| 8 | depends on NETDEVICES | 8 | depends on NETDEVICES |
| 9 | help | 9 | help |
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index 89f829f5f72..f8a6853b692 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c | |||
| @@ -423,10 +423,8 @@ static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr, | |||
| 423 | lock_sock(sk); | 423 | lock_sock(sk); |
| 424 | 424 | ||
| 425 | opt->src_addr = sp->sa_addr.pptp; | 425 | opt->src_addr = sp->sa_addr.pptp; |
| 426 | if (add_chan(po)) { | 426 | if (add_chan(po)) |
| 427 | release_sock(sk); | ||
| 428 | error = -EBUSY; | 427 | error = -EBUSY; |
| 429 | } | ||
| 430 | 428 | ||
| 431 | release_sock(sk); | 429 | release_sock(sk); |
| 432 | return error; | 430 | return error; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 93fbe6f4089..d2348a5a780 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -286,7 +286,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
| 286 | ath_start_ani(common); | 286 | ath_start_ani(common); |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | if (ath9k_hw_ops(ah)->antdiv_comb_conf_get && sc->ant_rx != 3) { | 289 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx != 3) { |
| 290 | struct ath_hw_antcomb_conf div_ant_conf; | 290 | struct ath_hw_antcomb_conf div_ant_conf; |
| 291 | u8 lna_conf; | 291 | u8 lna_conf; |
| 292 | 292 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index e12b48c2cff..dd008b0e641 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
| @@ -191,6 +191,7 @@ static struct iwl_base_params iwl1000_base_params = { | |||
| 191 | .chain_noise_scale = 1000, | 191 | .chain_noise_scale = 1000, |
| 192 | .wd_timeout = IWL_DEF_WD_TIMEOUT, | 192 | .wd_timeout = IWL_DEF_WD_TIMEOUT, |
| 193 | .max_event_log_size = 128, | 193 | .max_event_log_size = 128, |
| 194 | .wd_disable = true, | ||
| 194 | }; | 195 | }; |
| 195 | static struct iwl_ht_params iwl1000_ht_params = { | 196 | static struct iwl_ht_params iwl1000_ht_params = { |
| 196 | .ht_greenfield_support = true, | 197 | .ht_greenfield_support = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index c511c98a89a..f55fb2d1af5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
| @@ -364,6 +364,7 @@ static struct iwl_base_params iwl5000_base_params = { | |||
| 364 | .wd_timeout = IWL_LONG_WD_TIMEOUT, | 364 | .wd_timeout = IWL_LONG_WD_TIMEOUT, |
| 365 | .max_event_log_size = 512, | 365 | .max_event_log_size = 512, |
| 366 | .no_idle_support = true, | 366 | .no_idle_support = true, |
| 367 | .wd_disable = true, | ||
| 367 | }; | 368 | }; |
| 368 | static struct iwl_ht_params iwl5000_ht_params = { | 369 | static struct iwl_ht_params iwl5000_ht_params = { |
| 369 | .ht_greenfield_support = true, | 370 | .ht_greenfield_support = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 58a381c01c8..a7a6def40d0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
| @@ -528,6 +528,24 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 528 | return 0; | 528 | return 0; |
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | void iwlagn_config_ht40(struct ieee80211_conf *conf, | ||
| 532 | struct iwl_rxon_context *ctx) | ||
| 533 | { | ||
| 534 | if (conf_is_ht40_minus(conf)) { | ||
| 535 | ctx->ht.extension_chan_offset = | ||
| 536 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
| 537 | ctx->ht.is_40mhz = true; | ||
| 538 | } else if (conf_is_ht40_plus(conf)) { | ||
| 539 | ctx->ht.extension_chan_offset = | ||
| 540 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
| 541 | ctx->ht.is_40mhz = true; | ||
| 542 | } else { | ||
| 543 | ctx->ht.extension_chan_offset = | ||
| 544 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
| 545 | ctx->ht.is_40mhz = false; | ||
| 546 | } | ||
| 547 | } | ||
| 548 | |||
| 531 | int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | 549 | int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) |
| 532 | { | 550 | { |
| 533 | struct iwl_priv *priv = hw->priv; | 551 | struct iwl_priv *priv = hw->priv; |
| @@ -586,19 +604,11 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
| 586 | ctx->ht.enabled = conf_is_ht(conf); | 604 | ctx->ht.enabled = conf_is_ht(conf); |
| 587 | 605 | ||
| 588 | if (ctx->ht.enabled) { | 606 | if (ctx->ht.enabled) { |
| 589 | if (conf_is_ht40_minus(conf)) { | 607 | /* if HT40 is used, it should not change |
| 590 | ctx->ht.extension_chan_offset = | 608 | * after associated except channel switch */ |
| 591 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | 609 | if (iwl_is_associated_ctx(ctx) && |
| 592 | ctx->ht.is_40mhz = true; | 610 | !ctx->ht.is_40mhz) |
| 593 | } else if (conf_is_ht40_plus(conf)) { | 611 | iwlagn_config_ht40(conf, ctx); |
| 594 | ctx->ht.extension_chan_offset = | ||
| 595 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
| 596 | ctx->ht.is_40mhz = true; | ||
| 597 | } else { | ||
| 598 | ctx->ht.extension_chan_offset = | ||
| 599 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
| 600 | ctx->ht.is_40mhz = false; | ||
| 601 | } | ||
| 602 | } else | 612 | } else |
| 603 | ctx->ht.is_40mhz = false; | 613 | ctx->ht.is_40mhz = false; |
| 604 | 614 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index ed628362393..4b2aa1da095 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
| @@ -1268,9 +1268,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
| 1268 | 1268 | ||
| 1269 | switch (keyconf->cipher) { | 1269 | switch (keyconf->cipher) { |
| 1270 | case WLAN_CIPHER_SUITE_TKIP: | 1270 | case WLAN_CIPHER_SUITE_TKIP: |
| 1271 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
| 1272 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
| 1273 | |||
| 1274 | if (sta) | 1271 | if (sta) |
| 1275 | addr = sta->addr; | 1272 | addr = sta->addr; |
| 1276 | else /* station mode case only */ | 1273 | else /* station mode case only */ |
| @@ -1283,8 +1280,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, | |||
| 1283 | seq.tkip.iv32, p1k, CMD_SYNC); | 1280 | seq.tkip.iv32, p1k, CMD_SYNC); |
| 1284 | break; | 1281 | break; |
| 1285 | case WLAN_CIPHER_SUITE_CCMP: | 1282 | case WLAN_CIPHER_SUITE_CCMP: |
| 1286 | keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
| 1287 | /* fall through */ | ||
| 1288 | case WLAN_CIPHER_SUITE_WEP40: | 1283 | case WLAN_CIPHER_SUITE_WEP40: |
| 1289 | case WLAN_CIPHER_SUITE_WEP104: | 1284 | case WLAN_CIPHER_SUITE_WEP104: |
| 1290 | ret = iwlagn_send_sta_key(priv, keyconf, sta_id, | 1285 | ret = iwlagn_send_sta_key(priv, keyconf, sta_id, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ccba69b7f8a..bacc06c95e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
| @@ -2316,6 +2316,17 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
| 2316 | return -EOPNOTSUPP; | 2316 | return -EOPNOTSUPP; |
| 2317 | } | 2317 | } |
| 2318 | 2318 | ||
| 2319 | switch (key->cipher) { | ||
| 2320 | case WLAN_CIPHER_SUITE_TKIP: | ||
| 2321 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
| 2322 | /* fall through */ | ||
| 2323 | case WLAN_CIPHER_SUITE_CCMP: | ||
| 2324 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
| 2325 | break; | ||
| 2326 | default: | ||
| 2327 | break; | ||
| 2328 | } | ||
| 2329 | |||
| 2319 | /* | 2330 | /* |
| 2320 | * We could program these keys into the hardware as well, but we | 2331 | * We could program these keys into the hardware as well, but we |
| 2321 | * don't expect much multicast traffic in IBSS and having keys | 2332 | * don't expect much multicast traffic in IBSS and having keys |
| @@ -2599,21 +2610,9 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 2599 | 2610 | ||
| 2600 | /* Configure HT40 channels */ | 2611 | /* Configure HT40 channels */ |
| 2601 | ctx->ht.enabled = conf_is_ht(conf); | 2612 | ctx->ht.enabled = conf_is_ht(conf); |
| 2602 | if (ctx->ht.enabled) { | 2613 | if (ctx->ht.enabled) |
| 2603 | if (conf_is_ht40_minus(conf)) { | 2614 | iwlagn_config_ht40(conf, ctx); |
| 2604 | ctx->ht.extension_chan_offset = | 2615 | else |
| 2605 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
| 2606 | ctx->ht.is_40mhz = true; | ||
| 2607 | } else if (conf_is_ht40_plus(conf)) { | ||
| 2608 | ctx->ht.extension_chan_offset = | ||
| 2609 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
| 2610 | ctx->ht.is_40mhz = true; | ||
| 2611 | } else { | ||
| 2612 | ctx->ht.extension_chan_offset = | ||
| 2613 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
| 2614 | ctx->ht.is_40mhz = false; | ||
| 2615 | } | ||
| 2616 | } else | ||
| 2617 | ctx->ht.is_40mhz = false; | 2616 | ctx->ht.is_40mhz = false; |
| 2618 | 2617 | ||
| 2619 | if ((le16_to_cpu(ctx->staging.channel) != ch)) | 2618 | if ((le16_to_cpu(ctx->staging.channel) != ch)) |
| @@ -3499,9 +3498,10 @@ MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])"); | |||
| 3499 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); | 3498 | module_param_named(ack_check, iwlagn_mod_params.ack_check, bool, S_IRUGO); |
| 3500 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); | 3499 | MODULE_PARM_DESC(ack_check, "Check ack health (default: 0 [disabled])"); |
| 3501 | 3500 | ||
| 3502 | module_param_named(wd_disable, iwlagn_mod_params.wd_disable, bool, S_IRUGO); | 3501 | module_param_named(wd_disable, iwlagn_mod_params.wd_disable, int, S_IRUGO); |
| 3503 | MODULE_PARM_DESC(wd_disable, | 3502 | MODULE_PARM_DESC(wd_disable, |
| 3504 | "Disable stuck queue watchdog timer (default: 0 [enabled])"); | 3503 | "Disable stuck queue watchdog timer 0=system default, " |
| 3504 | "1=disable, 2=enable (default: 0)"); | ||
| 3505 | 3505 | ||
| 3506 | /* | 3506 | /* |
| 3507 | * set bt_coex_active to true, uCode will do kill/defer | 3507 | * set bt_coex_active to true, uCode will do kill/defer |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 5b936ec1a54..3856abaea50 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h | |||
| @@ -86,6 +86,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
| 86 | struct ieee80211_vif *vif, | 86 | struct ieee80211_vif *vif, |
| 87 | struct ieee80211_bss_conf *bss_conf, | 87 | struct ieee80211_bss_conf *bss_conf, |
| 88 | u32 changes); | 88 | u32 changes); |
| 89 | void iwlagn_config_ht40(struct ieee80211_conf *conf, | ||
| 90 | struct iwl_rxon_context *ctx); | ||
| 89 | 91 | ||
| 90 | /* uCode */ | 92 | /* uCode */ |
| 91 | int iwlagn_rx_calib_result(struct iwl_priv *priv, | 93 | int iwlagn_rx_calib_result(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 001fdf140ab..fcf54160e4e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
| @@ -1810,11 +1810,23 @@ void iwl_setup_watchdog(struct iwl_priv *priv) | |||
| 1810 | { | 1810 | { |
| 1811 | unsigned int timeout = priv->cfg->base_params->wd_timeout; | 1811 | unsigned int timeout = priv->cfg->base_params->wd_timeout; |
| 1812 | 1812 | ||
| 1813 | if (timeout && !iwlagn_mod_params.wd_disable) | 1813 | if (!iwlagn_mod_params.wd_disable) { |
| 1814 | mod_timer(&priv->watchdog, | 1814 | /* use system default */ |
| 1815 | jiffies + msecs_to_jiffies(IWL_WD_TICK(timeout))); | 1815 | if (timeout && !priv->cfg->base_params->wd_disable) |
| 1816 | else | 1816 | mod_timer(&priv->watchdog, |
| 1817 | del_timer(&priv->watchdog); | 1817 | jiffies + |
| 1818 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | ||
| 1819 | else | ||
| 1820 | del_timer(&priv->watchdog); | ||
| 1821 | } else { | ||
| 1822 | /* module parameter overwrite default configuration */ | ||
| 1823 | if (timeout && iwlagn_mod_params.wd_disable == 2) | ||
| 1824 | mod_timer(&priv->watchdog, | ||
| 1825 | jiffies + | ||
| 1826 | msecs_to_jiffies(IWL_WD_TICK(timeout))); | ||
| 1827 | else | ||
| 1828 | del_timer(&priv->watchdog); | ||
| 1829 | } | ||
| 1818 | } | 1830 | } |
| 1819 | 1831 | ||
| 1820 | /** | 1832 | /** |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 137da338070..f2fc288f3dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
| @@ -113,6 +113,7 @@ struct iwl_lib_ops { | |||
| 113 | * @shadow_reg_enable: HW shadhow register bit | 113 | * @shadow_reg_enable: HW shadhow register bit |
| 114 | * @no_idle_support: do not support idle mode | 114 | * @no_idle_support: do not support idle mode |
| 115 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up | 115 | * @hd_v2: v2 of enhanced sensitivity value, used for 2000 series and up |
| 116 | * wd_disable: disable watchdog timer | ||
| 116 | */ | 117 | */ |
| 117 | struct iwl_base_params { | 118 | struct iwl_base_params { |
| 118 | int eeprom_size; | 119 | int eeprom_size; |
| @@ -134,6 +135,7 @@ struct iwl_base_params { | |||
| 134 | const bool shadow_reg_enable; | 135 | const bool shadow_reg_enable; |
| 135 | const bool no_idle_support; | 136 | const bool no_idle_support; |
| 136 | const bool hd_v2; | 137 | const bool hd_v2; |
| 138 | const bool wd_disable; | ||
| 137 | }; | 139 | }; |
| 138 | /* | 140 | /* |
| 139 | * @advanced_bt_coexist: support advanced bt coexist | 141 | * @advanced_bt_coexist: support advanced bt coexist |
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 1f7a93c67c4..14eaf37ce3b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h | |||
| @@ -120,7 +120,7 @@ extern struct iwl_mod_params iwlagn_mod_params; | |||
| 120 | * @restart_fw: restart firmware, default = 1 | 120 | * @restart_fw: restart firmware, default = 1 |
| 121 | * @plcp_check: enable plcp health check, default = true | 121 | * @plcp_check: enable plcp health check, default = true |
| 122 | * @ack_check: disable ack health check, default = false | 122 | * @ack_check: disable ack health check, default = false |
| 123 | * @wd_disable: enable stuck queue check, default = false | 123 | * @wd_disable: enable stuck queue check, default = 0 |
| 124 | * @bt_coex_active: enable bt coex, default = true | 124 | * @bt_coex_active: enable bt coex, default = true |
| 125 | * @led_mode: system default, default = 0 | 125 | * @led_mode: system default, default = 0 |
| 126 | * @no_sleep_autoadjust: disable autoadjust, default = true | 126 | * @no_sleep_autoadjust: disable autoadjust, default = true |
| @@ -141,7 +141,7 @@ struct iwl_mod_params { | |||
| 141 | int restart_fw; | 141 | int restart_fw; |
| 142 | bool plcp_check; | 142 | bool plcp_check; |
| 143 | bool ack_check; | 143 | bool ack_check; |
| 144 | bool wd_disable; | 144 | int wd_disable; |
| 145 | bool bt_coex_active; | 145 | bool bt_coex_active; |
| 146 | int led_mode; | 146 | int led_mode; |
| 147 | bool no_sleep_autoadjust; | 147 | bool no_sleep_autoadjust; |
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index f18df82eeb9..78d0d698855 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c | |||
| @@ -588,8 +588,6 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) | |||
| 588 | 588 | ||
| 589 | WARN_ON(priv->fw_state != FW_STATE_READY); | 589 | WARN_ON(priv->fw_state != FW_STATE_READY); |
| 590 | 590 | ||
| 591 | cancel_work_sync(&priv->work); | ||
| 592 | |||
| 593 | p54spi_power_off(priv); | 591 | p54spi_power_off(priv); |
| 594 | spin_lock_irqsave(&priv->tx_lock, flags); | 592 | spin_lock_irqsave(&priv->tx_lock, flags); |
| 595 | INIT_LIST_HEAD(&priv->tx_pending); | 593 | INIT_LIST_HEAD(&priv->tx_pending); |
| @@ -597,6 +595,8 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) | |||
| 597 | 595 | ||
| 598 | priv->fw_state = FW_STATE_OFF; | 596 | priv->fw_state = FW_STATE_OFF; |
| 599 | mutex_unlock(&priv->mutex); | 597 | mutex_unlock(&priv->mutex); |
| 598 | |||
| 599 | cancel_work_sync(&priv->work); | ||
| 600 | } | 600 | } |
| 601 | 601 | ||
| 602 | static int __devinit p54spi_probe(struct spi_device *spi) | 602 | static int __devinit p54spi_probe(struct spi_device *spi) |
| @@ -656,6 +656,7 @@ static int __devinit p54spi_probe(struct spi_device *spi) | |||
| 656 | init_completion(&priv->fw_comp); | 656 | init_completion(&priv->fw_comp); |
| 657 | INIT_LIST_HEAD(&priv->tx_pending); | 657 | INIT_LIST_HEAD(&priv->tx_pending); |
| 658 | mutex_init(&priv->mutex); | 658 | mutex_init(&priv->mutex); |
| 659 | spin_lock_init(&priv->tx_lock); | ||
| 659 | SET_IEEE80211_DEV(hw, &spi->dev); | 660 | SET_IEEE80211_DEV(hw, &spi->dev); |
| 660 | priv->common.open = p54spi_op_start; | 661 | priv->common.open = p54spi_op_start; |
| 661 | priv->common.stop = p54spi_op_stop; | 662 | priv->common.stop = p54spi_op_stop; |
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index d97a2caf582..bc2ba80c47b 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
| @@ -778,7 +778,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info, | |||
| 778 | dwrq->flags = 0; | 778 | dwrq->flags = 0; |
| 779 | dwrq->length = 0; | 779 | dwrq->length = 0; |
| 780 | } | 780 | } |
| 781 | essid->octets[essid->length] = '\0'; | 781 | essid->octets[dwrq->length] = '\0'; |
| 782 | memcpy(extra, essid->octets, dwrq->length); | 782 | memcpy(extra, essid->octets, dwrq->length); |
| 783 | kfree(essid); | 783 | kfree(essid); |
| 784 | 784 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 3f183a15186..1ba079dffb1 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
| @@ -3771,7 +3771,7 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) | |||
| 3771 | /* Apparently the data is read from end to start */ | 3771 | /* Apparently the data is read from end to start */ |
| 3772 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®); | 3772 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®); |
| 3773 | /* The returned value is in CPU order, but eeprom is le */ | 3773 | /* The returned value is in CPU order, but eeprom is le */ |
| 3774 | rt2x00dev->eeprom[i] = cpu_to_le32(reg); | 3774 | *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg); |
| 3775 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®); | 3775 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®); |
| 3776 | *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); | 3776 | *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); |
| 3777 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®); | 3777 | rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®); |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index db526284454..55c8e50f45f 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
| @@ -395,7 +395,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
| 395 | if (mac->link_state != MAC80211_LINKED) | 395 | if (mac->link_state != MAC80211_LINKED) |
| 396 | return; | 396 | return; |
| 397 | 397 | ||
| 398 | spin_lock(&rtlpriv->locks.lps_lock); | 398 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
| 399 | 399 | ||
| 400 | /* Idle for a while if we connect to AP a while ago. */ | 400 | /* Idle for a while if we connect to AP a while ago. */ |
| 401 | if (mac->cnt_after_linked >= 2) { | 401 | if (mac->cnt_after_linked >= 2) { |
| @@ -407,7 +407,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
| 407 | } | 407 | } |
| 408 | } | 408 | } |
| 409 | 409 | ||
| 410 | spin_unlock(&rtlpriv->locks.lps_lock); | 410 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
| 411 | } | 411 | } |
| 412 | 412 | ||
| 413 | /*Leave the leisure power save mode.*/ | 413 | /*Leave the leisure power save mode.*/ |
| @@ -416,8 +416,9 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
| 416 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 416 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 417 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 417 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
| 418 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 418 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
| 419 | unsigned long flags; | ||
| 419 | 420 | ||
| 420 | spin_lock(&rtlpriv->locks.lps_lock); | 421 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flags); |
| 421 | 422 | ||
| 422 | if (ppsc->fwctrl_lps) { | 423 | if (ppsc->fwctrl_lps) { |
| 423 | if (ppsc->dot11_psmode != EACTIVE) { | 424 | if (ppsc->dot11_psmode != EACTIVE) { |
| @@ -438,7 +439,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
| 438 | rtl_lps_set_psmode(hw, EACTIVE); | 439 | rtl_lps_set_psmode(hw, EACTIVE); |
| 439 | } | 440 | } |
| 440 | } | 441 | } |
| 441 | spin_unlock(&rtlpriv->locks.lps_lock); | 442 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flags); |
| 442 | } | 443 | } |
| 443 | 444 | ||
| 444 | /* For sw LPS*/ | 445 | /* For sw LPS*/ |
| @@ -539,9 +540,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | |||
| 539 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); | 540 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); |
| 540 | } | 541 | } |
| 541 | 542 | ||
| 542 | spin_lock(&rtlpriv->locks.lps_lock); | 543 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
| 543 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); | 544 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS); |
| 544 | spin_unlock(&rtlpriv->locks.lps_lock); | 545 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
| 545 | } | 546 | } |
| 546 | 547 | ||
| 547 | void rtl_swlps_rfon_wq_callback(void *data) | 548 | void rtl_swlps_rfon_wq_callback(void *data) |
| @@ -574,9 +575,9 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) | |||
| 574 | if (rtlpriv->link_info.busytraffic) | 575 | if (rtlpriv->link_info.busytraffic) |
| 575 | return; | 576 | return; |
| 576 | 577 | ||
| 577 | spin_lock(&rtlpriv->locks.lps_lock); | 578 | spin_lock_irq(&rtlpriv->locks.lps_lock); |
| 578 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); | 579 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS); |
| 579 | spin_unlock(&rtlpriv->locks.lps_lock); | 580 | spin_unlock_irq(&rtlpriv->locks.lps_lock); |
| 580 | 581 | ||
| 581 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && | 582 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && |
| 582 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { | 583 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 592a10ac592..3b585aadabf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | |||
| @@ -569,7 +569,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
| 569 | } | 569 | } |
| 570 | case ERFSLEEP:{ | 570 | case ERFSLEEP:{ |
| 571 | if (ppsc->rfpwr_state == ERFOFF) | 571 | if (ppsc->rfpwr_state == ERFOFF) |
| 572 | break; | 572 | return false; |
| 573 | for (queue_id = 0, i = 0; | 573 | for (queue_id = 0, i = 0; |
| 574 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | 574 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { |
| 575 | ring = &pcipriv->dev.tx_ring[queue_id]; | 575 | ring = &pcipriv->dev.tx_ring[queue_id]; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index 72852900df8..e49cf2244c7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | |||
| @@ -548,7 +548,7 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
| 548 | break; | 548 | break; |
| 549 | case ERFSLEEP: | 549 | case ERFSLEEP: |
| 550 | if (ppsc->rfpwr_state == ERFOFF) | 550 | if (ppsc->rfpwr_state == ERFOFF) |
| 551 | break; | 551 | return false; |
| 552 | for (queue_id = 0, i = 0; | 552 | for (queue_id = 0, i = 0; |
| 553 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | 553 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { |
| 554 | ring = &pcipriv->dev.tx_ring[queue_id]; | 554 | ring = &pcipriv->dev.tx_ring[queue_id]; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 3ac7af1c550..0883349e1c8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c | |||
| @@ -3374,7 +3374,7 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
| 3374 | break; | 3374 | break; |
| 3375 | case ERFSLEEP: | 3375 | case ERFSLEEP: |
| 3376 | if (ppsc->rfpwr_state == ERFOFF) | 3376 | if (ppsc->rfpwr_state == ERFOFF) |
| 3377 | break; | 3377 | return false; |
| 3378 | 3378 | ||
| 3379 | for (queue_id = 0, i = 0; | 3379 | for (queue_id = 0, i = 0; |
| 3380 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | 3380 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index f27171af979..f10ac1ad908 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c | |||
| @@ -602,7 +602,7 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
| 602 | } | 602 | } |
| 603 | case ERFSLEEP: | 603 | case ERFSLEEP: |
| 604 | if (ppsc->rfpwr_state == ERFOFF) | 604 | if (ppsc->rfpwr_state == ERFOFF) |
| 605 | break; | 605 | return false; |
| 606 | 606 | ||
| 607 | for (queue_id = 0, i = 0; | 607 | for (queue_id = 0, i = 0; |
| 608 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | 608 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 0cb594c8609..15e332d08c8 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
| @@ -1021,7 +1021,7 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, | |||
| 1021 | pending_idx = *((u16 *)skb->data); | 1021 | pending_idx = *((u16 *)skb->data); |
| 1022 | xen_netbk_idx_release(netbk, pending_idx); | 1022 | xen_netbk_idx_release(netbk, pending_idx); |
| 1023 | for (j = start; j < i; j++) { | 1023 | for (j = start; j < i; j++) { |
| 1024 | pending_idx = frag_get_pending_idx(&shinfo->frags[i]); | 1024 | pending_idx = frag_get_pending_idx(&shinfo->frags[j]); |
| 1025 | xen_netbk_idx_release(netbk, pending_idx); | 1025 | xen_netbk_idx_release(netbk, pending_idx); |
| 1026 | } | 1026 | } |
| 1027 | 1027 | ||
| @@ -1668,7 +1668,7 @@ static int __init netback_init(void) | |||
| 1668 | "netback/%u", group); | 1668 | "netback/%u", group); |
| 1669 | 1669 | ||
| 1670 | if (IS_ERR(netbk->task)) { | 1670 | if (IS_ERR(netbk->task)) { |
| 1671 | printk(KERN_ALERT "kthread_run() fails at netback\n"); | 1671 | printk(KERN_ALERT "kthread_create() fails at netback\n"); |
| 1672 | del_timer(&netbk->net_timer); | 1672 | del_timer(&netbk->net_timer); |
| 1673 | rc = PTR_ERR(netbk->task); | 1673 | rc = PTR_ERR(netbk->task); |
| 1674 | goto failed_init; | 1674 | goto failed_init; |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 19c0115092d..0f0cfa3bca3 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/oprof.c b/drivers/oprofile/oprof.c index dccd8636095..f8c752e408a 100644 --- a/drivers/oprofile/oprof.c +++ b/drivers/oprofile/oprof.c | |||
| @@ -239,26 +239,45 @@ int oprofile_set_ulong(unsigned long *addr, unsigned long val) | |||
| 239 | return err; | 239 | return err; |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | static int timer_mode; | ||
| 243 | |||
| 242 | static int __init oprofile_init(void) | 244 | static int __init oprofile_init(void) |
| 243 | { | 245 | { |
| 244 | int err; | 246 | int err; |
| 245 | 247 | ||
| 248 | /* always init architecture to setup backtrace support */ | ||
| 246 | err = oprofile_arch_init(&oprofile_ops); | 249 | err = oprofile_arch_init(&oprofile_ops); |
| 247 | if (err < 0 || timer) { | 250 | |
| 248 | printk(KERN_INFO "oprofile: using timer interrupt.\n"); | 251 | timer_mode = err || timer; /* fall back to timer mode on errors */ |
| 252 | if (timer_mode) { | ||
| 253 | if (!err) | ||
| 254 | oprofile_arch_exit(); | ||
| 249 | err = oprofile_timer_init(&oprofile_ops); | 255 | err = oprofile_timer_init(&oprofile_ops); |
| 250 | if (err) | 256 | if (err) |
| 251 | return err; | 257 | return err; |
| 252 | } | 258 | } |
| 253 | return oprofilefs_register(); | 259 | |
| 260 | err = oprofilefs_register(); | ||
| 261 | if (!err) | ||
| 262 | return 0; | ||
| 263 | |||
| 264 | /* failed */ | ||
| 265 | if (timer_mode) | ||
| 266 | oprofile_timer_exit(); | ||
| 267 | else | ||
| 268 | oprofile_arch_exit(); | ||
| 269 | |||
| 270 | return err; | ||
| 254 | } | 271 | } |
| 255 | 272 | ||
| 256 | 273 | ||
| 257 | static void __exit oprofile_exit(void) | 274 | static void __exit oprofile_exit(void) |
| 258 | { | 275 | { |
| 259 | oprofile_timer_exit(); | ||
| 260 | oprofilefs_unregister(); | 276 | oprofilefs_unregister(); |
| 261 | oprofile_arch_exit(); | 277 | if (timer_mode) |
| 278 | oprofile_timer_exit(); | ||
| 279 | else | ||
| 280 | oprofile_arch_exit(); | ||
| 262 | } | 281 | } |
| 263 | 282 | ||
| 264 | 283 | ||
diff --git a/drivers/oprofile/timer_int.c b/drivers/oprofile/timer_int.c index 3ef44624f51..878fba12658 100644 --- a/drivers/oprofile/timer_int.c +++ b/drivers/oprofile/timer_int.c | |||
| @@ -110,6 +110,7 @@ int oprofile_timer_init(struct oprofile_operations *ops) | |||
| 110 | ops->start = oprofile_hrtimer_start; | 110 | ops->start = oprofile_hrtimer_start; |
| 111 | ops->stop = oprofile_hrtimer_stop; | 111 | ops->stop = oprofile_hrtimer_stop; |
| 112 | ops->cpu_type = "timer"; | 112 | ops->cpu_type = "timer"; |
| 113 | printk(KERN_INFO "oprofile: using timer interrupt.\n"); | ||
| 113 | return 0; | 114 | return 0; |
| 114 | } | 115 | } |
| 115 | 116 | ||
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 13ef8c37471..dcdc1f4a462 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
| @@ -121,6 +121,7 @@ struct toshiba_acpi_dev { | |||
| 121 | int illumination_supported:1; | 121 | int illumination_supported:1; |
| 122 | int video_supported:1; | 122 | int video_supported:1; |
| 123 | int fan_supported:1; | 123 | int fan_supported:1; |
| 124 | int system_event_supported:1; | ||
| 124 | 125 | ||
| 125 | struct mutex mutex; | 126 | struct mutex mutex; |
| 126 | }; | 127 | }; |
| @@ -724,7 +725,7 @@ static int keys_proc_show(struct seq_file *m, void *v) | |||
| 724 | u32 hci_result; | 725 | u32 hci_result; |
| 725 | u32 value; | 726 | u32 value; |
| 726 | 727 | ||
| 727 | if (!dev->key_event_valid) { | 728 | if (!dev->key_event_valid && dev->system_event_supported) { |
| 728 | hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); | 729 | hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); |
| 729 | if (hci_result == HCI_SUCCESS) { | 730 | if (hci_result == HCI_SUCCESS) { |
| 730 | dev->key_event_valid = 1; | 731 | dev->key_event_valid = 1; |
| @@ -964,6 +965,8 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
| 964 | 965 | ||
| 965 | /* enable event fifo */ | 966 | /* enable event fifo */ |
| 966 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); | 967 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); |
| 968 | if (hci_result == HCI_SUCCESS) | ||
| 969 | dev->system_event_supported = 1; | ||
| 967 | 970 | ||
| 968 | props.type = BACKLIGHT_PLATFORM; | 971 | props.type = BACKLIGHT_PLATFORM; |
| 969 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; | 972 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; |
| @@ -1032,12 +1035,15 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) | |||
| 1032 | { | 1035 | { |
| 1033 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); | 1036 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); |
| 1034 | u32 hci_result, value; | 1037 | u32 hci_result, value; |
| 1038 | int retries = 3; | ||
| 1035 | 1039 | ||
| 1036 | if (event != 0x80) | 1040 | if (!dev->system_event_supported || event != 0x80) |
| 1037 | return; | 1041 | return; |
| 1042 | |||
| 1038 | do { | 1043 | do { |
| 1039 | hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); | 1044 | hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); |
| 1040 | if (hci_result == HCI_SUCCESS) { | 1045 | switch (hci_result) { |
| 1046 | case HCI_SUCCESS: | ||
| 1041 | if (value == 0x100) | 1047 | if (value == 0x100) |
| 1042 | continue; | 1048 | continue; |
| 1043 | /* act on key press; ignore key release */ | 1049 | /* act on key press; ignore key release */ |
| @@ -1049,14 +1055,19 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) | |||
| 1049 | pr_info("Unknown key %x\n", | 1055 | pr_info("Unknown key %x\n", |
| 1050 | value); | 1056 | value); |
| 1051 | } | 1057 | } |
| 1052 | } else if (hci_result == HCI_NOT_SUPPORTED) { | 1058 | break; |
| 1059 | case HCI_NOT_SUPPORTED: | ||
| 1053 | /* This is a workaround for an unresolved issue on | 1060 | /* This is a workaround for an unresolved issue on |
| 1054 | * some machines where system events sporadically | 1061 | * some machines where system events sporadically |
| 1055 | * become disabled. */ | 1062 | * become disabled. */ |
| 1056 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); | 1063 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); |
| 1057 | pr_notice("Re-enabled hotkeys\n"); | 1064 | pr_notice("Re-enabled hotkeys\n"); |
| 1065 | /* fall through */ | ||
| 1066 | default: | ||
| 1067 | retries--; | ||
| 1068 | break; | ||
| 1058 | } | 1069 | } |
| 1059 | } while (hci_result != HCI_EMPTY); | 1070 | } while (retries && hci_result != HCI_EMPTY); |
| 1060 | } | 1071 | } |
| 1061 | 1072 | ||
| 1062 | 1073 | ||
diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c index cffcb7c00b0..01fa671ec97 100644 --- a/drivers/power/intel_mid_battery.c +++ b/drivers/power/intel_mid_battery.c | |||
| @@ -61,7 +61,8 @@ MODULE_PARM_DESC(debug, "Flag to enable PMIC Battery debug messages."); | |||
| 61 | #define PMIC_BATT_CHR_SBATDET_MASK (1 << 5) | 61 | #define PMIC_BATT_CHR_SBATDET_MASK (1 << 5) |
| 62 | #define PMIC_BATT_CHR_SDCLMT_MASK (1 << 6) | 62 | #define PMIC_BATT_CHR_SDCLMT_MASK (1 << 6) |
| 63 | #define PMIC_BATT_CHR_SUSBOVP_MASK (1 << 7) | 63 | #define PMIC_BATT_CHR_SUSBOVP_MASK (1 << 7) |
| 64 | #define PMIC_BATT_CHR_EXCPT_MASK 0xC6 | 64 | #define PMIC_BATT_CHR_EXCPT_MASK 0x86 |
| 65 | |||
| 65 | #define PMIC_BATT_ADC_ACCCHRG_MASK (1 << 31) | 66 | #define PMIC_BATT_ADC_ACCCHRG_MASK (1 << 31) |
| 66 | #define PMIC_BATT_ADC_ACCCHRGVAL_MASK 0x7FFFFFFF | 67 | #define PMIC_BATT_ADC_ACCCHRGVAL_MASK 0x7FFFFFFF |
| 67 | 68 | ||
| @@ -304,11 +305,6 @@ static void pmic_battery_read_status(struct pmic_power_module_info *pbi) | |||
| 304 | pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING; | 305 | pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING; |
| 305 | pmic_battery_log_event(BATT_EVENT_BATOVP_EXCPT); | 306 | pmic_battery_log_event(BATT_EVENT_BATOVP_EXCPT); |
| 306 | batt_exception = 1; | 307 | batt_exception = 1; |
| 307 | } else if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) { | ||
| 308 | pbi->batt_health = POWER_SUPPLY_HEALTH_OVERVOLTAGE; | ||
| 309 | pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING; | ||
| 310 | pmic_battery_log_event(BATT_EVENT_DCLMT_EXCPT); | ||
| 311 | batt_exception = 1; | ||
| 312 | } else if (r8 & PMIC_BATT_CHR_STEMP_MASK) { | 308 | } else if (r8 & PMIC_BATT_CHR_STEMP_MASK) { |
| 313 | pbi->batt_health = POWER_SUPPLY_HEALTH_OVERHEAT; | 309 | pbi->batt_health = POWER_SUPPLY_HEALTH_OVERHEAT; |
| 314 | pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING; | 310 | pbi->batt_status = POWER_SUPPLY_STATUS_NOT_CHARGING; |
| @@ -316,6 +312,10 @@ static void pmic_battery_read_status(struct pmic_power_module_info *pbi) | |||
| 316 | batt_exception = 1; | 312 | batt_exception = 1; |
| 317 | } else { | 313 | } else { |
| 318 | pbi->batt_health = POWER_SUPPLY_HEALTH_GOOD; | 314 | pbi->batt_health = POWER_SUPPLY_HEALTH_GOOD; |
| 315 | if (r8 & PMIC_BATT_CHR_SDCLMT_MASK) { | ||
| 316 | /* PMIC will change charging current automatically */ | ||
| 317 | pmic_battery_log_event(BATT_EVENT_DCLMT_EXCPT); | ||
| 318 | } | ||
| 319 | } | 319 | } |
| 320 | } | 320 | } |
| 321 | 321 | ||
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index cf3f9997546..10451a15e82 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 5225930a10c..691b1ab1a3d 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 58be4deb140..822e54c394d 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/class.c b/drivers/rtc/class.c index e8326f26fa2..dc4c2748bbc 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
| @@ -63,7 +63,7 @@ static int rtc_suspend(struct device *dev, pm_message_t mesg) | |||
| 63 | */ | 63 | */ |
| 64 | delta = timespec_sub(old_system, old_rtc); | 64 | delta = timespec_sub(old_system, old_rtc); |
| 65 | delta_delta = timespec_sub(delta, old_delta); | 65 | delta_delta = timespec_sub(delta, old_delta); |
| 66 | if (abs(delta_delta.tv_sec) >= 2) { | 66 | if (delta_delta.tv_sec < -2 || delta_delta.tv_sec >= 2) { |
| 67 | /* | 67 | /* |
| 68 | * if delta_delta is too large, assume time correction | 68 | * if delta_delta is too large, assume time correction |
| 69 | * has occured and set old_delta to the current delta. | 69 | * has occured and set old_delta to the current delta. |
| @@ -97,9 +97,8 @@ static int rtc_resume(struct device *dev) | |||
| 97 | rtc_tm_to_time(&tm, &new_rtc.tv_sec); | 97 | rtc_tm_to_time(&tm, &new_rtc.tv_sec); |
| 98 | new_rtc.tv_nsec = 0; | 98 | new_rtc.tv_nsec = 0; |
| 99 | 99 | ||
| 100 | if (new_rtc.tv_sec <= old_rtc.tv_sec) { | 100 | if (new_rtc.tv_sec < old_rtc.tv_sec) { |
| 101 | if (new_rtc.tv_sec < old_rtc.tv_sec) | 101 | pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); |
| 102 | pr_debug("%s: time travel!\n", dev_name(&rtc->dev)); | ||
| 103 | return 0; | 102 | return 0; |
| 104 | } | 103 | } |
| 105 | 104 | ||
| @@ -116,7 +115,8 @@ static int rtc_resume(struct device *dev) | |||
| 116 | sleep_time = timespec_sub(sleep_time, | 115 | sleep_time = timespec_sub(sleep_time, |
| 117 | timespec_sub(new_system, old_system)); | 116 | timespec_sub(new_system, old_system)); |
| 118 | 117 | ||
| 119 | timekeeping_inject_sleeptime(&sleep_time); | 118 | if (sleep_time.tv_sec >= 0) |
| 119 | timekeeping_inject_sleeptime(&sleep_time); | ||
| 120 | return 0; | 120 | return 0; |
| 121 | } | 121 | } |
| 122 | 122 | ||
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 8e286259a00..fa4d9f32418 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
| @@ -319,6 +319,20 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
| 319 | } | 319 | } |
| 320 | EXPORT_SYMBOL_GPL(rtc_read_alarm); | 320 | EXPORT_SYMBOL_GPL(rtc_read_alarm); |
| 321 | 321 | ||
| 322 | static int ___rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | ||
| 323 | { | ||
| 324 | int err; | ||
| 325 | |||
| 326 | if (!rtc->ops) | ||
| 327 | err = -ENODEV; | ||
| 328 | else if (!rtc->ops->set_alarm) | ||
| 329 | err = -EINVAL; | ||
| 330 | else | ||
| 331 | err = rtc->ops->set_alarm(rtc->dev.parent, alarm); | ||
| 332 | |||
| 333 | return err; | ||
| 334 | } | ||
| 335 | |||
| 322 | static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | 336 | static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
| 323 | { | 337 | { |
| 324 | struct rtc_time tm; | 338 | struct rtc_time tm; |
| @@ -342,14 +356,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
| 342 | * over right here, before we set the alarm. | 356 | * over right here, before we set the alarm. |
| 343 | */ | 357 | */ |
| 344 | 358 | ||
| 345 | if (!rtc->ops) | 359 | return ___rtc_set_alarm(rtc, alarm); |
| 346 | err = -ENODEV; | ||
| 347 | else if (!rtc->ops->set_alarm) | ||
| 348 | err = -EINVAL; | ||
| 349 | else | ||
| 350 | err = rtc->ops->set_alarm(rtc->dev.parent, alarm); | ||
| 351 | |||
| 352 | return err; | ||
| 353 | } | 360 | } |
| 354 | 361 | ||
| 355 | int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | 362 | int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) |
| @@ -763,6 +770,20 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) | |||
| 763 | return 0; | 770 | return 0; |
| 764 | } | 771 | } |
| 765 | 772 | ||
| 773 | static void rtc_alarm_disable(struct rtc_device *rtc) | ||
| 774 | { | ||
| 775 | struct rtc_wkalrm alarm; | ||
| 776 | struct rtc_time tm; | ||
| 777 | |||
| 778 | __rtc_read_time(rtc, &tm); | ||
| 779 | |||
| 780 | alarm.time = rtc_ktime_to_tm(ktime_add(rtc_tm_to_ktime(tm), | ||
| 781 | ktime_set(300, 0))); | ||
| 782 | alarm.enabled = 0; | ||
| 783 | |||
| 784 | ___rtc_set_alarm(rtc, &alarm); | ||
| 785 | } | ||
| 786 | |||
| 766 | /** | 787 | /** |
| 767 | * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue | 788 | * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue |
| 768 | * @rtc rtc device | 789 | * @rtc rtc device |
| @@ -784,8 +805,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) | |||
| 784 | struct rtc_wkalrm alarm; | 805 | struct rtc_wkalrm alarm; |
| 785 | int err; | 806 | int err; |
| 786 | next = timerqueue_getnext(&rtc->timerqueue); | 807 | next = timerqueue_getnext(&rtc->timerqueue); |
| 787 | if (!next) | 808 | if (!next) { |
| 809 | rtc_alarm_disable(rtc); | ||
| 788 | return; | 810 | return; |
| 811 | } | ||
| 789 | alarm.time = rtc_ktime_to_tm(next->expires); | 812 | alarm.time = rtc_ktime_to_tm(next->expires); |
| 790 | alarm.enabled = 1; | 813 | alarm.enabled = 1; |
| 791 | err = __rtc_set_alarm(rtc, &alarm); | 814 | err = __rtc_set_alarm(rtc, &alarm); |
| @@ -847,7 +870,8 @@ again: | |||
| 847 | err = __rtc_set_alarm(rtc, &alarm); | 870 | err = __rtc_set_alarm(rtc, &alarm); |
| 848 | if (err == -ETIME) | 871 | if (err == -ETIME) |
| 849 | goto again; | 872 | goto again; |
| 850 | } | 873 | } else |
| 874 | rtc_alarm_disable(rtc); | ||
| 851 | 875 | ||
| 852 | mutex_unlock(&rtc->ops_lock); | 876 | mutex_unlock(&rtc->ops_lock); |
| 853 | } | 877 | } |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 7639ab906f0..5b979d9cc33 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/cio/chsc.c b/drivers/s390/cio/chsc.c index 75c3f1f8fd4..a84631a7391 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
| @@ -529,10 +529,7 @@ __s390_vary_chpid_on(struct subchannel_id schid, void *data) | |||
| 529 | int chsc_chp_vary(struct chp_id chpid, int on) | 529 | int chsc_chp_vary(struct chp_id chpid, int on) |
| 530 | { | 530 | { |
| 531 | struct channel_path *chp = chpid_to_chp(chpid); | 531 | struct channel_path *chp = chpid_to_chp(chpid); |
| 532 | struct chp_link link; | ||
| 533 | 532 | ||
| 534 | memset(&link, 0, sizeof(struct chp_link)); | ||
| 535 | link.chpid = chpid; | ||
| 536 | /* Wait until previous actions have settled. */ | 533 | /* Wait until previous actions have settled. */ |
| 537 | css_wait_for_slow_path(); | 534 | css_wait_for_slow_path(); |
| 538 | /* | 535 | /* |
| @@ -542,10 +539,10 @@ int chsc_chp_vary(struct chp_id chpid, int on) | |||
| 542 | /* Try to update the channel path descritor. */ | 539 | /* Try to update the channel path descritor. */ |
| 543 | chsc_determine_base_channel_path_desc(chpid, &chp->desc); | 540 | chsc_determine_base_channel_path_desc(chpid, &chp->desc); |
| 544 | for_each_subchannel_staged(s390_subchannel_vary_chpid_on, | 541 | for_each_subchannel_staged(s390_subchannel_vary_chpid_on, |
| 545 | __s390_vary_chpid_on, &link); | 542 | __s390_vary_chpid_on, &chpid); |
| 546 | } else | 543 | } else |
| 547 | for_each_subchannel_staged(s390_subchannel_vary_chpid_off, | 544 | for_each_subchannel_staged(s390_subchannel_vary_chpid_off, |
| 548 | NULL, &link); | 545 | NULL, &chpid); |
| 549 | 546 | ||
| 550 | return 0; | 547 | return 0; |
| 551 | } | 548 | } |
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index 155a82bcb9e..4a1ff5c2eb8 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h | |||
| @@ -68,8 +68,13 @@ struct schib { | |||
| 68 | __u8 mda[4]; /* model dependent area */ | 68 | __u8 mda[4]; /* model dependent area */ |
| 69 | } __attribute__ ((packed,aligned(4))); | 69 | } __attribute__ ((packed,aligned(4))); |
| 70 | 70 | ||
| 71 | /* | ||
| 72 | * When rescheduled, todo's with higher values will overwrite those | ||
| 73 | * with lower values. | ||
| 74 | */ | ||
| 71 | enum sch_todo { | 75 | enum sch_todo { |
| 72 | SCH_TODO_NOTHING, | 76 | SCH_TODO_NOTHING, |
| 77 | SCH_TODO_EVAL, | ||
| 73 | SCH_TODO_UNREG, | 78 | SCH_TODO_UNREG, |
| 74 | }; | 79 | }; |
| 75 | 80 | ||
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 92d7324acb1..21908e67bf6 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
| @@ -195,51 +195,6 @@ void css_sch_device_unregister(struct subchannel *sch) | |||
| 195 | } | 195 | } |
| 196 | EXPORT_SYMBOL_GPL(css_sch_device_unregister); | 196 | EXPORT_SYMBOL_GPL(css_sch_device_unregister); |
| 197 | 197 | ||
| 198 | static void css_sch_todo(struct work_struct *work) | ||
| 199 | { | ||
| 200 | struct subchannel *sch; | ||
| 201 | enum sch_todo todo; | ||
| 202 | |||
| 203 | sch = container_of(work, struct subchannel, todo_work); | ||
| 204 | /* Find out todo. */ | ||
| 205 | spin_lock_irq(sch->lock); | ||
| 206 | todo = sch->todo; | ||
| 207 | CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid, | ||
| 208 | sch->schid.sch_no, todo); | ||
| 209 | sch->todo = SCH_TODO_NOTHING; | ||
| 210 | spin_unlock_irq(sch->lock); | ||
| 211 | /* Perform todo. */ | ||
| 212 | if (todo == SCH_TODO_UNREG) | ||
| 213 | css_sch_device_unregister(sch); | ||
| 214 | /* Release workqueue ref. */ | ||
| 215 | put_device(&sch->dev); | ||
| 216 | } | ||
| 217 | |||
| 218 | /** | ||
| 219 | * css_sched_sch_todo - schedule a subchannel operation | ||
| 220 | * @sch: subchannel | ||
| 221 | * @todo: todo | ||
| 222 | * | ||
| 223 | * Schedule the operation identified by @todo to be performed on the slow path | ||
| 224 | * workqueue. Do nothing if another operation with higher priority is already | ||
| 225 | * scheduled. Needs to be called with subchannel lock held. | ||
| 226 | */ | ||
| 227 | void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo) | ||
| 228 | { | ||
| 229 | CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n", | ||
| 230 | sch->schid.ssid, sch->schid.sch_no, todo); | ||
| 231 | if (sch->todo >= todo) | ||
| 232 | return; | ||
| 233 | /* Get workqueue ref. */ | ||
| 234 | if (!get_device(&sch->dev)) | ||
| 235 | return; | ||
| 236 | sch->todo = todo; | ||
| 237 | if (!queue_work(cio_work_q, &sch->todo_work)) { | ||
| 238 | /* Already queued, release workqueue ref. */ | ||
| 239 | put_device(&sch->dev); | ||
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw) | 198 | static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw) |
| 244 | { | 199 | { |
| 245 | int i; | 200 | int i; |
| @@ -466,6 +421,65 @@ static void css_evaluate_subchannel(struct subchannel_id schid, int slow) | |||
| 466 | css_schedule_eval(schid); | 421 | css_schedule_eval(schid); |
| 467 | } | 422 | } |
| 468 | 423 | ||
| 424 | /** | ||
| 425 | * css_sched_sch_todo - schedule a subchannel operation | ||
| 426 | * @sch: subchannel | ||
| 427 | * @todo: todo | ||
| 428 | * | ||
| 429 | * Schedule the operation identified by @todo to be performed on the slow path | ||
| 430 | * workqueue. Do nothing if another operation with higher priority is already | ||
| 431 | * scheduled. Needs to be called with subchannel lock held. | ||
| 432 | */ | ||
| 433 | void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo) | ||
| 434 | { | ||
| 435 | CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n", | ||
| 436 | sch->schid.ssid, sch->schid.sch_no, todo); | ||
| 437 | if (sch->todo >= todo) | ||
| 438 | return; | ||
| 439 | /* Get workqueue ref. */ | ||
| 440 | if (!get_device(&sch->dev)) | ||
| 441 | return; | ||
| 442 | sch->todo = todo; | ||
| 443 | if (!queue_work(cio_work_q, &sch->todo_work)) { | ||
| 444 | /* Already queued, release workqueue ref. */ | ||
| 445 | put_device(&sch->dev); | ||
| 446 | } | ||
| 447 | } | ||
| 448 | |||
| 449 | static void css_sch_todo(struct work_struct *work) | ||
| 450 | { | ||
| 451 | struct subchannel *sch; | ||
| 452 | enum sch_todo todo; | ||
| 453 | int ret; | ||
| 454 | |||
| 455 | sch = container_of(work, struct subchannel, todo_work); | ||
| 456 | /* Find out todo. */ | ||
| 457 | spin_lock_irq(sch->lock); | ||
| 458 | todo = sch->todo; | ||
| 459 | CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid, | ||
| 460 | sch->schid.sch_no, todo); | ||
| 461 | sch->todo = SCH_TODO_NOTHING; | ||
| 462 | spin_unlock_irq(sch->lock); | ||
| 463 | /* Perform todo. */ | ||
| 464 | switch (todo) { | ||
| 465 | case SCH_TODO_NOTHING: | ||
| 466 | break; | ||
| 467 | case SCH_TODO_EVAL: | ||
| 468 | ret = css_evaluate_known_subchannel(sch, 1); | ||
| 469 | if (ret == -EAGAIN) { | ||
| 470 | spin_lock_irq(sch->lock); | ||
| 471 | css_sched_sch_todo(sch, todo); | ||
| 472 | spin_unlock_irq(sch->lock); | ||
| 473 | } | ||
| 474 | break; | ||
| 475 | case SCH_TODO_UNREG: | ||
| 476 | css_sch_device_unregister(sch); | ||
| 477 | break; | ||
| 478 | } | ||
| 479 | /* Release workqueue ref. */ | ||
| 480 | put_device(&sch->dev); | ||
| 481 | } | ||
| 482 | |||
| 469 | static struct idset *slow_subchannel_set; | 483 | static struct idset *slow_subchannel_set; |
| 470 | static spinlock_t slow_subchannel_lock; | 484 | static spinlock_t slow_subchannel_lock; |
| 471 | static wait_queue_head_t css_eval_wq; | 485 | static wait_queue_head_t css_eval_wq; |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index d734f4a0eca..47269858ecb 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
| @@ -1868,9 +1868,9 @@ static void __ccw_device_pm_restore(struct ccw_device *cdev) | |||
| 1868 | */ | 1868 | */ |
| 1869 | cdev->private->flags.resuming = 1; | 1869 | cdev->private->flags.resuming = 1; |
| 1870 | cdev->private->path_new_mask = LPM_ANYPATH; | 1870 | cdev->private->path_new_mask = LPM_ANYPATH; |
| 1871 | css_schedule_eval(sch->schid); | 1871 | css_sched_sch_todo(sch, SCH_TODO_EVAL); |
| 1872 | spin_unlock_irq(sch->lock); | 1872 | spin_unlock_irq(sch->lock); |
| 1873 | css_complete_work(); | 1873 | css_wait_for_slow_path(); |
| 1874 | 1874 | ||
| 1875 | /* cdev may have been moved to a different subchannel. */ | 1875 | /* cdev may have been moved to a different subchannel. */ |
| 1876 | sch = to_subchannel(cdev->dev.parent); | 1876 | sch = to_subchannel(cdev->dev.parent); |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 52c233fa2b1..1b853513c89 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
| @@ -496,8 +496,26 @@ static void ccw_device_reset_path_events(struct ccw_device *cdev) | |||
| 496 | cdev->private->pgid_reset_mask = 0; | 496 | cdev->private->pgid_reset_mask = 0; |
| 497 | } | 497 | } |
| 498 | 498 | ||
| 499 | void | 499 | static void create_fake_irb(struct irb *irb, int type) |
| 500 | ccw_device_verify_done(struct ccw_device *cdev, int err) | 500 | { |
| 501 | memset(irb, 0, sizeof(*irb)); | ||
| 502 | if (type == FAKE_CMD_IRB) { | ||
| 503 | struct cmd_scsw *scsw = &irb->scsw.cmd; | ||
| 504 | scsw->cc = 1; | ||
| 505 | scsw->fctl = SCSW_FCTL_START_FUNC; | ||
| 506 | scsw->actl = SCSW_ACTL_START_PEND; | ||
| 507 | scsw->stctl = SCSW_STCTL_STATUS_PEND; | ||
| 508 | } else if (type == FAKE_TM_IRB) { | ||
| 509 | struct tm_scsw *scsw = &irb->scsw.tm; | ||
| 510 | scsw->x = 1; | ||
| 511 | scsw->cc = 1; | ||
| 512 | scsw->fctl = SCSW_FCTL_START_FUNC; | ||
| 513 | scsw->actl = SCSW_ACTL_START_PEND; | ||
| 514 | scsw->stctl = SCSW_STCTL_STATUS_PEND; | ||
| 515 | } | ||
| 516 | } | ||
| 517 | |||
| 518 | void ccw_device_verify_done(struct ccw_device *cdev, int err) | ||
| 501 | { | 519 | { |
| 502 | struct subchannel *sch; | 520 | struct subchannel *sch; |
| 503 | 521 | ||
| @@ -520,12 +538,8 @@ callback: | |||
| 520 | ccw_device_done(cdev, DEV_STATE_ONLINE); | 538 | ccw_device_done(cdev, DEV_STATE_ONLINE); |
| 521 | /* Deliver fake irb to device driver, if needed. */ | 539 | /* Deliver fake irb to device driver, if needed. */ |
| 522 | if (cdev->private->flags.fake_irb) { | 540 | if (cdev->private->flags.fake_irb) { |
| 523 | memset(&cdev->private->irb, 0, sizeof(struct irb)); | 541 | create_fake_irb(&cdev->private->irb, |
| 524 | cdev->private->irb.scsw.cmd.cc = 1; | 542 | cdev->private->flags.fake_irb); |
| 525 | cdev->private->irb.scsw.cmd.fctl = SCSW_FCTL_START_FUNC; | ||
| 526 | cdev->private->irb.scsw.cmd.actl = SCSW_ACTL_START_PEND; | ||
| 527 | cdev->private->irb.scsw.cmd.stctl = | ||
| 528 | SCSW_STCTL_STATUS_PEND; | ||
| 529 | cdev->private->flags.fake_irb = 0; | 543 | cdev->private->flags.fake_irb = 0; |
| 530 | if (cdev->handler) | 544 | if (cdev->handler) |
| 531 | cdev->handler(cdev, cdev->private->intparm, | 545 | cdev->handler(cdev, cdev->private->intparm, |
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index f98698d5735..ec7fb6d3b47 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c | |||
| @@ -198,7 +198,7 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, | |||
| 198 | if (cdev->private->state == DEV_STATE_VERIFY) { | 198 | if (cdev->private->state == DEV_STATE_VERIFY) { |
| 199 | /* Remember to fake irb when finished. */ | 199 | /* Remember to fake irb when finished. */ |
| 200 | if (!cdev->private->flags.fake_irb) { | 200 | if (!cdev->private->flags.fake_irb) { |
| 201 | cdev->private->flags.fake_irb = 1; | 201 | cdev->private->flags.fake_irb = FAKE_CMD_IRB; |
| 202 | cdev->private->intparm = intparm; | 202 | cdev->private->intparm = intparm; |
| 203 | return 0; | 203 | return 0; |
| 204 | } else | 204 | } else |
| @@ -213,9 +213,9 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, | |||
| 213 | ret = cio_set_options (sch, flags); | 213 | ret = cio_set_options (sch, flags); |
| 214 | if (ret) | 214 | if (ret) |
| 215 | return ret; | 215 | return ret; |
| 216 | /* Adjust requested path mask to excluded varied off paths. */ | 216 | /* Adjust requested path mask to exclude unusable paths. */ |
| 217 | if (lpm) { | 217 | if (lpm) { |
| 218 | lpm &= sch->opm; | 218 | lpm &= sch->lpm; |
| 219 | if (lpm == 0) | 219 | if (lpm == 0) |
| 220 | return -EACCES; | 220 | return -EACCES; |
| 221 | } | 221 | } |
| @@ -605,11 +605,21 @@ int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw, | |||
| 605 | sch = to_subchannel(cdev->dev.parent); | 605 | sch = to_subchannel(cdev->dev.parent); |
| 606 | if (!sch->schib.pmcw.ena) | 606 | if (!sch->schib.pmcw.ena) |
| 607 | return -EINVAL; | 607 | return -EINVAL; |
| 608 | if (cdev->private->state == DEV_STATE_VERIFY) { | ||
| 609 | /* Remember to fake irb when finished. */ | ||
| 610 | if (!cdev->private->flags.fake_irb) { | ||
| 611 | cdev->private->flags.fake_irb = FAKE_TM_IRB; | ||
| 612 | cdev->private->intparm = intparm; | ||
| 613 | return 0; | ||
| 614 | } else | ||
| 615 | /* There's already a fake I/O around. */ | ||
| 616 | return -EBUSY; | ||
| 617 | } | ||
| 608 | if (cdev->private->state != DEV_STATE_ONLINE) | 618 | if (cdev->private->state != DEV_STATE_ONLINE) |
| 609 | return -EIO; | 619 | return -EIO; |
| 610 | /* Adjust requested path mask to excluded varied off paths. */ | 620 | /* Adjust requested path mask to exclude unusable paths. */ |
| 611 | if (lpm) { | 621 | if (lpm) { |
| 612 | lpm &= sch->opm; | 622 | lpm &= sch->lpm; |
| 613 | if (lpm == 0) | 623 | if (lpm == 0) |
| 614 | return -EACCES; | 624 | return -EACCES; |
| 615 | } | 625 | } |
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index 2ebb492a5c1..76253dfcc1b 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h | |||
| @@ -111,6 +111,9 @@ enum cdev_todo { | |||
| 111 | CDEV_TODO_UNREG_EVAL, | 111 | CDEV_TODO_UNREG_EVAL, |
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | #define FAKE_CMD_IRB 1 | ||
| 115 | #define FAKE_TM_IRB 2 | ||
| 116 | |||
| 114 | struct ccw_device_private { | 117 | struct ccw_device_private { |
| 115 | struct ccw_device *cdev; | 118 | struct ccw_device *cdev; |
| 116 | struct subchannel *sch; | 119 | struct subchannel *sch; |
| @@ -138,7 +141,7 @@ struct ccw_device_private { | |||
| 138 | unsigned int doverify:1; /* delayed path verification */ | 141 | unsigned int doverify:1; /* delayed path verification */ |
| 139 | unsigned int donotify:1; /* call notify function */ | 142 | unsigned int donotify:1; /* call notify function */ |
| 140 | unsigned int recog_done:1; /* dev. recog. complete */ | 143 | unsigned int recog_done:1; /* dev. recog. complete */ |
| 141 | unsigned int fake_irb:1; /* deliver faked irb */ | 144 | unsigned int fake_irb:2; /* deliver faked irb */ |
| 142 | unsigned int resuming:1; /* recognition while resume */ | 145 | unsigned int resuming:1; /* recognition while resume */ |
| 143 | unsigned int pgroup:1; /* pathgroup is set up */ | 146 | unsigned int pgroup:1; /* pathgroup is set up */ |
| 144 | unsigned int mpath:1; /* multipathing is set up */ | 147 | unsigned int mpath:1; /* multipathing is set up */ |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index ec94f049e99..96bbe9d12a7 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
| @@ -1552,6 +1552,8 @@ static void ap_reset(struct ap_device *ap_dev) | |||
| 1552 | rc = ap_init_queue(ap_dev->qid); | 1552 | rc = ap_init_queue(ap_dev->qid); |
| 1553 | if (rc == -ENODEV) | 1553 | if (rc == -ENODEV) |
| 1554 | ap_dev->unregistered = 1; | 1554 | ap_dev->unregistered = 1; |
| 1555 | else | ||
| 1556 | __ap_schedule_poll_timer(); | ||
| 1555 | } | 1557 | } |
| 1556 | 1558 | ||
| 1557 | static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags) | 1559 | static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags) |
diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 5f94d22c491..54266829290 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 965a1fccd66..4b9939726c3 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 be7b4e56154..339fd6f65ed 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 73dd4e7afaa..826157f3869 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 ebce9639a26..0b31658ccde 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/spi/Kconfig b/drivers/spi/Kconfig index a1fd73df541..8ba4510a951 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 024b48aed5c..acc88b4d286 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 e093d3ec41b..0094c645ff0 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 21c70b2b831..182e9c87382 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/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 84c934c0a54..520e8286db2 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c | |||
| @@ -517,10 +517,14 @@ static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc) | |||
| 517 | 517 | ||
| 518 | static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) | 518 | static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) |
| 519 | { | 519 | { |
| 520 | ssb_pcicore_fix_sprom_core_index(pc); | 520 | struct ssb_device *pdev = pc->dev; |
| 521 | struct ssb_bus *bus = pdev->bus; | ||
| 522 | |||
| 523 | if (bus->bustype == SSB_BUSTYPE_PCI) | ||
| 524 | ssb_pcicore_fix_sprom_core_index(pc); | ||
| 521 | 525 | ||
| 522 | /* Disable PCI interrupts. */ | 526 | /* Disable PCI interrupts. */ |
| 523 | ssb_write32(pc->dev, SSB_INTVEC, 0); | 527 | ssb_write32(pdev, SSB_INTVEC, 0); |
| 524 | 528 | ||
| 525 | /* Additional PCIe always once-executed workarounds */ | 529 | /* Additional PCIe always once-executed workarounds */ |
| 526 | if (pc->dev->id.coreid == SSB_DEV_PCIE) { | 530 | if (pc->dev->id.coreid == SSB_DEV_PCIE) { |
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 21d8c1c16cd..5e78c77d5a0 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c | |||
| @@ -671,7 +671,7 @@ static int do_insnlist_ioctl(struct comedi_device *dev, | |||
| 671 | } | 671 | } |
| 672 | 672 | ||
| 673 | insns = | 673 | insns = |
| 674 | kmalloc(sizeof(struct comedi_insn) * insnlist.n_insns, GFP_KERNEL); | 674 | kcalloc(insnlist.n_insns, sizeof(struct comedi_insn), GFP_KERNEL); |
| 675 | if (!insns) { | 675 | if (!insns) { |
| 676 | DPRINTK("kmalloc failed\n"); | 676 | DPRINTK("kmalloc failed\n"); |
| 677 | ret = -ENOMEM; | 677 | ret = -ENOMEM; |
| @@ -1432,7 +1432,21 @@ static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s) | |||
| 1432 | return ret; | 1432 | return ret; |
| 1433 | } | 1433 | } |
| 1434 | 1434 | ||
| 1435 | static void comedi_unmap(struct vm_area_struct *area) | 1435 | |
| 1436 | static void comedi_vm_open(struct vm_area_struct *area) | ||
| 1437 | { | ||
| 1438 | struct comedi_async *async; | ||
| 1439 | struct comedi_device *dev; | ||
| 1440 | |||
| 1441 | async = area->vm_private_data; | ||
| 1442 | dev = async->subdevice->device; | ||
| 1443 | |||
| 1444 | mutex_lock(&dev->mutex); | ||
| 1445 | async->mmap_count++; | ||
| 1446 | mutex_unlock(&dev->mutex); | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | static void comedi_vm_close(struct vm_area_struct *area) | ||
| 1436 | { | 1450 | { |
| 1437 | struct comedi_async *async; | 1451 | struct comedi_async *async; |
| 1438 | struct comedi_device *dev; | 1452 | struct comedi_device *dev; |
| @@ -1446,15 +1460,13 @@ static void comedi_unmap(struct vm_area_struct *area) | |||
| 1446 | } | 1460 | } |
| 1447 | 1461 | ||
| 1448 | static struct vm_operations_struct comedi_vm_ops = { | 1462 | static struct vm_operations_struct comedi_vm_ops = { |
| 1449 | .close = comedi_unmap, | 1463 | .open = comedi_vm_open, |
| 1464 | .close = comedi_vm_close, | ||
| 1450 | }; | 1465 | }; |
| 1451 | 1466 | ||
| 1452 | static int comedi_mmap(struct file *file, struct vm_area_struct *vma) | 1467 | static int comedi_mmap(struct file *file, struct vm_area_struct *vma) |
| 1453 | { | 1468 | { |
| 1454 | const unsigned minor = iminor(file->f_dentry->d_inode); | 1469 | const unsigned minor = iminor(file->f_dentry->d_inode); |
| 1455 | struct comedi_device_file_info *dev_file_info = | ||
| 1456 | comedi_get_device_file_info(minor); | ||
| 1457 | struct comedi_device *dev = dev_file_info->device; | ||
| 1458 | struct comedi_async *async = NULL; | 1470 | struct comedi_async *async = NULL; |
| 1459 | unsigned long start = vma->vm_start; | 1471 | unsigned long start = vma->vm_start; |
| 1460 | unsigned long size; | 1472 | unsigned long size; |
| @@ -1462,6 +1474,15 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) | |||
| 1462 | int i; | 1474 | int i; |
| 1463 | int retval; | 1475 | int retval; |
| 1464 | struct comedi_subdevice *s; | 1476 | struct comedi_subdevice *s; |
| 1477 | struct comedi_device_file_info *dev_file_info; | ||
| 1478 | struct comedi_device *dev; | ||
| 1479 | |||
| 1480 | dev_file_info = comedi_get_device_file_info(minor); | ||
| 1481 | if (dev_file_info == NULL) | ||
| 1482 | return -ENODEV; | ||
| 1483 | dev = dev_file_info->device; | ||
| 1484 | if (dev == NULL) | ||
| 1485 | return -ENODEV; | ||
| 1465 | 1486 | ||
| 1466 | mutex_lock(&dev->mutex); | 1487 | mutex_lock(&dev->mutex); |
| 1467 | if (!dev->attached) { | 1488 | if (!dev->attached) { |
| @@ -1528,11 +1549,17 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait) | |||
| 1528 | { | 1549 | { |
| 1529 | unsigned int mask = 0; | 1550 | unsigned int mask = 0; |
| 1530 | const unsigned minor = iminor(file->f_dentry->d_inode); | 1551 | const unsigned minor = iminor(file->f_dentry->d_inode); |
| 1531 | struct comedi_device_file_info *dev_file_info = | ||
| 1532 | comedi_get_device_file_info(minor); | ||
| 1533 | struct comedi_device *dev = dev_file_info->device; | ||
| 1534 | struct comedi_subdevice *read_subdev; | 1552 | struct comedi_subdevice *read_subdev; |
| 1535 | struct comedi_subdevice *write_subdev; | 1553 | struct comedi_subdevice *write_subdev; |
| 1554 | struct comedi_device_file_info *dev_file_info; | ||
| 1555 | struct comedi_device *dev; | ||
| 1556 | dev_file_info = comedi_get_device_file_info(minor); | ||
| 1557 | |||
| 1558 | if (dev_file_info == NULL) | ||
| 1559 | return -ENODEV; | ||
| 1560 | dev = dev_file_info->device; | ||
| 1561 | if (dev == NULL) | ||
| 1562 | return -ENODEV; | ||
| 1536 | 1563 | ||
| 1537 | mutex_lock(&dev->mutex); | 1564 | mutex_lock(&dev->mutex); |
| 1538 | if (!dev->attached) { | 1565 | if (!dev->attached) { |
| @@ -1578,9 +1605,15 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, | |||
| 1578 | int n, m, count = 0, retval = 0; | 1605 | int n, m, count = 0, retval = 0; |
| 1579 | DECLARE_WAITQUEUE(wait, current); | 1606 | DECLARE_WAITQUEUE(wait, current); |
| 1580 | const unsigned minor = iminor(file->f_dentry->d_inode); | 1607 | const unsigned minor = iminor(file->f_dentry->d_inode); |
| 1581 | struct comedi_device_file_info *dev_file_info = | 1608 | struct comedi_device_file_info *dev_file_info; |
| 1582 | comedi_get_device_file_info(minor); | 1609 | struct comedi_device *dev; |
| 1583 | struct comedi_device *dev = dev_file_info->device; | 1610 | dev_file_info = comedi_get_device_file_info(minor); |
| 1611 | |||
| 1612 | if (dev_file_info == NULL) | ||
| 1613 | return -ENODEV; | ||
| 1614 | dev = dev_file_info->device; | ||
| 1615 | if (dev == NULL) | ||
| 1616 | return -ENODEV; | ||
| 1584 | 1617 | ||
| 1585 | if (!dev->attached) { | 1618 | if (!dev->attached) { |
| 1586 | DPRINTK("no driver configured on comedi%i\n", dev->minor); | 1619 | DPRINTK("no driver configured on comedi%i\n", dev->minor); |
| @@ -1640,11 +1673,11 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, | |||
| 1640 | retval = -EAGAIN; | 1673 | retval = -EAGAIN; |
| 1641 | break; | 1674 | break; |
| 1642 | } | 1675 | } |
| 1676 | schedule(); | ||
| 1643 | if (signal_pending(current)) { | 1677 | if (signal_pending(current)) { |
| 1644 | retval = -ERESTARTSYS; | 1678 | retval = -ERESTARTSYS; |
| 1645 | break; | 1679 | break; |
| 1646 | } | 1680 | } |
| 1647 | schedule(); | ||
| 1648 | if (!s->busy) | 1681 | if (!s->busy) |
| 1649 | break; | 1682 | break; |
| 1650 | if (s->busy != file) { | 1683 | if (s->busy != file) { |
| @@ -1683,9 +1716,15 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, | |||
| 1683 | int n, m, count = 0, retval = 0; | 1716 | int n, m, count = 0, retval = 0; |
| 1684 | DECLARE_WAITQUEUE(wait, current); | 1717 | DECLARE_WAITQUEUE(wait, current); |
| 1685 | const unsigned minor = iminor(file->f_dentry->d_inode); | 1718 | const unsigned minor = iminor(file->f_dentry->d_inode); |
| 1686 | struct comedi_device_file_info *dev_file_info = | 1719 | struct comedi_device_file_info *dev_file_info; |
| 1687 | comedi_get_device_file_info(minor); | 1720 | struct comedi_device *dev; |
| 1688 | struct comedi_device *dev = dev_file_info->device; | 1721 | dev_file_info = comedi_get_device_file_info(minor); |
| 1722 | |||
| 1723 | if (dev_file_info == NULL) | ||
| 1724 | return -ENODEV; | ||
| 1725 | dev = dev_file_info->device; | ||
| 1726 | if (dev == NULL) | ||
| 1727 | return -ENODEV; | ||
| 1689 | 1728 | ||
| 1690 | if (!dev->attached) { | 1729 | if (!dev->attached) { |
| 1691 | DPRINTK("no driver configured on comedi%i\n", dev->minor); | 1730 | DPRINTK("no driver configured on comedi%i\n", dev->minor); |
| @@ -1741,11 +1780,11 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, | |||
| 1741 | retval = -EAGAIN; | 1780 | retval = -EAGAIN; |
| 1742 | break; | 1781 | break; |
| 1743 | } | 1782 | } |
| 1783 | schedule(); | ||
| 1744 | if (signal_pending(current)) { | 1784 | if (signal_pending(current)) { |
| 1745 | retval = -ERESTARTSYS; | 1785 | retval = -ERESTARTSYS; |
| 1746 | break; | 1786 | break; |
| 1747 | } | 1787 | } |
| 1748 | schedule(); | ||
| 1749 | if (!s->busy) { | 1788 | if (!s->busy) { |
| 1750 | retval = 0; | 1789 | retval = 0; |
| 1751 | break; | 1790 | break; |
| @@ -1885,11 +1924,17 @@ ok: | |||
| 1885 | static int comedi_close(struct inode *inode, struct file *file) | 1924 | static int comedi_close(struct inode *inode, struct file *file) |
| 1886 | { | 1925 | { |
| 1887 | const unsigned minor = iminor(inode); | 1926 | const unsigned minor = iminor(inode); |
| 1888 | struct comedi_device_file_info *dev_file_info = | ||
| 1889 | comedi_get_device_file_info(minor); | ||
| 1890 | struct comedi_device *dev = dev_file_info->device; | ||
| 1891 | struct comedi_subdevice *s = NULL; | 1927 | struct comedi_subdevice *s = NULL; |
| 1892 | int i; | 1928 | int i; |
| 1929 | struct comedi_device_file_info *dev_file_info; | ||
| 1930 | struct comedi_device *dev; | ||
| 1931 | dev_file_info = comedi_get_device_file_info(minor); | ||
| 1932 | |||
| 1933 | if (dev_file_info == NULL) | ||
| 1934 | return -ENODEV; | ||
| 1935 | dev = dev_file_info->device; | ||
| 1936 | if (dev == NULL) | ||
| 1937 | return -ENODEV; | ||
| 1893 | 1938 | ||
| 1894 | mutex_lock(&dev->mutex); | 1939 | mutex_lock(&dev->mutex); |
| 1895 | 1940 | ||
| @@ -1923,10 +1968,15 @@ static int comedi_close(struct inode *inode, struct file *file) | |||
| 1923 | static int comedi_fasync(int fd, struct file *file, int on) | 1968 | static int comedi_fasync(int fd, struct file *file, int on) |
| 1924 | { | 1969 | { |
| 1925 | const unsigned minor = iminor(file->f_dentry->d_inode); | 1970 | const unsigned minor = iminor(file->f_dentry->d_inode); |
| 1926 | struct comedi_device_file_info *dev_file_info = | 1971 | struct comedi_device_file_info *dev_file_info; |
| 1927 | comedi_get_device_file_info(minor); | 1972 | struct comedi_device *dev; |
| 1973 | dev_file_info = comedi_get_device_file_info(minor); | ||
| 1928 | 1974 | ||
| 1929 | struct comedi_device *dev = dev_file_info->device; | 1975 | if (dev_file_info == NULL) |
| 1976 | return -ENODEV; | ||
| 1977 | dev = dev_file_info->device; | ||
| 1978 | if (dev == NULL) | ||
| 1979 | return -ENODEV; | ||
| 1930 | 1980 | ||
| 1931 | return fasync_helper(fd, file, on, &dev->async_queue); | 1981 | return fasync_helper(fd, file, on, &dev->async_queue); |
| 1932 | } | 1982 | } |
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index a8fea9a9173..6144afb8cba 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | #define DRIVER_VERSION "v0.5" | 1 | #define DRIVER_VERSION "v0.6" |
| 2 | #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com" | 2 | #define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com" |
| 3 | #define DRIVER_DESC "Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com" | 3 | #define DRIVER_DESC "Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com" |
| 4 | /* | 4 | /* |
| @@ -25,7 +25,7 @@ Driver: usbduxsigma | |||
| 25 | Description: University of Stirling USB DAQ & INCITE Technology Limited | 25 | Description: University of Stirling USB DAQ & INCITE Technology Limited |
| 26 | Devices: [ITL] USB-DUX (usbduxsigma.o) | 26 | Devices: [ITL] USB-DUX (usbduxsigma.o) |
| 27 | Author: Bernd Porr <BerndPorr@f2s.com> | 27 | Author: Bernd Porr <BerndPorr@f2s.com> |
| 28 | Updated: 21 Jul 2011 | 28 | Updated: 8 Nov 2011 |
| 29 | Status: testing | 29 | Status: testing |
| 30 | */ | 30 | */ |
| 31 | /* | 31 | /* |
| @@ -44,6 +44,7 @@ Status: testing | |||
| 44 | * 0.3: proper vendor ID and driver name | 44 | * 0.3: proper vendor ID and driver name |
| 45 | * 0.4: fixed D/A voltage range | 45 | * 0.4: fixed D/A voltage range |
| 46 | * 0.5: various bug fixes, health check at startup | 46 | * 0.5: various bug fixes, health check at startup |
| 47 | * 0.6: corrected wrong input range | ||
| 47 | */ | 48 | */ |
| 48 | 49 | ||
| 49 | /* generates loads of debug info */ | 50 | /* generates loads of debug info */ |
| @@ -175,7 +176,7 @@ Status: testing | |||
| 175 | /* comedi constants */ | 176 | /* comedi constants */ |
| 176 | static const struct comedi_lrange range_usbdux_ai_range = { 1, { | 177 | static const struct comedi_lrange range_usbdux_ai_range = { 1, { |
| 177 | BIP_RANGE | 178 | BIP_RANGE |
| 178 | (2.65) | 179 | (2.65/2.0) |
| 179 | } | 180 | } |
| 180 | }; | 181 | }; |
| 181 | 182 | ||
diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index fb2e89c3056..5385da2e9cd 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/rts_pstor/rtsx.c b/drivers/staging/rts_pstor/rtsx.c index 480b0ed2e4d..115635f9502 100644 --- a/drivers/staging/rts_pstor/rtsx.c +++ b/drivers/staging/rts_pstor/rtsx.c | |||
| @@ -1021,6 +1021,7 @@ static int __devinit rtsx_probe(struct pci_dev *pci, | |||
| 1021 | th = kthread_create(rtsx_scan_thread, dev, "rtsx-scan"); | 1021 | th = kthread_create(rtsx_scan_thread, dev, "rtsx-scan"); |
| 1022 | if (IS_ERR(th)) { | 1022 | if (IS_ERR(th)) { |
| 1023 | printk(KERN_ERR "Unable to start the device-scanning thread\n"); | 1023 | printk(KERN_ERR "Unable to start the device-scanning thread\n"); |
| 1024 | complete(&dev->scanning_done); | ||
| 1024 | quiesce_and_remove_host(dev); | 1025 | quiesce_and_remove_host(dev); |
| 1025 | err = PTR_ERR(th); | 1026 | err = PTR_ERR(th); |
| 1026 | goto errout; | 1027 | goto errout; |
diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c index 3d1279c424a..7eb56178fb6 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 c43c7e3421c..76cfc6edecd 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/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c index 09c44abb89e..3872b8cccdc 100644 --- a/drivers/staging/usbip/vhci_rx.c +++ b/drivers/staging/usbip/vhci_rx.c | |||
| @@ -68,6 +68,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, | |||
| 68 | { | 68 | { |
| 69 | struct usbip_device *ud = &vdev->ud; | 69 | struct usbip_device *ud = &vdev->ud; |
| 70 | struct urb *urb; | 70 | struct urb *urb; |
| 71 | unsigned long flags; | ||
| 71 | 72 | ||
| 72 | spin_lock(&vdev->priv_lock); | 73 | spin_lock(&vdev->priv_lock); |
| 73 | urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum); | 74 | urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum); |
| @@ -101,9 +102,9 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, | |||
| 101 | 102 | ||
| 102 | usbip_dbg_vhci_rx("now giveback urb %p\n", urb); | 103 | usbip_dbg_vhci_rx("now giveback urb %p\n", urb); |
| 103 | 104 | ||
| 104 | spin_lock(&the_controller->lock); | 105 | spin_lock_irqsave(&the_controller->lock, flags); |
| 105 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); | 106 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); |
| 106 | spin_unlock(&the_controller->lock); | 107 | spin_unlock_irqrestore(&the_controller->lock, flags); |
| 107 | 108 | ||
| 108 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); | 109 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); |
| 109 | 110 | ||
| @@ -141,6 +142,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, | |||
| 141 | { | 142 | { |
| 142 | struct vhci_unlink *unlink; | 143 | struct vhci_unlink *unlink; |
| 143 | struct urb *urb; | 144 | struct urb *urb; |
| 145 | unsigned long flags; | ||
| 144 | 146 | ||
| 145 | usbip_dump_header(pdu); | 147 | usbip_dump_header(pdu); |
| 146 | 148 | ||
| @@ -170,9 +172,9 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, | |||
| 170 | urb->status = pdu->u.ret_unlink.status; | 172 | urb->status = pdu->u.ret_unlink.status; |
| 171 | pr_info("urb->status %d\n", urb->status); | 173 | pr_info("urb->status %d\n", urb->status); |
| 172 | 174 | ||
| 173 | spin_lock(&the_controller->lock); | 175 | spin_lock_irqsave(&the_controller->lock, flags); |
| 174 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); | 176 | usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); |
| 175 | spin_unlock(&the_controller->lock); | 177 | spin_unlock_irqrestore(&the_controller->lock, flags); |
| 176 | 178 | ||
| 177 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, | 179 | usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, |
| 178 | urb->status); | 180 | urb->status); |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 0fd96c10271..8599545cdf9 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 beb39469e7f..1cd6ce373b8 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 3723d90d5ae..f1a02dad05a 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 c4c68da3e50..101b1beb3bc 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 daad362a93c..d734bdec24f 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 426cd4bf6a9..98936cb7c29 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 3df1c9b8ae6..81d5832fbbd 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 88f2ad43ec8..1dcbef499d6 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 683ba02b824..831468b3163 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 e0c1e8a8dd4..93d4f6a1b79 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 ba5edec2c5f..9b863942547 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 67cd6fe05bf..b4864fba4ef 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 7698efe2926..4aa99220443 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 5a4ebfc3a54..95dee7074ae 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 ed32e1efe42..8b15e56b038 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 5158d3846f1..02e51faa2f4 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 217e29df629..684522805a1 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 3400ae6e93f..0257658e2e3 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 4fac37c4c61..71fc9cea5dc 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 5f770412ca4..9402b7387ca 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 e8c564a5334..a8078d0638f 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/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 4730016d7cd..45f422ac103 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
| @@ -1959,7 +1959,7 @@ static int amd5536_start(struct usb_gadget_driver *driver, | |||
| 1959 | u32 tmp; | 1959 | u32 tmp; |
| 1960 | 1960 | ||
| 1961 | if (!driver || !bind || !driver->setup | 1961 | if (!driver || !bind || !driver->setup |
| 1962 | || driver->speed != USB_SPEED_HIGH) | 1962 | || driver->speed < USB_SPEED_HIGH) |
| 1963 | return -EINVAL; | 1963 | return -EINVAL; |
| 1964 | if (!dev) | 1964 | if (!dev) |
| 1965 | return -ENODEV; | 1965 | return -ENODEV; |
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index c39d58860fa..1a6f415c0d0 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/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index 91fdf790ed2..cf33a8d0fd5 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c | |||
| @@ -131,8 +131,8 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt) | |||
| 131 | } | 131 | } |
| 132 | if (!gser->port.in->desc || !gser->port.out->desc) { | 132 | if (!gser->port.in->desc || !gser->port.out->desc) { |
| 133 | DBG(cdev, "activate generic ttyGS%d\n", gser->port_num); | 133 | DBG(cdev, "activate generic ttyGS%d\n", gser->port_num); |
| 134 | if (!config_ep_by_speed(cdev->gadget, f, gser->port.in) || | 134 | if (config_ep_by_speed(cdev->gadget, f, gser->port.in) || |
| 135 | !config_ep_by_speed(cdev->gadget, f, gser->port.out)) { | 135 | config_ep_by_speed(cdev->gadget, f, gser->port.out)) { |
| 136 | gser->port.in->desc = NULL; | 136 | gser->port.in->desc = NULL; |
| 137 | gser->port.out->desc = NULL; | 137 | gser->port.out->desc = NULL; |
| 138 | return -EINVAL; | 138 | return -EINVAL; |
diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c index 43a49ecc1f3..dcbc0a2e48d 100644 --- a/drivers/usb/gadget/fsl_mxc_udc.c +++ b/drivers/usb/gadget/fsl_mxc_udc.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
| 17 | #include <linux/fsl_devices.h> | 17 | #include <linux/fsl_devices.h> |
| 18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/io.h> | ||
| 19 | 20 | ||
| 20 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
| 21 | 22 | ||
| @@ -88,7 +89,6 @@ eenahb: | |||
| 88 | void fsl_udc_clk_finalize(struct platform_device *pdev) | 89 | void fsl_udc_clk_finalize(struct platform_device *pdev) |
| 89 | { | 90 | { |
| 90 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; | 91 | struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data; |
| 91 | #if defined(CONFIG_SOC_IMX35) | ||
| 92 | if (cpu_is_mx35()) { | 92 | if (cpu_is_mx35()) { |
| 93 | unsigned int v; | 93 | unsigned int v; |
| 94 | 94 | ||
| @@ -101,7 +101,6 @@ void fsl_udc_clk_finalize(struct platform_device *pdev) | |||
| 101 | USBPHYCTRL_OTGBASE_OFFSET)); | 101 | USBPHYCTRL_OTGBASE_OFFSET)); |
| 102 | } | 102 | } |
| 103 | } | 103 | } |
| 104 | #endif | ||
| 105 | 104 | ||
| 106 | /* ULPI transceivers don't need usbpll */ | 105 | /* ULPI transceivers don't need usbpll */ |
| 107 | if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { | 106 | if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { |
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index 2a03e4de11c..e00cf92409c 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
| @@ -2336,8 +2336,7 @@ static int fsl_qe_start(struct usb_gadget_driver *driver, | |||
| 2336 | if (!udc_controller) | 2336 | if (!udc_controller) |
| 2337 | return -ENODEV; | 2337 | return -ENODEV; |
| 2338 | 2338 | ||
| 2339 | if (!driver || (driver->speed != USB_SPEED_FULL | 2339 | if (!driver || driver->speed < USB_SPEED_FULL |
| 2340 | && driver->speed != USB_SPEED_HIGH) | ||
| 2341 | || !bind || !driver->disconnect || !driver->setup) | 2340 | || !bind || !driver->disconnect || !driver->setup) |
| 2342 | return -EINVAL; | 2341 | return -EINVAL; |
| 2343 | 2342 | ||
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index b3b3d83b7c3..dd28ef3def7 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
| @@ -696,12 +696,31 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req) | |||
| 696 | kfree(req); | 696 | kfree(req); |
| 697 | } | 697 | } |
| 698 | 698 | ||
| 699 | /*-------------------------------------------------------------------------*/ | 699 | /* Actually add a dTD chain to an empty dQH and let go */ |
| 700 | static void fsl_prime_ep(struct fsl_ep *ep, struct ep_td_struct *td) | ||
| 701 | { | ||
| 702 | struct ep_queue_head *qh = get_qh_by_ep(ep); | ||
| 703 | |||
| 704 | /* Write dQH next pointer and terminate bit to 0 */ | ||
| 705 | qh->next_dtd_ptr = cpu_to_hc32(td->td_dma | ||
| 706 | & EP_QUEUE_HEAD_NEXT_POINTER_MASK); | ||
| 707 | |||
| 708 | /* Clear active and halt bit */ | ||
| 709 | qh->size_ioc_int_sts &= cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE | ||
| 710 | | EP_QUEUE_HEAD_STATUS_HALT)); | ||
| 711 | |||
| 712 | /* Ensure that updates to the QH will occur before priming. */ | ||
| 713 | wmb(); | ||
| 714 | |||
| 715 | /* Prime endpoint by writing correct bit to ENDPTPRIME */ | ||
| 716 | fsl_writel(ep_is_in(ep) ? (1 << (ep_index(ep) + 16)) | ||
| 717 | : (1 << (ep_index(ep))), &dr_regs->endpointprime); | ||
| 718 | } | ||
| 719 | |||
| 720 | /* Add dTD chain to the dQH of an EP */ | ||
| 700 | static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) | 721 | static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) |
| 701 | { | 722 | { |
| 702 | int i = ep_index(ep) * 2 + ep_is_in(ep); | ||
| 703 | u32 temp, bitmask, tmp_stat; | 723 | u32 temp, bitmask, tmp_stat; |
| 704 | struct ep_queue_head *dQH = &ep->udc->ep_qh[i]; | ||
| 705 | 724 | ||
| 706 | /* VDBG("QH addr Register 0x%8x", dr_regs->endpointlistaddr); | 725 | /* VDBG("QH addr Register 0x%8x", dr_regs->endpointlistaddr); |
| 707 | VDBG("ep_qh[%d] addr is 0x%8x", i, (u32)&(ep->udc->ep_qh[i])); */ | 726 | VDBG("ep_qh[%d] addr is 0x%8x", i, (u32)&(ep->udc->ep_qh[i])); */ |
| @@ -719,7 +738,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) | |||
| 719 | cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK); | 738 | cpu_to_hc32(req->head->td_dma & DTD_ADDR_MASK); |
| 720 | /* Read prime bit, if 1 goto done */ | 739 | /* Read prime bit, if 1 goto done */ |
| 721 | if (fsl_readl(&dr_regs->endpointprime) & bitmask) | 740 | if (fsl_readl(&dr_regs->endpointprime) & bitmask) |
| 722 | goto out; | 741 | return; |
| 723 | 742 | ||
| 724 | do { | 743 | do { |
| 725 | /* Set ATDTW bit in USBCMD */ | 744 | /* Set ATDTW bit in USBCMD */ |
| @@ -736,28 +755,10 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) | |||
| 736 | fsl_writel(temp & ~USB_CMD_ATDTW, &dr_regs->usbcmd); | 755 | fsl_writel(temp & ~USB_CMD_ATDTW, &dr_regs->usbcmd); |
| 737 | 756 | ||
| 738 | if (tmp_stat) | 757 | if (tmp_stat) |
| 739 | goto out; | 758 | return; |
| 740 | } | 759 | } |
| 741 | 760 | ||
| 742 | /* Write dQH next pointer and terminate bit to 0 */ | 761 | fsl_prime_ep(ep, req->head); |
| 743 | temp = req->head->td_dma & EP_QUEUE_HEAD_NEXT_POINTER_MASK; | ||
| 744 | dQH->next_dtd_ptr = cpu_to_hc32(temp); | ||
| 745 | |||
| 746 | /* Clear active and halt bit */ | ||
| 747 | temp = cpu_to_hc32(~(EP_QUEUE_HEAD_STATUS_ACTIVE | ||
| 748 | | EP_QUEUE_HEAD_STATUS_HALT)); | ||
| 749 | dQH->size_ioc_int_sts &= temp; | ||
| 750 | |||
| 751 | /* Ensure that updates to the QH will occur before priming. */ | ||
| 752 | wmb(); | ||
| 753 | |||
| 754 | /* Prime endpoint by writing 1 to ENDPTPRIME */ | ||
| 755 | temp = ep_is_in(ep) | ||
| 756 | ? (1 << (ep_index(ep) + 16)) | ||
| 757 | : (1 << (ep_index(ep))); | ||
| 758 | fsl_writel(temp, &dr_regs->endpointprime); | ||
| 759 | out: | ||
| 760 | return; | ||
| 761 | } | 762 | } |
| 762 | 763 | ||
| 763 | /* Fill in the dTD structure | 764 | /* Fill in the dTD structure |
| @@ -877,7 +878,7 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | |||
| 877 | VDBG("%s, bad ep", __func__); | 878 | VDBG("%s, bad ep", __func__); |
| 878 | return -EINVAL; | 879 | return -EINVAL; |
| 879 | } | 880 | } |
| 880 | if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { | 881 | if (usb_endpoint_xfer_isoc(ep->desc)) { |
| 881 | if (req->req.length > ep->ep.maxpacket) | 882 | if (req->req.length > ep->ep.maxpacket) |
| 882 | return -EMSGSIZE; | 883 | return -EMSGSIZE; |
| 883 | } | 884 | } |
| @@ -973,25 +974,20 @@ static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
| 973 | 974 | ||
| 974 | /* The request isn't the last request in this ep queue */ | 975 | /* The request isn't the last request in this ep queue */ |
| 975 | if (req->queue.next != &ep->queue) { | 976 | if (req->queue.next != &ep->queue) { |
| 976 | struct ep_queue_head *qh; | ||
| 977 | struct fsl_req *next_req; | 977 | struct fsl_req *next_req; |
| 978 | 978 | ||
| 979 | qh = ep->qh; | ||
| 980 | next_req = list_entry(req->queue.next, struct fsl_req, | 979 | next_req = list_entry(req->queue.next, struct fsl_req, |
| 981 | queue); | 980 | queue); |
| 982 | 981 | ||
| 983 | /* Point the QH to the first TD of next request */ | 982 | /* prime with dTD of next request */ |
| 984 | fsl_writel((u32) next_req->head, &qh->curr_dtd_ptr); | 983 | fsl_prime_ep(ep, next_req->head); |
| 985 | } | 984 | } |
| 986 | 985 | /* The request hasn't been processed, patch up the TD chain */ | |
| 987 | /* The request hasn't been processed, patch up the TD chain */ | ||
| 988 | } else { | 986 | } else { |
| 989 | struct fsl_req *prev_req; | 987 | struct fsl_req *prev_req; |
| 990 | 988 | ||
| 991 | prev_req = list_entry(req->queue.prev, struct fsl_req, queue); | 989 | prev_req = list_entry(req->queue.prev, struct fsl_req, queue); |
| 992 | fsl_writel(fsl_readl(&req->tail->next_td_ptr), | 990 | prev_req->tail->next_td_ptr = req->tail->next_td_ptr; |
| 993 | &prev_req->tail->next_td_ptr); | ||
| 994 | |||
| 995 | } | 991 | } |
| 996 | 992 | ||
| 997 | done(ep, req, -ECONNRESET); | 993 | done(ep, req, -ECONNRESET); |
| @@ -1032,7 +1028,7 @@ static int fsl_ep_set_halt(struct usb_ep *_ep, int value) | |||
| 1032 | goto out; | 1028 | goto out; |
| 1033 | } | 1029 | } |
| 1034 | 1030 | ||
| 1035 | if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) { | 1031 | if (usb_endpoint_xfer_isoc(ep->desc)) { |
| 1036 | status = -EOPNOTSUPP; | 1032 | status = -EOPNOTSUPP; |
| 1037 | goto out; | 1033 | goto out; |
| 1038 | } | 1034 | } |
| @@ -1068,7 +1064,7 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep) | |||
| 1068 | struct fsl_udc *udc; | 1064 | struct fsl_udc *udc; |
| 1069 | int size = 0; | 1065 | int size = 0; |
| 1070 | u32 bitmask; | 1066 | u32 bitmask; |
| 1071 | struct ep_queue_head *d_qh; | 1067 | struct ep_queue_head *qh; |
| 1072 | 1068 | ||
| 1073 | ep = container_of(_ep, struct fsl_ep, ep); | 1069 | ep = container_of(_ep, struct fsl_ep, ep); |
| 1074 | if (!_ep || (!ep->desc && ep_index(ep) != 0)) | 1070 | if (!_ep || (!ep->desc && ep_index(ep) != 0)) |
| @@ -1079,13 +1075,13 @@ static int fsl_ep_fifo_status(struct usb_ep *_ep) | |||
| 1079 | if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) | 1075 | if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) |
| 1080 | return -ESHUTDOWN; | 1076 | return -ESHUTDOWN; |
| 1081 | 1077 | ||
| 1082 | d_qh = &ep->udc->ep_qh[ep_index(ep) * 2 + ep_is_in(ep)]; | 1078 | qh = get_qh_by_ep(ep); |
| 1083 | 1079 | ||
| 1084 | bitmask = (ep_is_in(ep)) ? (1 << (ep_index(ep) + 16)) : | 1080 | bitmask = (ep_is_in(ep)) ? (1 << (ep_index(ep) + 16)) : |
| 1085 | (1 << (ep_index(ep))); | 1081 | (1 << (ep_index(ep))); |
| 1086 | 1082 | ||
| 1087 | if (fsl_readl(&dr_regs->endptstatus) & bitmask) | 1083 | if (fsl_readl(&dr_regs->endptstatus) & bitmask) |
| 1088 | size = (d_qh->size_ioc_int_sts & DTD_PACKET_SIZE) | 1084 | size = (qh->size_ioc_int_sts & DTD_PACKET_SIZE) |
| 1089 | >> DTD_LENGTH_BIT_POS; | 1085 | >> DTD_LENGTH_BIT_POS; |
| 1090 | 1086 | ||
| 1091 | pr_debug("%s %u\n", __func__, size); | 1087 | pr_debug("%s %u\n", __func__, size); |
| @@ -1938,8 +1934,7 @@ static int fsl_start(struct usb_gadget_driver *driver, | |||
| 1938 | if (!udc_controller) | 1934 | if (!udc_controller) |
| 1939 | return -ENODEV; | 1935 | return -ENODEV; |
| 1940 | 1936 | ||
| 1941 | if (!driver || (driver->speed != USB_SPEED_FULL | 1937 | if (!driver || driver->speed < USB_SPEED_FULL |
| 1942 | && driver->speed != USB_SPEED_HIGH) | ||
| 1943 | || !bind || !driver->disconnect || !driver->setup) | 1938 | || !bind || !driver->disconnect || !driver->setup) |
| 1944 | return -EINVAL; | 1939 | return -EINVAL; |
| 1945 | 1940 | ||
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h index 1d51be83fda..f781f5dec41 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.h +++ b/drivers/usb/gadget/fsl_usb2_udc.h | |||
| @@ -569,6 +569,16 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length) | |||
| 569 | * 2 + ((windex & USB_DIR_IN) ? 1 : 0)) | 569 | * 2 + ((windex & USB_DIR_IN) ? 1 : 0)) |
| 570 | #define get_pipe_by_ep(EP) (ep_index(EP) * 2 + ep_is_in(EP)) | 570 | #define get_pipe_by_ep(EP) (ep_index(EP) * 2 + ep_is_in(EP)) |
| 571 | 571 | ||
| 572 | static inline struct ep_queue_head *get_qh_by_ep(struct fsl_ep *ep) | ||
| 573 | { | ||
| 574 | /* we only have one ep0 structure but two queue heads */ | ||
| 575 | if (ep_index(ep) != 0) | ||
| 576 | return ep->qh; | ||
| 577 | else | ||
| 578 | return &ep->udc->ep_qh[(ep->udc->ep0_dir == | ||
| 579 | USB_DIR_IN) ? 1 : 0]; | ||
| 580 | } | ||
| 581 | |||
| 572 | struct platform_device; | 582 | struct platform_device; |
| 573 | #ifdef CONFIG_ARCH_MXC | 583 | #ifdef CONFIG_ARCH_MXC |
| 574 | int fsl_udc_clk_init(struct platform_device *pdev); | 584 | int fsl_udc_clk_init(struct platform_device *pdev); |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 91d0af2a24a..9aa1cbbee45 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
| @@ -1472,7 +1472,7 @@ static int m66592_start(struct usb_gadget_driver *driver, | |||
| 1472 | int retval; | 1472 | int retval; |
| 1473 | 1473 | ||
| 1474 | if (!driver | 1474 | if (!driver |
| 1475 | || driver->speed != USB_SPEED_HIGH | 1475 | || driver->speed < USB_SPEED_HIGH |
| 1476 | || !bind | 1476 | || !bind |
| 1477 | || !driver->setup) | 1477 | || !driver->setup) |
| 1478 | return -EINVAL; | 1478 | return -EINVAL; |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 7f1bc9a73cd..da2b9d0be3c 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
| @@ -1881,7 +1881,7 @@ static int net2280_start(struct usb_gadget *_gadget, | |||
| 1881 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) | 1881 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) |
| 1882 | * "must not be used in normal operation" | 1882 | * "must not be used in normal operation" |
| 1883 | */ | 1883 | */ |
| 1884 | if (!driver || driver->speed != USB_SPEED_HIGH | 1884 | if (!driver || driver->speed < USB_SPEED_HIGH |
| 1885 | || !driver->setup) | 1885 | || !driver->setup) |
| 1886 | return -EINVAL; | 1886 | return -EINVAL; |
| 1887 | 1887 | ||
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 24f84b210ce..fc719a3f855 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
| @@ -1746,7 +1746,7 @@ static int r8a66597_start(struct usb_gadget *gadget, | |||
| 1746 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); | 1746 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); |
| 1747 | 1747 | ||
| 1748 | if (!driver | 1748 | if (!driver |
| 1749 | || driver->speed != USB_SPEED_HIGH | 1749 | || driver->speed < USB_SPEED_HIGH |
| 1750 | || !driver->setup) | 1750 | || !driver->setup) |
| 1751 | return -EINVAL; | 1751 | return -EINVAL; |
| 1752 | if (!r8a66597) | 1752 | if (!r8a66597) |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index a552453dc94..b31448229f0 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
| @@ -2586,10 +2586,8 @@ static int s3c_hsotg_start(struct usb_gadget_driver *driver, | |||
| 2586 | return -EINVAL; | 2586 | return -EINVAL; |
| 2587 | } | 2587 | } |
| 2588 | 2588 | ||
| 2589 | if (driver->speed != USB_SPEED_HIGH && | 2589 | if (driver->speed < USB_SPEED_FULL) |
| 2590 | driver->speed != USB_SPEED_FULL) { | ||
| 2591 | dev_err(hsotg->dev, "%s: bad speed\n", __func__); | 2590 | dev_err(hsotg->dev, "%s: bad speed\n", __func__); |
| 2592 | } | ||
| 2593 | 2591 | ||
| 2594 | if (!bind || !driver->setup) { | 2592 | if (!bind || !driver->setup) { |
| 2595 | dev_err(hsotg->dev, "%s: missing entry points\n", __func__); | 2593 | dev_err(hsotg->dev, "%s: missing entry points\n", __func__); |
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 8d54f893cef..20a553b46ae 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c | |||
| @@ -1142,8 +1142,7 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, | |||
| 1142 | int ret; | 1142 | int ret; |
| 1143 | 1143 | ||
| 1144 | if (!driver | 1144 | if (!driver |
| 1145 | || (driver->speed != USB_SPEED_FULL && | 1145 | || driver->speed < USB_SPEED_FULL |
| 1146 | driver->speed != USB_SPEED_HIGH) | ||
| 1147 | || !bind | 1146 | || !bind |
| 1148 | || !driver->unbind || !driver->disconnect || !driver->setup) | 1147 | || !driver->unbind || !driver->disconnect || !driver->setup) |
| 1149 | return -EINVAL; | 1148 | return -EINVAL; |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 56a32033adb..a60679cbbf8 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
| @@ -1475,6 +1475,7 @@ iso_stream_schedule ( | |||
| 1475 | * jump until after the queue is primed. | 1475 | * jump until after the queue is primed. |
| 1476 | */ | 1476 | */ |
| 1477 | else { | 1477 | else { |
| 1478 | int done = 0; | ||
| 1478 | start = SCHEDULE_SLOP + (now & ~0x07); | 1479 | start = SCHEDULE_SLOP + (now & ~0x07); |
| 1479 | 1480 | ||
| 1480 | /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ | 1481 | /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ |
| @@ -1492,18 +1493,18 @@ iso_stream_schedule ( | |||
| 1492 | if (stream->highspeed) { | 1493 | if (stream->highspeed) { |
| 1493 | if (itd_slot_ok(ehci, mod, start, | 1494 | if (itd_slot_ok(ehci, mod, start, |
| 1494 | stream->usecs, period)) | 1495 | stream->usecs, period)) |
| 1495 | break; | 1496 | done = 1; |
| 1496 | } else { | 1497 | } else { |
| 1497 | if ((start % 8) >= 6) | 1498 | if ((start % 8) >= 6) |
| 1498 | continue; | 1499 | continue; |
| 1499 | if (sitd_slot_ok(ehci, mod, stream, | 1500 | if (sitd_slot_ok(ehci, mod, stream, |
| 1500 | start, sched, period)) | 1501 | start, sched, period)) |
| 1501 | break; | 1502 | done = 1; |
| 1502 | } | 1503 | } |
| 1503 | } while (start > next); | 1504 | } while (start > next && !done); |
| 1504 | 1505 | ||
| 1505 | /* no room in the schedule */ | 1506 | /* no room in the schedule */ |
| 1506 | if (start == next) { | 1507 | if (!done) { |
| 1507 | ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n", | 1508 | ehci_dbg(ehci, "iso resched full %p (now %d max %d)\n", |
| 1508 | urb, now, now + mod); | 1509 | urb, now, now + mod); |
| 1509 | status = -ENOSPC; | 1510 | status = -ENOSPC; |
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c index d6e17542861..a403b53e86b 100644 --- a/drivers/usb/host/whci/qset.c +++ b/drivers/usb/host/whci/qset.c | |||
| @@ -124,7 +124,7 @@ void qset_clear(struct whc *whc, struct whc_qset *qset) | |||
| 124 | { | 124 | { |
| 125 | qset->td_start = qset->td_end = qset->ntds = 0; | 125 | qset->td_start = qset->td_end = qset->ntds = 0; |
| 126 | 126 | ||
| 127 | qset->qh.link = cpu_to_le32(QH_LINK_NTDS(8) | QH_LINK_T); | 127 | qset->qh.link = cpu_to_le64(QH_LINK_NTDS(8) | QH_LINK_T); |
| 128 | qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK; | 128 | qset->qh.status = qset->qh.status & QH_STATUS_SEQ_MASK; |
| 129 | qset->qh.err_count = 0; | 129 | qset->qh.err_count = 0; |
| 130 | qset->qh.scratch[0] = 0; | 130 | qset->qh.scratch[0] = 0; |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index aa94c019579..a1afb7c39f7 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
| @@ -711,7 +711,10 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci) | |||
| 711 | ring = xhci->cmd_ring; | 711 | ring = xhci->cmd_ring; |
| 712 | seg = ring->deq_seg; | 712 | seg = ring->deq_seg; |
| 713 | do { | 713 | do { |
| 714 | memset(seg->trbs, 0, SEGMENT_SIZE); | 714 | memset(seg->trbs, 0, |
| 715 | sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1)); | ||
| 716 | seg->trbs[TRBS_PER_SEGMENT - 1].link.control &= | ||
| 717 | cpu_to_le32(~TRB_CYCLE); | ||
| 715 | seg = seg->next; | 718 | seg = seg->next; |
| 716 | } while (seg != ring->deq_seg); | 719 | } while (seg != ring->deq_seg); |
| 717 | 720 | ||
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index c1fa12ec7a9..b63ab157010 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
| @@ -2301,18 +2301,12 @@ static int musb_suspend(struct device *dev) | |||
| 2301 | */ | 2301 | */ |
| 2302 | } | 2302 | } |
| 2303 | 2303 | ||
| 2304 | musb_save_context(musb); | ||
| 2305 | |||
| 2306 | spin_unlock_irqrestore(&musb->lock, flags); | 2304 | spin_unlock_irqrestore(&musb->lock, flags); |
| 2307 | return 0; | 2305 | return 0; |
| 2308 | } | 2306 | } |
| 2309 | 2307 | ||
| 2310 | static int musb_resume_noirq(struct device *dev) | 2308 | static int musb_resume_noirq(struct device *dev) |
| 2311 | { | 2309 | { |
| 2312 | struct musb *musb = dev_to_musb(dev); | ||
| 2313 | |||
| 2314 | musb_restore_context(musb); | ||
| 2315 | |||
| 2316 | /* for static cmos like DaVinci, register values were preserved | 2310 | /* for static cmos like DaVinci, register values were preserved |
| 2317 | * unless for some reason the whole soc powered down or the USB | 2311 | * unless for some reason the whole soc powered down or the USB |
| 2318 | * module got reset through the PSC (vs just being disabled). | 2312 | * module got reset through the PSC (vs just being disabled). |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d51043acfe1..922148ff8d2 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
| @@ -1903,7 +1903,7 @@ static int musb_gadget_start(struct usb_gadget *g, | |||
| 1903 | unsigned long flags; | 1903 | unsigned long flags; |
| 1904 | int retval = -EINVAL; | 1904 | int retval = -EINVAL; |
| 1905 | 1905 | ||
| 1906 | if (driver->speed != USB_SPEED_HIGH) | 1906 | if (driver->speed < USB_SPEED_HIGH) |
| 1907 | goto err0; | 1907 | goto err0; |
| 1908 | 1908 | ||
| 1909 | pm_runtime_get_sync(musb->controller); | 1909 | pm_runtime_get_sync(musb->controller); |
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 053f86d7000..ad96a389672 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_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index d9717e0bc1f..7f4e8033857 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
| @@ -751,53 +751,32 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget, | |||
| 751 | struct usb_gadget_driver *driver) | 751 | struct usb_gadget_driver *driver) |
| 752 | { | 752 | { |
| 753 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); | 753 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
| 754 | struct usbhs_priv *priv; | 754 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
| 755 | struct device *dev; | ||
| 756 | int ret; | ||
| 757 | 755 | ||
| 758 | if (!driver || | 756 | if (!driver || |
| 759 | !driver->setup || | 757 | !driver->setup || |
| 760 | driver->speed != USB_SPEED_HIGH) | 758 | driver->speed < USB_SPEED_FULL) |
| 761 | return -EINVAL; | 759 | return -EINVAL; |
| 762 | 760 | ||
| 763 | dev = usbhsg_gpriv_to_dev(gpriv); | ||
| 764 | priv = usbhsg_gpriv_to_priv(gpriv); | ||
| 765 | |||
| 766 | /* first hook up the driver ... */ | 761 | /* first hook up the driver ... */ |
| 767 | gpriv->driver = driver; | 762 | gpriv->driver = driver; |
| 768 | gpriv->gadget.dev.driver = &driver->driver; | 763 | gpriv->gadget.dev.driver = &driver->driver; |
| 769 | 764 | ||
| 770 | ret = device_add(&gpriv->gadget.dev); | ||
| 771 | if (ret) { | ||
| 772 | dev_err(dev, "device_add error %d\n", ret); | ||
| 773 | goto add_fail; | ||
| 774 | } | ||
| 775 | |||
| 776 | return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); | 765 | return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); |
| 777 | |||
| 778 | add_fail: | ||
| 779 | gpriv->driver = NULL; | ||
| 780 | gpriv->gadget.dev.driver = NULL; | ||
| 781 | |||
| 782 | return ret; | ||
| 783 | } | 766 | } |
| 784 | 767 | ||
| 785 | static int usbhsg_gadget_stop(struct usb_gadget *gadget, | 768 | static int usbhsg_gadget_stop(struct usb_gadget *gadget, |
| 786 | struct usb_gadget_driver *driver) | 769 | struct usb_gadget_driver *driver) |
| 787 | { | 770 | { |
| 788 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); | 771 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); |
| 789 | struct usbhs_priv *priv; | 772 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
| 790 | struct device *dev; | ||
| 791 | 773 | ||
| 792 | if (!driver || | 774 | if (!driver || |
| 793 | !driver->unbind) | 775 | !driver->unbind) |
| 794 | return -EINVAL; | 776 | return -EINVAL; |
| 795 | 777 | ||
| 796 | dev = usbhsg_gpriv_to_dev(gpriv); | ||
| 797 | priv = usbhsg_gpriv_to_priv(gpriv); | ||
| 798 | |||
| 799 | usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); | 778 | usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); |
| 800 | device_del(&gpriv->gadget.dev); | 779 | gpriv->gadget.dev.driver = NULL; |
| 801 | gpriv->driver = NULL; | 780 | gpriv->driver = NULL; |
| 802 | 781 | ||
| 803 | return 0; | 782 | return 0; |
| @@ -827,6 +806,13 @@ static int usbhsg_start(struct usbhs_priv *priv) | |||
| 827 | 806 | ||
| 828 | static int usbhsg_stop(struct usbhs_priv *priv) | 807 | static int usbhsg_stop(struct usbhs_priv *priv) |
| 829 | { | 808 | { |
| 809 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
| 810 | |||
| 811 | /* cable disconnect */ | ||
| 812 | if (gpriv->driver && | ||
| 813 | gpriv->driver->disconnect) | ||
| 814 | gpriv->driver->disconnect(&gpriv->gadget); | ||
| 815 | |||
| 830 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); | 816 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); |
| 831 | } | 817 | } |
| 832 | 818 | ||
| @@ -876,12 +862,14 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | |||
| 876 | /* | 862 | /* |
| 877 | * init gadget | 863 | * init gadget |
| 878 | */ | 864 | */ |
| 879 | device_initialize(&gpriv->gadget.dev); | ||
| 880 | dev_set_name(&gpriv->gadget.dev, "gadget"); | 865 | dev_set_name(&gpriv->gadget.dev, "gadget"); |
| 881 | gpriv->gadget.dev.parent = dev; | 866 | gpriv->gadget.dev.parent = dev; |
| 882 | gpriv->gadget.name = "renesas_usbhs_udc"; | 867 | gpriv->gadget.name = "renesas_usbhs_udc"; |
| 883 | gpriv->gadget.ops = &usbhsg_gadget_ops; | 868 | gpriv->gadget.ops = &usbhsg_gadget_ops; |
| 884 | gpriv->gadget.is_dualspeed = 1; | 869 | gpriv->gadget.is_dualspeed = 1; |
| 870 | ret = device_register(&gpriv->gadget.dev); | ||
| 871 | if (ret < 0) | ||
| 872 | goto err_add_udc; | ||
| 885 | 873 | ||
| 886 | INIT_LIST_HEAD(&gpriv->gadget.ep_list); | 874 | INIT_LIST_HEAD(&gpriv->gadget.ep_list); |
| 887 | 875 | ||
| @@ -912,12 +900,15 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | |||
| 912 | 900 | ||
| 913 | ret = usb_add_gadget_udc(dev, &gpriv->gadget); | 901 | ret = usb_add_gadget_udc(dev, &gpriv->gadget); |
| 914 | if (ret) | 902 | if (ret) |
| 915 | goto err_add_udc; | 903 | goto err_register; |
| 916 | 904 | ||
| 917 | 905 | ||
| 918 | dev_info(dev, "gadget probed\n"); | 906 | dev_info(dev, "gadget probed\n"); |
| 919 | 907 | ||
| 920 | return 0; | 908 | return 0; |
| 909 | |||
| 910 | err_register: | ||
| 911 | device_unregister(&gpriv->gadget.dev); | ||
| 921 | err_add_udc: | 912 | err_add_udc: |
| 922 | kfree(gpriv->uep); | 913 | kfree(gpriv->uep); |
| 923 | 914 | ||
| @@ -933,6 +924,8 @@ void usbhs_mod_gadget_remove(struct usbhs_priv *priv) | |||
| 933 | 924 | ||
| 934 | usb_del_gadget_udc(&gpriv->gadget); | 925 | usb_del_gadget_udc(&gpriv->gadget); |
| 935 | 926 | ||
| 927 | device_unregister(&gpriv->gadget.dev); | ||
| 928 | |||
| 936 | usbhsg_controller_unregister(gpriv); | 929 | usbhsg_controller_unregister(gpriv); |
| 937 | 930 | ||
| 938 | kfree(gpriv->uep); | 931 | kfree(gpriv->uep); |
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index bade761a1e5..7955de58995 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/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index bd4298bb675..ff3db5d056a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -736,6 +736,7 @@ static struct usb_device_id id_table_combined [] = { | |||
| 736 | { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, | 736 | { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, |
| 737 | { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, | 737 | { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) }, |
| 738 | { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, | 738 | { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) }, |
| 739 | { USB_DEVICE(FTDI_VID, FTDI_PROPOX_ISPCABLEIII_PID) }, | ||
| 739 | { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), | 740 | { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), |
| 740 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 741 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
| 741 | { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID), | 742 | { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID), |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 571fa96b49c..055b64ef0bb 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
| @@ -112,6 +112,7 @@ | |||
| 112 | 112 | ||
| 113 | /* Propox devices */ | 113 | /* Propox devices */ |
| 114 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | 114 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 |
| 115 | #define FTDI_PROPOX_ISPCABLEIII_PID 0xD739 | ||
| 115 | 116 | ||
| 116 | /* Lenz LI-USB Computer Interface. */ | 117 | /* Lenz LI-USB Computer Interface. */ |
| 117 | #define FTDI_LENZ_LIUSB_PID 0xD780 | 118 | #define FTDI_LENZ_LIUSB_PID 0xD780 |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d865878c9f9..6dd64534fad 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -661,6 +661,14 @@ static const struct usb_device_id option_ids[] = { | |||
| 661 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) }, | 661 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) }, |
| 662 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) }, | 662 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) }, |
| 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) }, | ||
| 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, 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 */ | ||
| 664 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, | 672 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, |
| 665 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, | 673 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, |
| 666 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, | 674 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, |
| @@ -747,6 +755,7 @@ static const struct usb_device_id option_ids[] = { | |||
| 747 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, | 755 | { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, |
| 748 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ | 756 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ |
| 749 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 757 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
| 758 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ | ||
| 750 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ | 759 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ |
| 751 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, | 760 | { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, |
| 752 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, | 761 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 3041a974faf..24caba79d72 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
| @@ -1854,6 +1854,13 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110, | |||
| 1854 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 1854 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 1855 | US_FL_IGNORE_RESIDUE ), | 1855 | US_FL_IGNORE_RESIDUE ), |
| 1856 | 1856 | ||
| 1857 | /* Reported by Qinglin Ye <yestyle@gmail.com> */ | ||
| 1858 | UNUSUAL_DEV( 0x13fe, 0x3600, 0x0100, 0x0100, | ||
| 1859 | "Kingston", | ||
| 1860 | "DT 101 G2", | ||
| 1861 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 1862 | US_FL_BULK_IGNORE_TAG ), | ||
| 1863 | |||
| 1857 | /* Reported by Francesco Foresti <frafore@tiscali.it> */ | 1864 | /* Reported by Francesco Foresti <frafore@tiscali.it> */ |
| 1858 | UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201, | 1865 | UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201, |
| 1859 | "Super Top", | 1866 | "Super Top", |
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 8e964b91c44..284798aaf8b 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"\ |
