diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 18:22:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 18:22:42 -0400 |
commit | 2f9e825d3e0e2b407ae8f082de5c00afcf7378fb (patch) | |
tree | f8b3ee40674ce4acd5508a0a0bf52a30904caf6c /drivers/block | |
parent | 7ae0dea900b027cd90e8a3e14deca9a19e17638b (diff) | |
parent | de75d60d5ea235e6e09f4962ab22541ce0fe176a (diff) |
Merge branch 'for-2.6.36' of git://git.kernel.dk/linux-2.6-block
* 'for-2.6.36' of git://git.kernel.dk/linux-2.6-block: (149 commits)
block: make sure that REQ_* types are seen even with CONFIG_BLOCK=n
xen-blkfront: fix missing out label
blkdev: fix blkdev_issue_zeroout return value
block: update request stacking methods to support discards
block: fix missing export of blk_types.h
writeback: fix bad _bh spinlock nesting
drbd: revert "delay probes", feature is being re-implemented differently
drbd: Initialize all members of sync_conf to their defaults [Bugz 315]
drbd: Disable delay probes for the upcomming release
writeback: cleanup bdi_register
writeback: add new tracepoints
writeback: remove unnecessary init_timer call
writeback: optimize periodic bdi thread wakeups
writeback: prevent unnecessary bdi threads wakeups
writeback: move bdi threads exiting logic to the forker thread
writeback: restructure bdi forker loop a little
writeback: move last_active to bdi
writeback: do not remove bdi from bdi_list
writeback: simplify bdi code a little
writeback: do not lose wake-ups in bdi threads
...
Fixed up pretty trivial conflicts in drivers/block/virtio_blk.c and
drivers/scsi/scsi_error.c as per Jens.
Diffstat (limited to 'drivers/block')
39 files changed, 2568 insertions, 1869 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index c5f22bb0a48e..4e2c367fec11 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -79,23 +79,28 @@ static int DAC960_open(struct block_device *bdev, fmode_t mode) | |||
79 | struct gendisk *disk = bdev->bd_disk; | 79 | struct gendisk *disk = bdev->bd_disk; |
80 | DAC960_Controller_T *p = disk->queue->queuedata; | 80 | DAC960_Controller_T *p = disk->queue->queuedata; |
81 | int drive_nr = (long)disk->private_data; | 81 | int drive_nr = (long)disk->private_data; |
82 | int ret = -ENXIO; | ||
82 | 83 | ||
84 | lock_kernel(); | ||
83 | if (p->FirmwareType == DAC960_V1_Controller) { | 85 | if (p->FirmwareType == DAC960_V1_Controller) { |
84 | if (p->V1.LogicalDriveInformation[drive_nr]. | 86 | if (p->V1.LogicalDriveInformation[drive_nr]. |
85 | LogicalDriveState == DAC960_V1_LogicalDrive_Offline) | 87 | LogicalDriveState == DAC960_V1_LogicalDrive_Offline) |
86 | return -ENXIO; | 88 | goto out; |
87 | } else { | 89 | } else { |
88 | DAC960_V2_LogicalDeviceInfo_T *i = | 90 | DAC960_V2_LogicalDeviceInfo_T *i = |
89 | p->V2.LogicalDeviceInformation[drive_nr]; | 91 | p->V2.LogicalDeviceInformation[drive_nr]; |
90 | if (!i || i->LogicalDeviceState == DAC960_V2_LogicalDevice_Offline) | 92 | if (!i || i->LogicalDeviceState == DAC960_V2_LogicalDevice_Offline) |
91 | return -ENXIO; | 93 | goto out; |
92 | } | 94 | } |
93 | 95 | ||
94 | check_disk_change(bdev); | 96 | check_disk_change(bdev); |
95 | 97 | ||
96 | if (!get_capacity(p->disks[drive_nr])) | 98 | if (!get_capacity(p->disks[drive_nr])) |
97 | return -ENXIO; | 99 | goto out; |
98 | return 0; | 100 | ret = 0; |
101 | out: | ||
102 | unlock_kernel(); | ||
103 | return ret; | ||
99 | } | 104 | } |
100 | 105 | ||
101 | static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo) | 106 | static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 832798aa14f6..76f114f0bba3 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #include <linux/hdreg.h> | 60 | #include <linux/hdreg.h> |
61 | #include <linux/delay.h> | 61 | #include <linux/delay.h> |
62 | #include <linux/init.h> | 62 | #include <linux/init.h> |
63 | #include <linux/smp_lock.h> | ||
63 | #include <linux/amifdreg.h> | 64 | #include <linux/amifdreg.h> |
64 | #include <linux/amifd.h> | 65 | #include <linux/amifd.h> |
65 | #include <linux/buffer_head.h> | 66 | #include <linux/buffer_head.h> |
@@ -1423,7 +1424,7 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
1423 | return 0; | 1424 | return 0; |
1424 | } | 1425 | } |
1425 | 1426 | ||
1426 | static int fd_ioctl(struct block_device *bdev, fmode_t mode, | 1427 | static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, |
1427 | unsigned int cmd, unsigned long param) | 1428 | unsigned int cmd, unsigned long param) |
1428 | { | 1429 | { |
1429 | struct amiga_floppy_struct *p = bdev->bd_disk->private_data; | 1430 | struct amiga_floppy_struct *p = bdev->bd_disk->private_data; |
@@ -1500,6 +1501,18 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, | |||
1500 | return 0; | 1501 | return 0; |
1501 | } | 1502 | } |
1502 | 1503 | ||
1504 | static int fd_ioctl(struct block_device *bdev, fmode_t mode, | ||
1505 | unsigned int cmd, unsigned long param) | ||
1506 | { | ||
1507 | int ret; | ||
1508 | |||
1509 | lock_kernel(); | ||
1510 | ret = fd_locked_ioctl(bdev, mode, cmd, param); | ||
1511 | unlock_kernel(); | ||
1512 | |||
1513 | return ret; | ||
1514 | } | ||
1515 | |||
1503 | static void fd_probe(int dev) | 1516 | static void fd_probe(int dev) |
1504 | { | 1517 | { |
1505 | unsigned long code; | 1518 | unsigned long code; |
@@ -1542,10 +1555,13 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
1542 | int old_dev; | 1555 | int old_dev; |
1543 | unsigned long flags; | 1556 | unsigned long flags; |
1544 | 1557 | ||
1558 | lock_kernel(); | ||
1545 | old_dev = fd_device[drive]; | 1559 | old_dev = fd_device[drive]; |
1546 | 1560 | ||
1547 | if (fd_ref[drive] && old_dev != system) | 1561 | if (fd_ref[drive] && old_dev != system) { |
1562 | unlock_kernel(); | ||
1548 | return -EBUSY; | 1563 | return -EBUSY; |
1564 | } | ||
1549 | 1565 | ||
1550 | if (mode & (FMODE_READ|FMODE_WRITE)) { | 1566 | if (mode & (FMODE_READ|FMODE_WRITE)) { |
1551 | check_disk_change(bdev); | 1567 | check_disk_change(bdev); |
@@ -1558,8 +1574,10 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
1558 | fd_deselect (drive); | 1574 | fd_deselect (drive); |
1559 | rel_fdc(); | 1575 | rel_fdc(); |
1560 | 1576 | ||
1561 | if (wrprot) | 1577 | if (wrprot) { |
1578 | unlock_kernel(); | ||
1562 | return -EROFS; | 1579 | return -EROFS; |
1580 | } | ||
1563 | } | 1581 | } |
1564 | } | 1582 | } |
1565 | 1583 | ||
@@ -1576,6 +1594,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
1576 | printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive, | 1594 | printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive, |
1577 | unit[drive].type->name, data_types[system].name); | 1595 | unit[drive].type->name, data_types[system].name); |
1578 | 1596 | ||
1597 | unlock_kernel(); | ||
1579 | return 0; | 1598 | return 0; |
1580 | } | 1599 | } |
1581 | 1600 | ||
@@ -1584,6 +1603,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) | |||
1584 | struct amiga_floppy_struct *p = disk->private_data; | 1603 | struct amiga_floppy_struct *p = disk->private_data; |
1585 | int drive = p - unit; | 1604 | int drive = p - unit; |
1586 | 1605 | ||
1606 | lock_kernel(); | ||
1587 | if (unit[drive].dirty == 1) { | 1607 | if (unit[drive].dirty == 1) { |
1588 | del_timer (flush_track_timer + drive); | 1608 | del_timer (flush_track_timer + drive); |
1589 | non_int_flush_track (drive); | 1609 | non_int_flush_track (drive); |
@@ -1597,6 +1617,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) | |||
1597 | /* the mod_use counter is handled this way */ | 1617 | /* the mod_use counter is handled this way */ |
1598 | floppy_off (drive | 0x40000000); | 1618 | floppy_off (drive | 0x40000000); |
1599 | #endif | 1619 | #endif |
1620 | unlock_kernel(); | ||
1600 | return 0; | 1621 | return 0; |
1601 | } | 1622 | } |
1602 | 1623 | ||
@@ -1638,7 +1659,7 @@ static const struct block_device_operations floppy_fops = { | |||
1638 | .owner = THIS_MODULE, | 1659 | .owner = THIS_MODULE, |
1639 | .open = floppy_open, | 1660 | .open = floppy_open, |
1640 | .release = floppy_release, | 1661 | .release = floppy_release, |
1641 | .locked_ioctl = fd_ioctl, | 1662 | .ioctl = fd_ioctl, |
1642 | .getgeo = fd_getgeo, | 1663 | .getgeo = fd_getgeo, |
1643 | .media_changed = amiga_floppy_change, | 1664 | .media_changed = amiga_floppy_change, |
1644 | }; | 1665 | }; |
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 035cefe4045a..a946929735a5 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/genhd.h> | 13 | #include <linux/genhd.h> |
14 | #include <linux/netdevice.h> | 14 | #include <linux/netdevice.h> |
15 | #include <linux/smp_lock.h> | ||
15 | #include "aoe.h" | 16 | #include "aoe.h" |
16 | 17 | ||
17 | static struct kmem_cache *buf_pool_cache; | 18 | static struct kmem_cache *buf_pool_cache; |
@@ -124,13 +125,16 @@ aoeblk_open(struct block_device *bdev, fmode_t mode) | |||
124 | struct aoedev *d = bdev->bd_disk->private_data; | 125 | struct aoedev *d = bdev->bd_disk->private_data; |
125 | ulong flags; | 126 | ulong flags; |
126 | 127 | ||
128 | lock_kernel(); | ||
127 | spin_lock_irqsave(&d->lock, flags); | 129 | spin_lock_irqsave(&d->lock, flags); |
128 | if (d->flags & DEVFL_UP) { | 130 | if (d->flags & DEVFL_UP) { |
129 | d->nopen++; | 131 | d->nopen++; |
130 | spin_unlock_irqrestore(&d->lock, flags); | 132 | spin_unlock_irqrestore(&d->lock, flags); |
133 | unlock_kernel(); | ||
131 | return 0; | 134 | return 0; |
132 | } | 135 | } |
133 | spin_unlock_irqrestore(&d->lock, flags); | 136 | spin_unlock_irqrestore(&d->lock, flags); |
137 | unlock_kernel(); | ||
134 | return -ENODEV; | 138 | return -ENODEV; |
135 | } | 139 | } |
136 | 140 | ||
@@ -173,7 +177,7 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio) | |||
173 | BUG(); | 177 | BUG(); |
174 | bio_endio(bio, -ENXIO); | 178 | bio_endio(bio, -ENXIO); |
175 | return 0; | 179 | return 0; |
176 | } else if (bio_rw_flagged(bio, BIO_RW_BARRIER)) { | 180 | } else if (bio->bi_rw & REQ_HARDBARRIER) { |
177 | bio_endio(bio, -EOPNOTSUPP); | 181 | bio_endio(bio, -EOPNOTSUPP); |
178 | return 0; | 182 | return 0; |
179 | } else if (bio->bi_io_vec == NULL) { | 183 | } else if (bio->bi_io_vec == NULL) { |
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index e35cf59cbfde..aceb96476524 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #include <linux/delay.h> | 67 | #include <linux/delay.h> |
68 | #include <linux/init.h> | 68 | #include <linux/init.h> |
69 | #include <linux/blkdev.h> | 69 | #include <linux/blkdev.h> |
70 | #include <linux/smp_lock.h> | ||
70 | 71 | ||
71 | #include <asm/atafd.h> | 72 | #include <asm/atafd.h> |
72 | #include <asm/atafdreg.h> | 73 | #include <asm/atafdreg.h> |
@@ -359,7 +360,7 @@ static void finish_fdc( void ); | |||
359 | static void finish_fdc_done( int dummy ); | 360 | static void finish_fdc_done( int dummy ); |
360 | static void setup_req_params( int drive ); | 361 | static void setup_req_params( int drive ); |
361 | static void redo_fd_request( void); | 362 | static void redo_fd_request( void); |
362 | static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int | 363 | static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int |
363 | cmd, unsigned long param); | 364 | cmd, unsigned long param); |
364 | static void fd_probe( int drive ); | 365 | static void fd_probe( int drive ); |
365 | static int fd_test_drive_present( int drive ); | 366 | static int fd_test_drive_present( int drive ); |
@@ -1480,7 +1481,7 @@ void do_fd_request(struct request_queue * q) | |||
1480 | atari_enable_irq( IRQ_MFP_FDC ); | 1481 | atari_enable_irq( IRQ_MFP_FDC ); |
1481 | } | 1482 | } |
1482 | 1483 | ||
1483 | static int fd_ioctl(struct block_device *bdev, fmode_t mode, | 1484 | static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, |
1484 | unsigned int cmd, unsigned long param) | 1485 | unsigned int cmd, unsigned long param) |
1485 | { | 1486 | { |
1486 | struct gendisk *disk = bdev->bd_disk; | 1487 | struct gendisk *disk = bdev->bd_disk; |
@@ -1665,6 +1666,17 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, | |||
1665 | } | 1666 | } |
1666 | } | 1667 | } |
1667 | 1668 | ||
1669 | static int fd_ioctl(struct block_device *bdev, fmode_t mode, | ||
1670 | unsigned int cmd, unsigned long arg) | ||
1671 | { | ||
1672 | int ret; | ||
1673 | |||
1674 | lock_kernel(); | ||
1675 | ret = fd_locked_ioctl(bdev, mode, cmd, arg); | ||
1676 | unlock_kernel(); | ||
1677 | |||
1678 | return ret; | ||
1679 | } | ||
1668 | 1680 | ||
1669 | /* Initialize the 'unit' variable for drive 'drive' */ | 1681 | /* Initialize the 'unit' variable for drive 'drive' */ |
1670 | 1682 | ||
@@ -1838,24 +1850,36 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
1838 | return 0; | 1850 | return 0; |
1839 | } | 1851 | } |
1840 | 1852 | ||
1853 | static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode) | ||
1854 | { | ||
1855 | int ret; | ||
1856 | |||
1857 | lock_kernel(); | ||
1858 | ret = floppy_open(bdev, mode); | ||
1859 | unlock_kernel(); | ||
1860 | |||
1861 | return ret; | ||
1862 | } | ||
1841 | 1863 | ||
1842 | static int floppy_release(struct gendisk *disk, fmode_t mode) | 1864 | static int floppy_release(struct gendisk *disk, fmode_t mode) |
1843 | { | 1865 | { |
1844 | struct atari_floppy_struct *p = disk->private_data; | 1866 | struct atari_floppy_struct *p = disk->private_data; |
1867 | lock_kernel(); | ||
1845 | if (p->ref < 0) | 1868 | if (p->ref < 0) |
1846 | p->ref = 0; | 1869 | p->ref = 0; |
1847 | else if (!p->ref--) { | 1870 | else if (!p->ref--) { |
1848 | printk(KERN_ERR "floppy_release with fd_ref == 0"); | 1871 | printk(KERN_ERR "floppy_release with fd_ref == 0"); |
1849 | p->ref = 0; | 1872 | p->ref = 0; |
1850 | } | 1873 | } |
1874 | unlock_kernel(); | ||
1851 | return 0; | 1875 | return 0; |
1852 | } | 1876 | } |
1853 | 1877 | ||
1854 | static const struct block_device_operations floppy_fops = { | 1878 | static const struct block_device_operations floppy_fops = { |
1855 | .owner = THIS_MODULE, | 1879 | .owner = THIS_MODULE, |
1856 | .open = floppy_open, | 1880 | .open = floppy_unlocked_open, |
1857 | .release = floppy_release, | 1881 | .release = floppy_release, |
1858 | .locked_ioctl = fd_ioctl, | 1882 | .ioctl = fd_ioctl, |
1859 | .media_changed = check_floppy_change, | 1883 | .media_changed = check_floppy_change, |
1860 | .revalidate_disk= floppy_revalidate, | 1884 | .revalidate_disk= floppy_revalidate, |
1861 | }; | 1885 | }; |
diff --git a/drivers/block/brd.c b/drivers/block/brd.c index f1bf79d9bc0a..1c7f63792ff8 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/blkdev.h> | 15 | #include <linux/blkdev.h> |
16 | #include <linux/bio.h> | 16 | #include <linux/bio.h> |
17 | #include <linux/highmem.h> | 17 | #include <linux/highmem.h> |
18 | #include <linux/smp_lock.h> | ||
18 | #include <linux/radix-tree.h> | 19 | #include <linux/radix-tree.h> |
19 | #include <linux/buffer_head.h> /* invalidate_bh_lrus() */ | 20 | #include <linux/buffer_head.h> /* invalidate_bh_lrus() */ |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
@@ -340,7 +341,7 @@ static int brd_make_request(struct request_queue *q, struct bio *bio) | |||
340 | get_capacity(bdev->bd_disk)) | 341 | get_capacity(bdev->bd_disk)) |
341 | goto out; | 342 | goto out; |
342 | 343 | ||
343 | if (unlikely(bio_rw_flagged(bio, BIO_RW_DISCARD))) { | 344 | if (unlikely(bio->bi_rw & REQ_DISCARD)) { |
344 | err = 0; | 345 | err = 0; |
345 | discard_from_brd(brd, sector, bio->bi_size); | 346 | discard_from_brd(brd, sector, bio->bi_size); |
346 | goto out; | 347 | goto out; |
@@ -401,6 +402,7 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode, | |||
401 | * ram device BLKFLSBUF has special semantics, we want to actually | 402 | * ram device BLKFLSBUF has special semantics, we want to actually |
402 | * release and destroy the ramdisk data. | 403 | * release and destroy the ramdisk data. |
403 | */ | 404 | */ |
405 | lock_kernel(); | ||
404 | mutex_lock(&bdev->bd_mutex); | 406 | mutex_lock(&bdev->bd_mutex); |
405 | error = -EBUSY; | 407 | error = -EBUSY; |
406 | if (bdev->bd_openers <= 1) { | 408 | if (bdev->bd_openers <= 1) { |
@@ -417,13 +419,14 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode, | |||
417 | error = 0; | 419 | error = 0; |
418 | } | 420 | } |
419 | mutex_unlock(&bdev->bd_mutex); | 421 | mutex_unlock(&bdev->bd_mutex); |
422 | unlock_kernel(); | ||
420 | 423 | ||
421 | return error; | 424 | return error; |
422 | } | 425 | } |
423 | 426 | ||
424 | static const struct block_device_operations brd_fops = { | 427 | static const struct block_device_operations brd_fops = { |
425 | .owner = THIS_MODULE, | 428 | .owner = THIS_MODULE, |
426 | .locked_ioctl = brd_ioctl, | 429 | .ioctl = brd_ioctl, |
427 | #ifdef CONFIG_BLK_DEV_XIP | 430 | #ifdef CONFIG_BLK_DEV_XIP |
428 | .direct_access = brd_direct_access, | 431 | .direct_access = brd_direct_access, |
429 | #endif | 432 | #endif |
@@ -479,7 +482,7 @@ static struct brd_device *brd_alloc(int i) | |||
479 | if (!brd->brd_queue) | 482 | if (!brd->brd_queue) |
480 | goto out_free_dev; | 483 | goto out_free_dev; |
481 | blk_queue_make_request(brd->brd_queue, brd_make_request); | 484 | blk_queue_make_request(brd->brd_queue, brd_make_request); |
482 | blk_queue_ordered(brd->brd_queue, QUEUE_ORDERED_TAG, NULL); | 485 | blk_queue_ordered(brd->brd_queue, QUEUE_ORDERED_TAG); |
483 | blk_queue_max_hw_sectors(brd->brd_queue, 1024); | 486 | blk_queue_max_hw_sectors(brd->brd_queue, 1024); |
484 | blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY); | 487 | blk_queue_bounce_limit(brd->brd_queue, BLK_BOUNCE_ANY); |
485 | 488 | ||
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index e1e7143ca1e3..31064df1370a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -56,16 +56,14 @@ | |||
56 | #include <linux/kthread.h> | 56 | #include <linux/kthread.h> |
57 | 57 | ||
58 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) | 58 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) |
59 | #define DRIVER_NAME "HP CISS Driver (v 3.6.20)" | 59 | #define DRIVER_NAME "HP CISS Driver (v 3.6.26)" |
60 | #define DRIVER_VERSION CCISS_DRIVER_VERSION(3, 6, 20) | 60 | #define DRIVER_VERSION CCISS_DRIVER_VERSION(3, 6, 26) |
61 | 61 | ||
62 | /* Embedded module documentation macros - see modules.h */ | 62 | /* Embedded module documentation macros - see modules.h */ |
63 | MODULE_AUTHOR("Hewlett-Packard Company"); | 63 | MODULE_AUTHOR("Hewlett-Packard Company"); |
64 | MODULE_DESCRIPTION("Driver for HP Smart Array Controllers"); | 64 | MODULE_DESCRIPTION("Driver for HP Smart Array Controllers"); |
65 | MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" | 65 | MODULE_SUPPORTED_DEVICE("HP Smart Array Controllers"); |
66 | " SA6i P600 P800 P400 P400i E200 E200i E500 P700m" | 66 | MODULE_VERSION("3.6.26"); |
67 | " Smart Array G2 Series SAS/SATA Controllers"); | ||
68 | MODULE_VERSION("3.6.20"); | ||
69 | MODULE_LICENSE("GPL"); | 67 | MODULE_LICENSE("GPL"); |
70 | 68 | ||
71 | static int cciss_allow_hpsa; | 69 | static int cciss_allow_hpsa; |
@@ -107,6 +105,11 @@ static const struct pci_device_id cciss_pci_device_id[] = { | |||
107 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, | 105 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, |
108 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A}, | 106 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A}, |
109 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B}, | 107 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B}, |
108 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3250}, | ||
109 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3251}, | ||
110 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252}, | ||
111 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253}, | ||
112 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254}, | ||
110 | {0,} | 113 | {0,} |
111 | }; | 114 | }; |
112 | 115 | ||
@@ -146,6 +149,11 @@ static struct board_type products[] = { | |||
146 | {0x3249103C, "Smart Array P812", &SA5_access}, | 149 | {0x3249103C, "Smart Array P812", &SA5_access}, |
147 | {0x324A103C, "Smart Array P712m", &SA5_access}, | 150 | {0x324A103C, "Smart Array P712m", &SA5_access}, |
148 | {0x324B103C, "Smart Array P711m", &SA5_access}, | 151 | {0x324B103C, "Smart Array P711m", &SA5_access}, |
152 | {0x3250103C, "Smart Array", &SA5_access}, | ||
153 | {0x3251103C, "Smart Array", &SA5_access}, | ||
154 | {0x3252103C, "Smart Array", &SA5_access}, | ||
155 | {0x3253103C, "Smart Array", &SA5_access}, | ||
156 | {0x3254103C, "Smart Array", &SA5_access}, | ||
149 | }; | 157 | }; |
150 | 158 | ||
151 | /* How long to wait (in milliseconds) for board to go into simple mode */ | 159 | /* How long to wait (in milliseconds) for board to go into simple mode */ |
@@ -167,9 +175,13 @@ static DEFINE_MUTEX(scan_mutex); | |||
167 | static LIST_HEAD(scan_q); | 175 | static LIST_HEAD(scan_q); |
168 | 176 | ||
169 | static void do_cciss_request(struct request_queue *q); | 177 | static void do_cciss_request(struct request_queue *q); |
170 | static irqreturn_t do_cciss_intr(int irq, void *dev_id); | 178 | static irqreturn_t do_cciss_intx(int irq, void *dev_id); |
179 | static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id); | ||
171 | static int cciss_open(struct block_device *bdev, fmode_t mode); | 180 | static int cciss_open(struct block_device *bdev, fmode_t mode); |
181 | static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode); | ||
172 | static int cciss_release(struct gendisk *disk, fmode_t mode); | 182 | static int cciss_release(struct gendisk *disk, fmode_t mode); |
183 | static int do_ioctl(struct block_device *bdev, fmode_t mode, | ||
184 | unsigned int cmd, unsigned long arg); | ||
173 | static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | 185 | static int cciss_ioctl(struct block_device *bdev, fmode_t mode, |
174 | unsigned int cmd, unsigned long arg); | 186 | unsigned int cmd, unsigned long arg); |
175 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); | 187 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); |
@@ -179,25 +191,23 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl); | |||
179 | static int deregister_disk(ctlr_info_t *h, int drv_index, | 191 | static int deregister_disk(ctlr_info_t *h, int drv_index, |
180 | int clear_all, int via_ioctl); | 192 | int clear_all, int via_ioctl); |
181 | 193 | ||
182 | static void cciss_read_capacity(int ctlr, int logvol, | 194 | static void cciss_read_capacity(ctlr_info_t *h, int logvol, |
183 | sector_t *total_size, unsigned int *block_size); | 195 | sector_t *total_size, unsigned int *block_size); |
184 | static void cciss_read_capacity_16(int ctlr, int logvol, | 196 | static void cciss_read_capacity_16(ctlr_info_t *h, int logvol, |
185 | sector_t *total_size, unsigned int *block_size); | 197 | sector_t *total_size, unsigned int *block_size); |
186 | static void cciss_geometry_inquiry(int ctlr, int logvol, | 198 | static void cciss_geometry_inquiry(ctlr_info_t *h, int logvol, |
187 | sector_t total_size, | 199 | sector_t total_size, |
188 | unsigned int block_size, InquiryData_struct *inq_buff, | 200 | unsigned int block_size, InquiryData_struct *inq_buff, |
189 | drive_info_struct *drv); | 201 | drive_info_struct *drv); |
190 | static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, | 202 | static void __devinit cciss_interrupt_mode(ctlr_info_t *); |
191 | __u32); | ||
192 | static void start_io(ctlr_info_t *h); | 203 | static void start_io(ctlr_info_t *h); |
193 | static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size, | 204 | static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size, |
194 | __u8 page_code, unsigned char scsi3addr[], | 205 | __u8 page_code, unsigned char scsi3addr[], |
195 | int cmd_type); | 206 | int cmd_type); |
196 | static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c, | 207 | static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c, |
197 | int attempt_retry); | 208 | int attempt_retry); |
198 | static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c); | 209 | static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c); |
199 | 210 | ||
200 | static void fail_all_cmds(unsigned long ctlr); | ||
201 | static int add_to_scan_list(struct ctlr_info *h); | 211 | static int add_to_scan_list(struct ctlr_info *h); |
202 | static int scan_thread(void *data); | 212 | static int scan_thread(void *data); |
203 | static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c); | 213 | static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c); |
@@ -205,11 +215,23 @@ static void cciss_hba_release(struct device *dev); | |||
205 | static void cciss_device_release(struct device *dev); | 215 | static void cciss_device_release(struct device *dev); |
206 | static void cciss_free_gendisk(ctlr_info_t *h, int drv_index); | 216 | static void cciss_free_gendisk(ctlr_info_t *h, int drv_index); |
207 | static void cciss_free_drive_info(ctlr_info_t *h, int drv_index); | 217 | static void cciss_free_drive_info(ctlr_info_t *h, int drv_index); |
218 | static inline u32 next_command(ctlr_info_t *h); | ||
219 | static int __devinit cciss_find_cfg_addrs(struct pci_dev *pdev, | ||
220 | void __iomem *vaddr, u32 *cfg_base_addr, u64 *cfg_base_addr_index, | ||
221 | u64 *cfg_offset); | ||
222 | static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev, | ||
223 | unsigned long *memory_bar); | ||
224 | |||
225 | |||
226 | /* performant mode helper functions */ | ||
227 | static void calc_bucket_map(int *bucket, int num_buckets, int nsgs, | ||
228 | int *bucket_map); | ||
229 | static void cciss_put_controller_into_performant_mode(ctlr_info_t *h); | ||
208 | 230 | ||
209 | #ifdef CONFIG_PROC_FS | 231 | #ifdef CONFIG_PROC_FS |
210 | static void cciss_procinit(int i); | 232 | static void cciss_procinit(ctlr_info_t *h); |
211 | #else | 233 | #else |
212 | static void cciss_procinit(int i) | 234 | static void cciss_procinit(ctlr_info_t *h) |
213 | { | 235 | { |
214 | } | 236 | } |
215 | #endif /* CONFIG_PROC_FS */ | 237 | #endif /* CONFIG_PROC_FS */ |
@@ -221,9 +243,9 @@ static int cciss_compat_ioctl(struct block_device *, fmode_t, | |||
221 | 243 | ||
222 | static const struct block_device_operations cciss_fops = { | 244 | static const struct block_device_operations cciss_fops = { |
223 | .owner = THIS_MODULE, | 245 | .owner = THIS_MODULE, |
224 | .open = cciss_open, | 246 | .open = cciss_unlocked_open, |
225 | .release = cciss_release, | 247 | .release = cciss_release, |
226 | .locked_ioctl = cciss_ioctl, | 248 | .ioctl = do_ioctl, |
227 | .getgeo = cciss_getgeo, | 249 | .getgeo = cciss_getgeo, |
228 | #ifdef CONFIG_COMPAT | 250 | #ifdef CONFIG_COMPAT |
229 | .compat_ioctl = cciss_compat_ioctl, | 251 | .compat_ioctl = cciss_compat_ioctl, |
@@ -231,6 +253,16 @@ static const struct block_device_operations cciss_fops = { | |||
231 | .revalidate_disk = cciss_revalidate, | 253 | .revalidate_disk = cciss_revalidate, |
232 | }; | 254 | }; |
233 | 255 | ||
256 | /* set_performant_mode: Modify the tag for cciss performant | ||
257 | * set bit 0 for pull model, bits 3-1 for block fetch | ||
258 | * register number | ||
259 | */ | ||
260 | static void set_performant_mode(ctlr_info_t *h, CommandList_struct *c) | ||
261 | { | ||
262 | if (likely(h->transMethod == CFGTBL_Trans_Performant)) | ||
263 | c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1); | ||
264 | } | ||
265 | |||
234 | /* | 266 | /* |
235 | * Enqueuing and dequeuing functions for cmdlists. | 267 | * Enqueuing and dequeuing functions for cmdlists. |
236 | */ | 268 | */ |
@@ -257,6 +289,18 @@ static inline void removeQ(CommandList_struct *c) | |||
257 | hlist_del_init(&c->list); | 289 | hlist_del_init(&c->list); |
258 | } | 290 | } |
259 | 291 | ||
292 | static void enqueue_cmd_and_start_io(ctlr_info_t *h, | ||
293 | CommandList_struct *c) | ||
294 | { | ||
295 | unsigned long flags; | ||
296 | set_performant_mode(h, c); | ||
297 | spin_lock_irqsave(&h->lock, flags); | ||
298 | addQ(&h->reqQ, c); | ||
299 | h->Qdepth++; | ||
300 | start_io(h); | ||
301 | spin_unlock_irqrestore(&h->lock, flags); | ||
302 | } | ||
303 | |||
260 | static void cciss_free_sg_chain_blocks(SGDescriptor_struct **cmd_sg_list, | 304 | static void cciss_free_sg_chain_blocks(SGDescriptor_struct **cmd_sg_list, |
261 | int nr_cmds) | 305 | int nr_cmds) |
262 | { | 306 | { |
@@ -366,32 +410,31 @@ static void cciss_seq_show_header(struct seq_file *seq) | |||
366 | h->product_name, | 410 | h->product_name, |
367 | (unsigned long)h->board_id, | 411 | (unsigned long)h->board_id, |
368 | h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], | 412 | h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], |
369 | h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT], | 413 | h->firm_ver[3], (unsigned int)h->intr[PERF_MODE_INT], |
370 | h->num_luns, | 414 | h->num_luns, |
371 | h->Qdepth, h->commands_outstanding, | 415 | h->Qdepth, h->commands_outstanding, |
372 | h->maxQsinceinit, h->max_outstanding, h->maxSG); | 416 | h->maxQsinceinit, h->max_outstanding, h->maxSG); |
373 | 417 | ||
374 | #ifdef CONFIG_CISS_SCSI_TAPE | 418 | #ifdef CONFIG_CISS_SCSI_TAPE |
375 | cciss_seq_tape_report(seq, h->ctlr); | 419 | cciss_seq_tape_report(seq, h); |
376 | #endif /* CONFIG_CISS_SCSI_TAPE */ | 420 | #endif /* CONFIG_CISS_SCSI_TAPE */ |
377 | } | 421 | } |
378 | 422 | ||
379 | static void *cciss_seq_start(struct seq_file *seq, loff_t *pos) | 423 | static void *cciss_seq_start(struct seq_file *seq, loff_t *pos) |
380 | { | 424 | { |
381 | ctlr_info_t *h = seq->private; | 425 | ctlr_info_t *h = seq->private; |
382 | unsigned ctlr = h->ctlr; | ||
383 | unsigned long flags; | 426 | unsigned long flags; |
384 | 427 | ||
385 | /* prevent displaying bogus info during configuration | 428 | /* prevent displaying bogus info during configuration |
386 | * or deconfiguration of a logical volume | 429 | * or deconfiguration of a logical volume |
387 | */ | 430 | */ |
388 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | 431 | spin_lock_irqsave(&h->lock, flags); |
389 | if (h->busy_configuring) { | 432 | if (h->busy_configuring) { |
390 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 433 | spin_unlock_irqrestore(&h->lock, flags); |
391 | return ERR_PTR(-EBUSY); | 434 | return ERR_PTR(-EBUSY); |
392 | } | 435 | } |
393 | h->busy_configuring = 1; | 436 | h->busy_configuring = 1; |
394 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 437 | spin_unlock_irqrestore(&h->lock, flags); |
395 | 438 | ||
396 | if (*pos == 0) | 439 | if (*pos == 0) |
397 | cciss_seq_show_header(seq); | 440 | cciss_seq_show_header(seq); |
@@ -499,7 +542,7 @@ cciss_proc_write(struct file *file, const char __user *buf, | |||
499 | struct seq_file *seq = file->private_data; | 542 | struct seq_file *seq = file->private_data; |
500 | ctlr_info_t *h = seq->private; | 543 | ctlr_info_t *h = seq->private; |
501 | 544 | ||
502 | err = cciss_engage_scsi(h->ctlr); | 545 | err = cciss_engage_scsi(h); |
503 | if (err == 0) | 546 | if (err == 0) |
504 | err = length; | 547 | err = length; |
505 | } else | 548 | } else |
@@ -522,7 +565,7 @@ static const struct file_operations cciss_proc_fops = { | |||
522 | .write = cciss_proc_write, | 565 | .write = cciss_proc_write, |
523 | }; | 566 | }; |
524 | 567 | ||
525 | static void __devinit cciss_procinit(int i) | 568 | static void __devinit cciss_procinit(ctlr_info_t *h) |
526 | { | 569 | { |
527 | struct proc_dir_entry *pde; | 570 | struct proc_dir_entry *pde; |
528 | 571 | ||
@@ -530,9 +573,9 @@ static void __devinit cciss_procinit(int i) | |||
530 | proc_cciss = proc_mkdir("driver/cciss", NULL); | 573 | proc_cciss = proc_mkdir("driver/cciss", NULL); |
531 | if (!proc_cciss) | 574 | if (!proc_cciss) |
532 | return; | 575 | return; |
533 | pde = proc_create_data(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP | | 576 | pde = proc_create_data(h->devname, S_IWUSR | S_IRUSR | S_IRGRP | |
534 | S_IROTH, proc_cciss, | 577 | S_IROTH, proc_cciss, |
535 | &cciss_proc_fops, hba[i]); | 578 | &cciss_proc_fops, h); |
536 | } | 579 | } |
537 | #endif /* CONFIG_PROC_FS */ | 580 | #endif /* CONFIG_PROC_FS */ |
538 | 581 | ||
@@ -565,12 +608,12 @@ static ssize_t dev_show_unique_id(struct device *dev, | |||
565 | unsigned long flags; | 608 | unsigned long flags; |
566 | int ret = 0; | 609 | int ret = 0; |
567 | 610 | ||
568 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 611 | spin_lock_irqsave(&h->lock, flags); |
569 | if (h->busy_configuring) | 612 | if (h->busy_configuring) |
570 | ret = -EBUSY; | 613 | ret = -EBUSY; |
571 | else | 614 | else |
572 | memcpy(sn, drv->serial_no, sizeof(sn)); | 615 | memcpy(sn, drv->serial_no, sizeof(sn)); |
573 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 616 | spin_unlock_irqrestore(&h->lock, flags); |
574 | 617 | ||
575 | if (ret) | 618 | if (ret) |
576 | return ret; | 619 | return ret; |
@@ -595,12 +638,12 @@ static ssize_t dev_show_vendor(struct device *dev, | |||
595 | unsigned long flags; | 638 | unsigned long flags; |
596 | int ret = 0; | 639 | int ret = 0; |
597 | 640 | ||
598 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 641 | spin_lock_irqsave(&h->lock, flags); |
599 | if (h->busy_configuring) | 642 | if (h->busy_configuring) |
600 | ret = -EBUSY; | 643 | ret = -EBUSY; |
601 | else | 644 | else |
602 | memcpy(vendor, drv->vendor, VENDOR_LEN + 1); | 645 | memcpy(vendor, drv->vendor, VENDOR_LEN + 1); |
603 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 646 | spin_unlock_irqrestore(&h->lock, flags); |
604 | 647 | ||
605 | if (ret) | 648 | if (ret) |
606 | return ret; | 649 | return ret; |
@@ -619,12 +662,12 @@ static ssize_t dev_show_model(struct device *dev, | |||
619 | unsigned long flags; | 662 | unsigned long flags; |
620 | int ret = 0; | 663 | int ret = 0; |
621 | 664 | ||
622 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 665 | spin_lock_irqsave(&h->lock, flags); |
623 | if (h->busy_configuring) | 666 | if (h->busy_configuring) |
624 | ret = -EBUSY; | 667 | ret = -EBUSY; |
625 | else | 668 | else |
626 | memcpy(model, drv->model, MODEL_LEN + 1); | 669 | memcpy(model, drv->model, MODEL_LEN + 1); |
627 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 670 | spin_unlock_irqrestore(&h->lock, flags); |
628 | 671 | ||
629 | if (ret) | 672 | if (ret) |
630 | return ret; | 673 | return ret; |
@@ -643,12 +686,12 @@ static ssize_t dev_show_rev(struct device *dev, | |||
643 | unsigned long flags; | 686 | unsigned long flags; |
644 | int ret = 0; | 687 | int ret = 0; |
645 | 688 | ||
646 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 689 | spin_lock_irqsave(&h->lock, flags); |
647 | if (h->busy_configuring) | 690 | if (h->busy_configuring) |
648 | ret = -EBUSY; | 691 | ret = -EBUSY; |
649 | else | 692 | else |
650 | memcpy(rev, drv->rev, REV_LEN + 1); | 693 | memcpy(rev, drv->rev, REV_LEN + 1); |
651 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 694 | spin_unlock_irqrestore(&h->lock, flags); |
652 | 695 | ||
653 | if (ret) | 696 | if (ret) |
654 | return ret; | 697 | return ret; |
@@ -665,17 +708,17 @@ static ssize_t cciss_show_lunid(struct device *dev, | |||
665 | unsigned long flags; | 708 | unsigned long flags; |
666 | unsigned char lunid[8]; | 709 | unsigned char lunid[8]; |
667 | 710 | ||
668 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 711 | spin_lock_irqsave(&h->lock, flags); |
669 | if (h->busy_configuring) { | 712 | if (h->busy_configuring) { |
670 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 713 | spin_unlock_irqrestore(&h->lock, flags); |
671 | return -EBUSY; | 714 | return -EBUSY; |
672 | } | 715 | } |
673 | if (!drv->heads) { | 716 | if (!drv->heads) { |
674 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 717 | spin_unlock_irqrestore(&h->lock, flags); |
675 | return -ENOTTY; | 718 | return -ENOTTY; |
676 | } | 719 | } |
677 | memcpy(lunid, drv->LunID, sizeof(lunid)); | 720 | memcpy(lunid, drv->LunID, sizeof(lunid)); |
678 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 721 | spin_unlock_irqrestore(&h->lock, flags); |
679 | return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", | 722 | return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", |
680 | lunid[0], lunid[1], lunid[2], lunid[3], | 723 | lunid[0], lunid[1], lunid[2], lunid[3], |
681 | lunid[4], lunid[5], lunid[6], lunid[7]); | 724 | lunid[4], lunid[5], lunid[6], lunid[7]); |
@@ -690,13 +733,13 @@ static ssize_t cciss_show_raid_level(struct device *dev, | |||
690 | int raid; | 733 | int raid; |
691 | unsigned long flags; | 734 | unsigned long flags; |
692 | 735 | ||
693 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 736 | spin_lock_irqsave(&h->lock, flags); |
694 | if (h->busy_configuring) { | 737 | if (h->busy_configuring) { |
695 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 738 | spin_unlock_irqrestore(&h->lock, flags); |
696 | return -EBUSY; | 739 | return -EBUSY; |
697 | } | 740 | } |
698 | raid = drv->raid_level; | 741 | raid = drv->raid_level; |
699 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 742 | spin_unlock_irqrestore(&h->lock, flags); |
700 | if (raid < 0 || raid > RAID_UNKNOWN) | 743 | if (raid < 0 || raid > RAID_UNKNOWN) |
701 | raid = RAID_UNKNOWN; | 744 | raid = RAID_UNKNOWN; |
702 | 745 | ||
@@ -713,13 +756,13 @@ static ssize_t cciss_show_usage_count(struct device *dev, | |||
713 | unsigned long flags; | 756 | unsigned long flags; |
714 | int count; | 757 | int count; |
715 | 758 | ||
716 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 759 | spin_lock_irqsave(&h->lock, flags); |
717 | if (h->busy_configuring) { | 760 | if (h->busy_configuring) { |
718 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 761 | spin_unlock_irqrestore(&h->lock, flags); |
719 | return -EBUSY; | 762 | return -EBUSY; |
720 | } | 763 | } |
721 | count = drv->usage_count; | 764 | count = drv->usage_count; |
722 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 765 | spin_unlock_irqrestore(&h->lock, flags); |
723 | return snprintf(buf, 20, "%d\n", count); | 766 | return snprintf(buf, 20, "%d\n", count); |
724 | } | 767 | } |
725 | static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); | 768 | static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); |
@@ -864,60 +907,70 @@ static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index, | |||
864 | /* | 907 | /* |
865 | * For operations that cannot sleep, a command block is allocated at init, | 908 | * For operations that cannot sleep, a command block is allocated at init, |
866 | * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track | 909 | * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track |
867 | * which ones are free or in use. For operations that can wait for kmalloc | 910 | * which ones are free or in use. |
868 | * to possible sleep, this routine can be called with get_from_pool set to 0. | ||
869 | * cmd_free() MUST be called with a got_from_pool set to 0 if cmd_alloc was. | ||
870 | */ | 911 | */ |
871 | static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool) | 912 | static CommandList_struct *cmd_alloc(ctlr_info_t *h) |
872 | { | 913 | { |
873 | CommandList_struct *c; | 914 | CommandList_struct *c; |
874 | int i; | 915 | int i; |
875 | u64bit temp64; | 916 | u64bit temp64; |
876 | dma_addr_t cmd_dma_handle, err_dma_handle; | 917 | dma_addr_t cmd_dma_handle, err_dma_handle; |
877 | 918 | ||
878 | if (!get_from_pool) { | 919 | do { |
879 | c = (CommandList_struct *) pci_alloc_consistent(h->pdev, | 920 | i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds); |
880 | sizeof(CommandList_struct), &cmd_dma_handle); | 921 | if (i == h->nr_cmds) |
881 | if (c == NULL) | ||
882 | return NULL; | 922 | return NULL; |
883 | memset(c, 0, sizeof(CommandList_struct)); | 923 | } while (test_and_set_bit(i & (BITS_PER_LONG - 1), |
924 | h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0); | ||
925 | c = h->cmd_pool + i; | ||
926 | memset(c, 0, sizeof(CommandList_struct)); | ||
927 | cmd_dma_handle = h->cmd_pool_dhandle + i * sizeof(CommandList_struct); | ||
928 | c->err_info = h->errinfo_pool + i; | ||
929 | memset(c->err_info, 0, sizeof(ErrorInfo_struct)); | ||
930 | err_dma_handle = h->errinfo_pool_dhandle | ||
931 | + i * sizeof(ErrorInfo_struct); | ||
932 | h->nr_allocs++; | ||
884 | 933 | ||
885 | c->cmdindex = -1; | 934 | c->cmdindex = i; |
886 | 935 | ||
887 | c->err_info = (ErrorInfo_struct *) | 936 | INIT_HLIST_NODE(&c->list); |
888 | pci_alloc_consistent(h->pdev, sizeof(ErrorInfo_struct), | 937 | c->busaddr = (__u32) cmd_dma_handle; |
889 | &err_dma_handle); | 938 | temp64.val = (__u64) err_dma_handle; |
939 | c->ErrDesc.Addr.lower = temp64.val32.lower; | ||
940 | c->ErrDesc.Addr.upper = temp64.val32.upper; | ||
941 | c->ErrDesc.Len = sizeof(ErrorInfo_struct); | ||
890 | 942 | ||
891 | if (c->err_info == NULL) { | 943 | c->ctlr = h->ctlr; |
892 | pci_free_consistent(h->pdev, | 944 | return c; |
893 | sizeof(CommandList_struct), c, cmd_dma_handle); | 945 | } |
894 | return NULL; | ||
895 | } | ||
896 | memset(c->err_info, 0, sizeof(ErrorInfo_struct)); | ||
897 | } else { /* get it out of the controllers pool */ | ||
898 | |||
899 | do { | ||
900 | i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds); | ||
901 | if (i == h->nr_cmds) | ||
902 | return NULL; | ||
903 | } while (test_and_set_bit | ||
904 | (i & (BITS_PER_LONG - 1), | ||
905 | h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0); | ||
906 | #ifdef CCISS_DEBUG | ||
907 | printk(KERN_DEBUG "cciss: using command buffer %d\n", i); | ||
908 | #endif | ||
909 | c = h->cmd_pool + i; | ||
910 | memset(c, 0, sizeof(CommandList_struct)); | ||
911 | cmd_dma_handle = h->cmd_pool_dhandle | ||
912 | + i * sizeof(CommandList_struct); | ||
913 | c->err_info = h->errinfo_pool + i; | ||
914 | memset(c->err_info, 0, sizeof(ErrorInfo_struct)); | ||
915 | err_dma_handle = h->errinfo_pool_dhandle | ||
916 | + i * sizeof(ErrorInfo_struct); | ||
917 | h->nr_allocs++; | ||
918 | 946 | ||
919 | c->cmdindex = i; | 947 | /* allocate a command using pci_alloc_consistent, used for ioctls, |
948 | * etc., not for the main i/o path. | ||
949 | */ | ||
950 | static CommandList_struct *cmd_special_alloc(ctlr_info_t *h) | ||
951 | { | ||
952 | CommandList_struct *c; | ||
953 | u64bit temp64; | ||
954 | dma_addr_t cmd_dma_handle, err_dma_handle; | ||
955 | |||
956 | c = (CommandList_struct *) pci_alloc_consistent(h->pdev, | ||
957 | sizeof(CommandList_struct), &cmd_dma_handle); | ||
958 | if (c == NULL) | ||
959 | return NULL; | ||
960 | memset(c, 0, sizeof(CommandList_struct)); | ||
961 | |||
962 | c->cmdindex = -1; | ||
963 | |||
964 | c->err_info = (ErrorInfo_struct *) | ||
965 | pci_alloc_consistent(h->pdev, sizeof(ErrorInfo_struct), | ||
966 | &err_dma_handle); | ||
967 | |||
968 | if (c->err_info == NULL) { | ||
969 | pci_free_consistent(h->pdev, | ||
970 | sizeof(CommandList_struct), c, cmd_dma_handle); | ||
971 | return NULL; | ||
920 | } | 972 | } |
973 | memset(c->err_info, 0, sizeof(ErrorInfo_struct)); | ||
921 | 974 | ||
922 | INIT_HLIST_NODE(&c->list); | 975 | INIT_HLIST_NODE(&c->list); |
923 | c->busaddr = (__u32) cmd_dma_handle; | 976 | c->busaddr = (__u32) cmd_dma_handle; |
@@ -930,27 +983,26 @@ static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool) | |||
930 | return c; | 983 | return c; |
931 | } | 984 | } |
932 | 985 | ||
933 | /* | 986 | static void cmd_free(ctlr_info_t *h, CommandList_struct *c) |
934 | * Frees a command block that was previously allocated with cmd_alloc(). | ||
935 | */ | ||
936 | static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool) | ||
937 | { | 987 | { |
938 | int i; | 988 | int i; |
989 | |||
990 | i = c - h->cmd_pool; | ||
991 | clear_bit(i & (BITS_PER_LONG - 1), | ||
992 | h->cmd_pool_bits + (i / BITS_PER_LONG)); | ||
993 | h->nr_frees++; | ||
994 | } | ||
995 | |||
996 | static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c) | ||
997 | { | ||
939 | u64bit temp64; | 998 | u64bit temp64; |
940 | 999 | ||
941 | if (!got_from_pool) { | 1000 | temp64.val32.lower = c->ErrDesc.Addr.lower; |
942 | temp64.val32.lower = c->ErrDesc.Addr.lower; | 1001 | temp64.val32.upper = c->ErrDesc.Addr.upper; |
943 | temp64.val32.upper = c->ErrDesc.Addr.upper; | 1002 | pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct), |
944 | pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct), | 1003 | c->err_info, (dma_addr_t) temp64.val); |
945 | c->err_info, (dma_addr_t) temp64.val); | 1004 | pci_free_consistent(h->pdev, sizeof(CommandList_struct), |
946 | pci_free_consistent(h->pdev, sizeof(CommandList_struct), | 1005 | c, (dma_addr_t) c->busaddr); |
947 | c, (dma_addr_t) c->busaddr); | ||
948 | } else { | ||
949 | i = c - h->cmd_pool; | ||
950 | clear_bit(i & (BITS_PER_LONG - 1), | ||
951 | h->cmd_pool_bits + (i / BITS_PER_LONG)); | ||
952 | h->nr_frees++; | ||
953 | } | ||
954 | } | 1006 | } |
955 | 1007 | ||
956 | static inline ctlr_info_t *get_host(struct gendisk *disk) | 1008 | static inline ctlr_info_t *get_host(struct gendisk *disk) |
@@ -968,13 +1020,10 @@ static inline drive_info_struct *get_drv(struct gendisk *disk) | |||
968 | */ | 1020 | */ |
969 | static int cciss_open(struct block_device *bdev, fmode_t mode) | 1021 | static int cciss_open(struct block_device *bdev, fmode_t mode) |
970 | { | 1022 | { |
971 | ctlr_info_t *host = get_host(bdev->bd_disk); | 1023 | ctlr_info_t *h = get_host(bdev->bd_disk); |
972 | drive_info_struct *drv = get_drv(bdev->bd_disk); | 1024 | drive_info_struct *drv = get_drv(bdev->bd_disk); |
973 | 1025 | ||
974 | #ifdef CCISS_DEBUG | 1026 | dev_dbg(&h->pdev->dev, "cciss_open %s\n", bdev->bd_disk->disk_name); |
975 | printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name); | ||
976 | #endif /* CCISS_DEBUG */ | ||
977 | |||
978 | if (drv->busy_configuring) | 1027 | if (drv->busy_configuring) |
979 | return -EBUSY; | 1028 | return -EBUSY; |
980 | /* | 1029 | /* |
@@ -1000,29 +1049,39 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) | |||
1000 | return -EPERM; | 1049 | return -EPERM; |
1001 | } | 1050 | } |
1002 | drv->usage_count++; | 1051 | drv->usage_count++; |
1003 | host->usage_count++; | 1052 | h->usage_count++; |
1004 | return 0; | 1053 | return 0; |
1005 | } | 1054 | } |
1006 | 1055 | ||
1056 | static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode) | ||
1057 | { | ||
1058 | int ret; | ||
1059 | |||
1060 | lock_kernel(); | ||
1061 | ret = cciss_open(bdev, mode); | ||
1062 | unlock_kernel(); | ||
1063 | |||
1064 | return ret; | ||
1065 | } | ||
1066 | |||
1007 | /* | 1067 | /* |
1008 | * Close. Sync first. | 1068 | * Close. Sync first. |
1009 | */ | 1069 | */ |
1010 | static int cciss_release(struct gendisk *disk, fmode_t mode) | 1070 | static int cciss_release(struct gendisk *disk, fmode_t mode) |
1011 | { | 1071 | { |
1012 | ctlr_info_t *host = get_host(disk); | 1072 | ctlr_info_t *h; |
1013 | drive_info_struct *drv = get_drv(disk); | 1073 | drive_info_struct *drv; |
1014 | |||
1015 | #ifdef CCISS_DEBUG | ||
1016 | printk(KERN_DEBUG "cciss_release %s\n", disk->disk_name); | ||
1017 | #endif /* CCISS_DEBUG */ | ||
1018 | 1074 | ||
1075 | lock_kernel(); | ||
1076 | h = get_host(disk); | ||
1077 | drv = get_drv(disk); | ||
1078 | dev_dbg(&h->pdev->dev, "cciss_release %s\n", disk->disk_name); | ||
1019 | drv->usage_count--; | 1079 | drv->usage_count--; |
1020 | host->usage_count--; | 1080 | h->usage_count--; |
1081 | unlock_kernel(); | ||
1021 | return 0; | 1082 | return 0; |
1022 | } | 1083 | } |
1023 | 1084 | ||
1024 | #ifdef CONFIG_COMPAT | ||
1025 | |||
1026 | static int do_ioctl(struct block_device *bdev, fmode_t mode, | 1085 | static int do_ioctl(struct block_device *bdev, fmode_t mode, |
1027 | unsigned cmd, unsigned long arg) | 1086 | unsigned cmd, unsigned long arg) |
1028 | { | 1087 | { |
@@ -1033,6 +1092,8 @@ static int do_ioctl(struct block_device *bdev, fmode_t mode, | |||
1033 | return ret; | 1092 | return ret; |
1034 | } | 1093 | } |
1035 | 1094 | ||
1095 | #ifdef CONFIG_COMPAT | ||
1096 | |||
1036 | static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, | 1097 | static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, |
1037 | unsigned cmd, unsigned long arg); | 1098 | unsigned cmd, unsigned long arg); |
1038 | static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode, | 1099 | static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode, |
@@ -1163,11 +1224,11 @@ static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
1163 | return 0; | 1224 | return 0; |
1164 | } | 1225 | } |
1165 | 1226 | ||
1166 | static void check_ioctl_unit_attention(ctlr_info_t *host, CommandList_struct *c) | 1227 | static void check_ioctl_unit_attention(ctlr_info_t *h, CommandList_struct *c) |
1167 | { | 1228 | { |
1168 | if (c->err_info->CommandStatus == CMD_TARGET_STATUS && | 1229 | if (c->err_info->CommandStatus == CMD_TARGET_STATUS && |
1169 | c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) | 1230 | c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) |
1170 | (void)check_for_unit_attention(host, c); | 1231 | (void)check_for_unit_attention(h, c); |
1171 | } | 1232 | } |
1172 | /* | 1233 | /* |
1173 | * ioctl | 1234 | * ioctl |
@@ -1176,15 +1237,12 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1176 | unsigned int cmd, unsigned long arg) | 1237 | unsigned int cmd, unsigned long arg) |
1177 | { | 1238 | { |
1178 | struct gendisk *disk = bdev->bd_disk; | 1239 | struct gendisk *disk = bdev->bd_disk; |
1179 | ctlr_info_t *host = get_host(disk); | 1240 | ctlr_info_t *h = get_host(disk); |
1180 | drive_info_struct *drv = get_drv(disk); | 1241 | drive_info_struct *drv = get_drv(disk); |
1181 | int ctlr = host->ctlr; | ||
1182 | void __user *argp = (void __user *)arg; | 1242 | void __user *argp = (void __user *)arg; |
1183 | 1243 | ||
1184 | #ifdef CCISS_DEBUG | 1244 | dev_dbg(&h->pdev->dev, "cciss_ioctl: Called with cmd=%x %lx\n", |
1185 | printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg); | 1245 | cmd, arg); |
1186 | #endif /* CCISS_DEBUG */ | ||
1187 | |||
1188 | switch (cmd) { | 1246 | switch (cmd) { |
1189 | case CCISS_GETPCIINFO: | 1247 | case CCISS_GETPCIINFO: |
1190 | { | 1248 | { |
@@ -1192,10 +1250,10 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1192 | 1250 | ||
1193 | if (!arg) | 1251 | if (!arg) |
1194 | return -EINVAL; | 1252 | return -EINVAL; |
1195 | pciinfo.domain = pci_domain_nr(host->pdev->bus); | 1253 | pciinfo.domain = pci_domain_nr(h->pdev->bus); |
1196 | pciinfo.bus = host->pdev->bus->number; | 1254 | pciinfo.bus = h->pdev->bus->number; |
1197 | pciinfo.dev_fn = host->pdev->devfn; | 1255 | pciinfo.dev_fn = h->pdev->devfn; |
1198 | pciinfo.board_id = host->board_id; | 1256 | pciinfo.board_id = h->board_id; |
1199 | if (copy_to_user | 1257 | if (copy_to_user |
1200 | (argp, &pciinfo, sizeof(cciss_pci_info_struct))) | 1258 | (argp, &pciinfo, sizeof(cciss_pci_info_struct))) |
1201 | return -EFAULT; | 1259 | return -EFAULT; |
@@ -1207,9 +1265,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1207 | if (!arg) | 1265 | if (!arg) |
1208 | return -EINVAL; | 1266 | return -EINVAL; |
1209 | intinfo.delay = | 1267 | intinfo.delay = |
1210 | readl(&host->cfgtable->HostWrite.CoalIntDelay); | 1268 | readl(&h->cfgtable->HostWrite.CoalIntDelay); |
1211 | intinfo.count = | 1269 | intinfo.count = |
1212 | readl(&host->cfgtable->HostWrite.CoalIntCount); | 1270 | readl(&h->cfgtable->HostWrite.CoalIntCount); |
1213 | if (copy_to_user | 1271 | if (copy_to_user |
1214 | (argp, &intinfo, sizeof(cciss_coalint_struct))) | 1272 | (argp, &intinfo, sizeof(cciss_coalint_struct))) |
1215 | return -EFAULT; | 1273 | return -EFAULT; |
@@ -1229,26 +1287,23 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1229 | (&intinfo, argp, sizeof(cciss_coalint_struct))) | 1287 | (&intinfo, argp, sizeof(cciss_coalint_struct))) |
1230 | return -EFAULT; | 1288 | return -EFAULT; |
1231 | if ((intinfo.delay == 0) && (intinfo.count == 0)) | 1289 | if ((intinfo.delay == 0) && (intinfo.count == 0)) |
1232 | { | ||
1233 | // printk("cciss_ioctl: delay and count cannot be 0\n"); | ||
1234 | return -EINVAL; | 1290 | return -EINVAL; |
1235 | } | 1291 | spin_lock_irqsave(&h->lock, flags); |
1236 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | ||
1237 | /* Update the field, and then ring the doorbell */ | 1292 | /* Update the field, and then ring the doorbell */ |
1238 | writel(intinfo.delay, | 1293 | writel(intinfo.delay, |
1239 | &(host->cfgtable->HostWrite.CoalIntDelay)); | 1294 | &(h->cfgtable->HostWrite.CoalIntDelay)); |
1240 | writel(intinfo.count, | 1295 | writel(intinfo.count, |
1241 | &(host->cfgtable->HostWrite.CoalIntCount)); | 1296 | &(h->cfgtable->HostWrite.CoalIntCount)); |
1242 | writel(CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL); | 1297 | writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); |
1243 | 1298 | ||
1244 | for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) { | 1299 | for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) { |
1245 | if (!(readl(host->vaddr + SA5_DOORBELL) | 1300 | if (!(readl(h->vaddr + SA5_DOORBELL) |
1246 | & CFGTBL_ChangeReq)) | 1301 | & CFGTBL_ChangeReq)) |
1247 | break; | 1302 | break; |
1248 | /* delay and try again */ | 1303 | /* delay and try again */ |
1249 | udelay(1000); | 1304 | udelay(1000); |
1250 | } | 1305 | } |
1251 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1306 | spin_unlock_irqrestore(&h->lock, flags); |
1252 | if (i >= MAX_IOCTL_CONFIG_WAIT) | 1307 | if (i >= MAX_IOCTL_CONFIG_WAIT) |
1253 | return -EAGAIN; | 1308 | return -EAGAIN; |
1254 | return 0; | 1309 | return 0; |
@@ -1262,7 +1317,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1262 | return -EINVAL; | 1317 | return -EINVAL; |
1263 | for (i = 0; i < 16; i++) | 1318 | for (i = 0; i < 16; i++) |
1264 | NodeName[i] = | 1319 | NodeName[i] = |
1265 | readb(&host->cfgtable->ServerName[i]); | 1320 | readb(&h->cfgtable->ServerName[i]); |
1266 | if (copy_to_user(argp, NodeName, sizeof(NodeName_type))) | 1321 | if (copy_to_user(argp, NodeName, sizeof(NodeName_type))) |
1267 | return -EFAULT; | 1322 | return -EFAULT; |
1268 | return 0; | 1323 | return 0; |
@@ -1282,23 +1337,23 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1282 | (NodeName, argp, sizeof(NodeName_type))) | 1337 | (NodeName, argp, sizeof(NodeName_type))) |
1283 | return -EFAULT; | 1338 | return -EFAULT; |
1284 | 1339 | ||
1285 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | 1340 | spin_lock_irqsave(&h->lock, flags); |
1286 | 1341 | ||
1287 | /* Update the field, and then ring the doorbell */ | 1342 | /* Update the field, and then ring the doorbell */ |
1288 | for (i = 0; i < 16; i++) | 1343 | for (i = 0; i < 16; i++) |
1289 | writeb(NodeName[i], | 1344 | writeb(NodeName[i], |
1290 | &host->cfgtable->ServerName[i]); | 1345 | &h->cfgtable->ServerName[i]); |
1291 | 1346 | ||
1292 | writel(CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL); | 1347 | writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); |
1293 | 1348 | ||
1294 | for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) { | 1349 | for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) { |
1295 | if (!(readl(host->vaddr + SA5_DOORBELL) | 1350 | if (!(readl(h->vaddr + SA5_DOORBELL) |
1296 | & CFGTBL_ChangeReq)) | 1351 | & CFGTBL_ChangeReq)) |
1297 | break; | 1352 | break; |
1298 | /* delay and try again */ | 1353 | /* delay and try again */ |
1299 | udelay(1000); | 1354 | udelay(1000); |
1300 | } | 1355 | } |
1301 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1356 | spin_unlock_irqrestore(&h->lock, flags); |
1302 | if (i >= MAX_IOCTL_CONFIG_WAIT) | 1357 | if (i >= MAX_IOCTL_CONFIG_WAIT) |
1303 | return -EAGAIN; | 1358 | return -EAGAIN; |
1304 | return 0; | 1359 | return 0; |
@@ -1310,7 +1365,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1310 | 1365 | ||
1311 | if (!arg) | 1366 | if (!arg) |
1312 | return -EINVAL; | 1367 | return -EINVAL; |
1313 | heartbeat = readl(&host->cfgtable->HeartBeat); | 1368 | heartbeat = readl(&h->cfgtable->HeartBeat); |
1314 | if (copy_to_user | 1369 | if (copy_to_user |
1315 | (argp, &heartbeat, sizeof(Heartbeat_type))) | 1370 | (argp, &heartbeat, sizeof(Heartbeat_type))) |
1316 | return -EFAULT; | 1371 | return -EFAULT; |
@@ -1322,7 +1377,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1322 | 1377 | ||
1323 | if (!arg) | 1378 | if (!arg) |
1324 | return -EINVAL; | 1379 | return -EINVAL; |
1325 | BusTypes = readl(&host->cfgtable->BusTypes); | 1380 | BusTypes = readl(&h->cfgtable->BusTypes); |
1326 | if (copy_to_user | 1381 | if (copy_to_user |
1327 | (argp, &BusTypes, sizeof(BusTypes_type))) | 1382 | (argp, &BusTypes, sizeof(BusTypes_type))) |
1328 | return -EFAULT; | 1383 | return -EFAULT; |
@@ -1334,7 +1389,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1334 | 1389 | ||
1335 | if (!arg) | 1390 | if (!arg) |
1336 | return -EINVAL; | 1391 | return -EINVAL; |
1337 | memcpy(firmware, host->firm_ver, 4); | 1392 | memcpy(firmware, h->firm_ver, 4); |
1338 | 1393 | ||
1339 | if (copy_to_user | 1394 | if (copy_to_user |
1340 | (argp, firmware, sizeof(FirmwareVer_type))) | 1395 | (argp, firmware, sizeof(FirmwareVer_type))) |
@@ -1357,7 +1412,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1357 | case CCISS_DEREGDISK: | 1412 | case CCISS_DEREGDISK: |
1358 | case CCISS_REGNEWD: | 1413 | case CCISS_REGNEWD: |
1359 | case CCISS_REVALIDVOLS: | 1414 | case CCISS_REVALIDVOLS: |
1360 | return rebuild_lun_table(host, 0, 1); | 1415 | return rebuild_lun_table(h, 0, 1); |
1361 | 1416 | ||
1362 | case CCISS_GETLUNINFO:{ | 1417 | case CCISS_GETLUNINFO:{ |
1363 | LogvolInfo_struct luninfo; | 1418 | LogvolInfo_struct luninfo; |
@@ -1377,7 +1432,6 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1377 | CommandList_struct *c; | 1432 | CommandList_struct *c; |
1378 | char *buff = NULL; | 1433 | char *buff = NULL; |
1379 | u64bit temp64; | 1434 | u64bit temp64; |
1380 | unsigned long flags; | ||
1381 | DECLARE_COMPLETION_ONSTACK(wait); | 1435 | DECLARE_COMPLETION_ONSTACK(wait); |
1382 | 1436 | ||
1383 | if (!arg) | 1437 | if (!arg) |
@@ -1413,7 +1467,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1413 | } else { | 1467 | } else { |
1414 | memset(buff, 0, iocommand.buf_size); | 1468 | memset(buff, 0, iocommand.buf_size); |
1415 | } | 1469 | } |
1416 | if ((c = cmd_alloc(host, 0)) == NULL) { | 1470 | c = cmd_special_alloc(h); |
1471 | if (!c) { | ||
1417 | kfree(buff); | 1472 | kfree(buff); |
1418 | return -ENOMEM; | 1473 | return -ENOMEM; |
1419 | } | 1474 | } |
@@ -1439,7 +1494,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1439 | 1494 | ||
1440 | /* Fill in the scatter gather information */ | 1495 | /* Fill in the scatter gather information */ |
1441 | if (iocommand.buf_size > 0) { | 1496 | if (iocommand.buf_size > 0) { |
1442 | temp64.val = pci_map_single(host->pdev, buff, | 1497 | temp64.val = pci_map_single(h->pdev, buff, |
1443 | iocommand.buf_size, | 1498 | iocommand.buf_size, |
1444 | PCI_DMA_BIDIRECTIONAL); | 1499 | PCI_DMA_BIDIRECTIONAL); |
1445 | c->SG[0].Addr.lower = temp64.val32.lower; | 1500 | c->SG[0].Addr.lower = temp64.val32.lower; |
@@ -1449,30 +1504,24 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1449 | } | 1504 | } |
1450 | c->waiting = &wait; | 1505 | c->waiting = &wait; |
1451 | 1506 | ||
1452 | /* Put the request on the tail of the request queue */ | 1507 | enqueue_cmd_and_start_io(h, c); |
1453 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | ||
1454 | addQ(&host->reqQ, c); | ||
1455 | host->Qdepth++; | ||
1456 | start_io(host); | ||
1457 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | ||
1458 | |||
1459 | wait_for_completion(&wait); | 1508 | wait_for_completion(&wait); |
1460 | 1509 | ||
1461 | /* unlock the buffers from DMA */ | 1510 | /* unlock the buffers from DMA */ |
1462 | temp64.val32.lower = c->SG[0].Addr.lower; | 1511 | temp64.val32.lower = c->SG[0].Addr.lower; |
1463 | temp64.val32.upper = c->SG[0].Addr.upper; | 1512 | temp64.val32.upper = c->SG[0].Addr.upper; |
1464 | pci_unmap_single(host->pdev, (dma_addr_t) temp64.val, | 1513 | pci_unmap_single(h->pdev, (dma_addr_t) temp64.val, |
1465 | iocommand.buf_size, | 1514 | iocommand.buf_size, |
1466 | PCI_DMA_BIDIRECTIONAL); | 1515 | PCI_DMA_BIDIRECTIONAL); |
1467 | 1516 | ||
1468 | check_ioctl_unit_attention(host, c); | 1517 | check_ioctl_unit_attention(h, c); |
1469 | 1518 | ||
1470 | /* Copy the error information out */ | 1519 | /* Copy the error information out */ |
1471 | iocommand.error_info = *(c->err_info); | 1520 | iocommand.error_info = *(c->err_info); |
1472 | if (copy_to_user | 1521 | if (copy_to_user |
1473 | (argp, &iocommand, sizeof(IOCTL_Command_struct))) { | 1522 | (argp, &iocommand, sizeof(IOCTL_Command_struct))) { |
1474 | kfree(buff); | 1523 | kfree(buff); |
1475 | cmd_free(host, c, 0); | 1524 | cmd_special_free(h, c); |
1476 | return -EFAULT; | 1525 | return -EFAULT; |
1477 | } | 1526 | } |
1478 | 1527 | ||
@@ -1481,12 +1530,12 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1481 | if (copy_to_user | 1530 | if (copy_to_user |
1482 | (iocommand.buf, buff, iocommand.buf_size)) { | 1531 | (iocommand.buf, buff, iocommand.buf_size)) { |
1483 | kfree(buff); | 1532 | kfree(buff); |
1484 | cmd_free(host, c, 0); | 1533 | cmd_special_free(h, c); |
1485 | return -EFAULT; | 1534 | return -EFAULT; |
1486 | } | 1535 | } |
1487 | } | 1536 | } |
1488 | kfree(buff); | 1537 | kfree(buff); |
1489 | cmd_free(host, c, 0); | 1538 | cmd_special_free(h, c); |
1490 | return 0; | 1539 | return 0; |
1491 | } | 1540 | } |
1492 | case CCISS_BIG_PASSTHRU:{ | 1541 | case CCISS_BIG_PASSTHRU:{ |
@@ -1495,7 +1544,6 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1495 | unsigned char **buff = NULL; | 1544 | unsigned char **buff = NULL; |
1496 | int *buff_size = NULL; | 1545 | int *buff_size = NULL; |
1497 | u64bit temp64; | 1546 | u64bit temp64; |
1498 | unsigned long flags; | ||
1499 | BYTE sg_used = 0; | 1547 | BYTE sg_used = 0; |
1500 | int status = 0; | 1548 | int status = 0; |
1501 | int i; | 1549 | int i; |
@@ -1569,7 +1617,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1569 | data_ptr += sz; | 1617 | data_ptr += sz; |
1570 | sg_used++; | 1618 | sg_used++; |
1571 | } | 1619 | } |
1572 | if ((c = cmd_alloc(host, 0)) == NULL) { | 1620 | c = cmd_special_alloc(h); |
1621 | if (!c) { | ||
1573 | status = -ENOMEM; | 1622 | status = -ENOMEM; |
1574 | goto cleanup1; | 1623 | goto cleanup1; |
1575 | } | 1624 | } |
@@ -1590,7 +1639,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1590 | if (ioc->buf_size > 0) { | 1639 | if (ioc->buf_size > 0) { |
1591 | for (i = 0; i < sg_used; i++) { | 1640 | for (i = 0; i < sg_used; i++) { |
1592 | temp64.val = | 1641 | temp64.val = |
1593 | pci_map_single(host->pdev, buff[i], | 1642 | pci_map_single(h->pdev, buff[i], |
1594 | buff_size[i], | 1643 | buff_size[i], |
1595 | PCI_DMA_BIDIRECTIONAL); | 1644 | PCI_DMA_BIDIRECTIONAL); |
1596 | c->SG[i].Addr.lower = | 1645 | c->SG[i].Addr.lower = |
@@ -1602,26 +1651,21 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1602 | } | 1651 | } |
1603 | } | 1652 | } |
1604 | c->waiting = &wait; | 1653 | c->waiting = &wait; |
1605 | /* Put the request on the tail of the request queue */ | 1654 | enqueue_cmd_and_start_io(h, c); |
1606 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | ||
1607 | addQ(&host->reqQ, c); | ||
1608 | host->Qdepth++; | ||
1609 | start_io(host); | ||
1610 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | ||
1611 | wait_for_completion(&wait); | 1655 | wait_for_completion(&wait); |
1612 | /* unlock the buffers from DMA */ | 1656 | /* unlock the buffers from DMA */ |
1613 | for (i = 0; i < sg_used; i++) { | 1657 | for (i = 0; i < sg_used; i++) { |
1614 | temp64.val32.lower = c->SG[i].Addr.lower; | 1658 | temp64.val32.lower = c->SG[i].Addr.lower; |
1615 | temp64.val32.upper = c->SG[i].Addr.upper; | 1659 | temp64.val32.upper = c->SG[i].Addr.upper; |
1616 | pci_unmap_single(host->pdev, | 1660 | pci_unmap_single(h->pdev, |
1617 | (dma_addr_t) temp64.val, buff_size[i], | 1661 | (dma_addr_t) temp64.val, buff_size[i], |
1618 | PCI_DMA_BIDIRECTIONAL); | 1662 | PCI_DMA_BIDIRECTIONAL); |
1619 | } | 1663 | } |
1620 | check_ioctl_unit_attention(host, c); | 1664 | check_ioctl_unit_attention(h, c); |
1621 | /* Copy the error information out */ | 1665 | /* Copy the error information out */ |
1622 | ioc->error_info = *(c->err_info); | 1666 | ioc->error_info = *(c->err_info); |
1623 | if (copy_to_user(argp, ioc, sizeof(*ioc))) { | 1667 | if (copy_to_user(argp, ioc, sizeof(*ioc))) { |
1624 | cmd_free(host, c, 0); | 1668 | cmd_special_free(h, c); |
1625 | status = -EFAULT; | 1669 | status = -EFAULT; |
1626 | goto cleanup1; | 1670 | goto cleanup1; |
1627 | } | 1671 | } |
@@ -1631,14 +1675,14 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, | |||
1631 | for (i = 0; i < sg_used; i++) { | 1675 | for (i = 0; i < sg_used; i++) { |
1632 | if (copy_to_user | 1676 | if (copy_to_user |
1633 | (ptr, buff[i], buff_size[i])) { | 1677 | (ptr, buff[i], buff_size[i])) { |
1634 | cmd_free(host, c, 0); | 1678 | cmd_special_free(h, c); |
1635 | status = -EFAULT; | 1679 | status = -EFAULT; |
1636 | goto cleanup1; | 1680 | goto cleanup1; |
1637 | } | 1681 | } |
1638 | ptr += buff_size[i]; | 1682 | ptr += buff_size[i]; |
1639 | } | 1683 | } |
1640 | } | 1684 | } |
1641 | cmd_free(host, c, 0); | 1685 | cmd_special_free(h, c); |
1642 | status = 0; | 1686 | status = 0; |
1643 | cleanup1: | 1687 | cleanup1: |
1644 | if (buff) { | 1688 | if (buff) { |
@@ -1726,26 +1770,26 @@ static void cciss_check_queues(ctlr_info_t *h) | |||
1726 | 1770 | ||
1727 | static void cciss_softirq_done(struct request *rq) | 1771 | static void cciss_softirq_done(struct request *rq) |
1728 | { | 1772 | { |
1729 | CommandList_struct *cmd = rq->completion_data; | 1773 | CommandList_struct *c = rq->completion_data; |
1730 | ctlr_info_t *h = hba[cmd->ctlr]; | 1774 | ctlr_info_t *h = hba[c->ctlr]; |
1731 | SGDescriptor_struct *curr_sg = cmd->SG; | 1775 | SGDescriptor_struct *curr_sg = c->SG; |
1732 | unsigned long flags; | ||
1733 | u64bit temp64; | 1776 | u64bit temp64; |
1777 | unsigned long flags; | ||
1734 | int i, ddir; | 1778 | int i, ddir; |
1735 | int sg_index = 0; | 1779 | int sg_index = 0; |
1736 | 1780 | ||
1737 | if (cmd->Request.Type.Direction == XFER_READ) | 1781 | if (c->Request.Type.Direction == XFER_READ) |
1738 | ddir = PCI_DMA_FROMDEVICE; | 1782 | ddir = PCI_DMA_FROMDEVICE; |
1739 | else | 1783 | else |
1740 | ddir = PCI_DMA_TODEVICE; | 1784 | ddir = PCI_DMA_TODEVICE; |
1741 | 1785 | ||
1742 | /* command did not need to be retried */ | 1786 | /* command did not need to be retried */ |
1743 | /* unmap the DMA mapping for all the scatter gather elements */ | 1787 | /* unmap the DMA mapping for all the scatter gather elements */ |
1744 | for (i = 0; i < cmd->Header.SGList; i++) { | 1788 | for (i = 0; i < c->Header.SGList; i++) { |
1745 | if (curr_sg[sg_index].Ext == CCISS_SG_CHAIN) { | 1789 | if (curr_sg[sg_index].Ext == CCISS_SG_CHAIN) { |
1746 | cciss_unmap_sg_chain_block(h, cmd); | 1790 | cciss_unmap_sg_chain_block(h, c); |
1747 | /* Point to the next block */ | 1791 | /* Point to the next block */ |
1748 | curr_sg = h->cmd_sg_list[cmd->cmdindex]; | 1792 | curr_sg = h->cmd_sg_list[c->cmdindex]; |
1749 | sg_index = 0; | 1793 | sg_index = 0; |
1750 | } | 1794 | } |
1751 | temp64.val32.lower = curr_sg[sg_index].Addr.lower; | 1795 | temp64.val32.lower = curr_sg[sg_index].Addr.lower; |
@@ -1755,18 +1799,16 @@ static void cciss_softirq_done(struct request *rq) | |||
1755 | ++sg_index; | 1799 | ++sg_index; |
1756 | } | 1800 | } |
1757 | 1801 | ||
1758 | #ifdef CCISS_DEBUG | 1802 | dev_dbg(&h->pdev->dev, "Done with %p\n", rq); |
1759 | printk("Done with %p\n", rq); | ||
1760 | #endif /* CCISS_DEBUG */ | ||
1761 | 1803 | ||
1762 | /* set the residual count for pc requests */ | 1804 | /* set the residual count for pc requests */ |
1763 | if (blk_pc_request(rq)) | 1805 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) |
1764 | rq->resid_len = cmd->err_info->ResidualCnt; | 1806 | rq->resid_len = c->err_info->ResidualCnt; |
1765 | 1807 | ||
1766 | blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO); | 1808 | blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO); |
1767 | 1809 | ||
1768 | spin_lock_irqsave(&h->lock, flags); | 1810 | spin_lock_irqsave(&h->lock, flags); |
1769 | cmd_free(h, cmd, 1); | 1811 | cmd_free(h, c); |
1770 | cciss_check_queues(h); | 1812 | cciss_check_queues(h); |
1771 | spin_unlock_irqrestore(&h->lock, flags); | 1813 | spin_unlock_irqrestore(&h->lock, flags); |
1772 | } | 1814 | } |
@@ -1782,7 +1824,7 @@ static inline void log_unit_to_scsi3addr(ctlr_info_t *h, | |||
1782 | * via the inquiry page 0. Model, vendor, and rev are set to empty strings if | 1824 | * via the inquiry page 0. Model, vendor, and rev are set to empty strings if |
1783 | * they cannot be read. | 1825 | * they cannot be read. |
1784 | */ | 1826 | */ |
1785 | static void cciss_get_device_descr(int ctlr, int logvol, | 1827 | static void cciss_get_device_descr(ctlr_info_t *h, int logvol, |
1786 | char *vendor, char *model, char *rev) | 1828 | char *vendor, char *model, char *rev) |
1787 | { | 1829 | { |
1788 | int rc; | 1830 | int rc; |
@@ -1797,8 +1839,8 @@ static void cciss_get_device_descr(int ctlr, int logvol, | |||
1797 | if (!inq_buf) | 1839 | if (!inq_buf) |
1798 | return; | 1840 | return; |
1799 | 1841 | ||
1800 | log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol); | 1842 | log_unit_to_scsi3addr(h, scsi3addr, logvol); |
1801 | rc = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buf, sizeof(*inq_buf), 0, | 1843 | rc = sendcmd_withirq(h, CISS_INQUIRY, inq_buf, sizeof(*inq_buf), 0, |
1802 | scsi3addr, TYPE_CMD); | 1844 | scsi3addr, TYPE_CMD); |
1803 | if (rc == IO_OK) { | 1845 | if (rc == IO_OK) { |
1804 | memcpy(vendor, &inq_buf->data_byte[8], VENDOR_LEN); | 1846 | memcpy(vendor, &inq_buf->data_byte[8], VENDOR_LEN); |
@@ -1818,7 +1860,7 @@ static void cciss_get_device_descr(int ctlr, int logvol, | |||
1818 | * number cannot be had, for whatever reason, 16 bytes of 0xff | 1860 | * number cannot be had, for whatever reason, 16 bytes of 0xff |
1819 | * are returned instead. | 1861 | * are returned instead. |
1820 | */ | 1862 | */ |
1821 | static void cciss_get_serial_no(int ctlr, int logvol, | 1863 | static void cciss_get_serial_no(ctlr_info_t *h, int logvol, |
1822 | unsigned char *serial_no, int buflen) | 1864 | unsigned char *serial_no, int buflen) |
1823 | { | 1865 | { |
1824 | #define PAGE_83_INQ_BYTES 64 | 1866 | #define PAGE_83_INQ_BYTES 64 |
@@ -1833,8 +1875,8 @@ static void cciss_get_serial_no(int ctlr, int logvol, | |||
1833 | if (!buf) | 1875 | if (!buf) |
1834 | return; | 1876 | return; |
1835 | memset(serial_no, 0, buflen); | 1877 | memset(serial_no, 0, buflen); |
1836 | log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol); | 1878 | log_unit_to_scsi3addr(h, scsi3addr, logvol); |
1837 | rc = sendcmd_withirq(CISS_INQUIRY, ctlr, buf, | 1879 | rc = sendcmd_withirq(h, CISS_INQUIRY, buf, |
1838 | PAGE_83_INQ_BYTES, 0x83, scsi3addr, TYPE_CMD); | 1880 | PAGE_83_INQ_BYTES, 0x83, scsi3addr, TYPE_CMD); |
1839 | if (rc == IO_OK) | 1881 | if (rc == IO_OK) |
1840 | memcpy(serial_no, &buf[8], buflen); | 1882 | memcpy(serial_no, &buf[8], buflen); |
@@ -1900,10 +1942,9 @@ init_queue_failure: | |||
1900 | * is also the controller node. Any changes to disk 0 will show up on | 1942 | * is also the controller node. Any changes to disk 0 will show up on |
1901 | * the next reboot. | 1943 | * the next reboot. |
1902 | */ | 1944 | */ |
1903 | static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, | 1945 | static void cciss_update_drive_info(ctlr_info_t *h, int drv_index, |
1904 | int via_ioctl) | 1946 | int first_time, int via_ioctl) |
1905 | { | 1947 | { |
1906 | ctlr_info_t *h = hba[ctlr]; | ||
1907 | struct gendisk *disk; | 1948 | struct gendisk *disk; |
1908 | InquiryData_struct *inq_buff = NULL; | 1949 | InquiryData_struct *inq_buff = NULL; |
1909 | unsigned int block_size; | 1950 | unsigned int block_size; |
@@ -1920,16 +1961,16 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, | |||
1920 | 1961 | ||
1921 | /* testing to see if 16-byte CDBs are already being used */ | 1962 | /* testing to see if 16-byte CDBs are already being used */ |
1922 | if (h->cciss_read == CCISS_READ_16) { | 1963 | if (h->cciss_read == CCISS_READ_16) { |
1923 | cciss_read_capacity_16(h->ctlr, drv_index, | 1964 | cciss_read_capacity_16(h, drv_index, |
1924 | &total_size, &block_size); | 1965 | &total_size, &block_size); |
1925 | 1966 | ||
1926 | } else { | 1967 | } else { |
1927 | cciss_read_capacity(ctlr, drv_index, &total_size, &block_size); | 1968 | cciss_read_capacity(h, drv_index, &total_size, &block_size); |
1928 | /* if read_capacity returns all F's this volume is >2TB */ | 1969 | /* if read_capacity returns all F's this volume is >2TB */ |
1929 | /* in size so we switch to 16-byte CDB's for all */ | 1970 | /* in size so we switch to 16-byte CDB's for all */ |
1930 | /* read/write ops */ | 1971 | /* read/write ops */ |
1931 | if (total_size == 0xFFFFFFFFULL) { | 1972 | if (total_size == 0xFFFFFFFFULL) { |
1932 | cciss_read_capacity_16(ctlr, drv_index, | 1973 | cciss_read_capacity_16(h, drv_index, |
1933 | &total_size, &block_size); | 1974 | &total_size, &block_size); |
1934 | h->cciss_read = CCISS_READ_16; | 1975 | h->cciss_read = CCISS_READ_16; |
1935 | h->cciss_write = CCISS_WRITE_16; | 1976 | h->cciss_write = CCISS_WRITE_16; |
@@ -1939,14 +1980,14 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, | |||
1939 | } | 1980 | } |
1940 | } | 1981 | } |
1941 | 1982 | ||
1942 | cciss_geometry_inquiry(ctlr, drv_index, total_size, block_size, | 1983 | cciss_geometry_inquiry(h, drv_index, total_size, block_size, |
1943 | inq_buff, drvinfo); | 1984 | inq_buff, drvinfo); |
1944 | drvinfo->block_size = block_size; | 1985 | drvinfo->block_size = block_size; |
1945 | drvinfo->nr_blocks = total_size + 1; | 1986 | drvinfo->nr_blocks = total_size + 1; |
1946 | 1987 | ||
1947 | cciss_get_device_descr(ctlr, drv_index, drvinfo->vendor, | 1988 | cciss_get_device_descr(h, drv_index, drvinfo->vendor, |
1948 | drvinfo->model, drvinfo->rev); | 1989 | drvinfo->model, drvinfo->rev); |
1949 | cciss_get_serial_no(ctlr, drv_index, drvinfo->serial_no, | 1990 | cciss_get_serial_no(h, drv_index, drvinfo->serial_no, |
1950 | sizeof(drvinfo->serial_no)); | 1991 | sizeof(drvinfo->serial_no)); |
1951 | /* Save the lunid in case we deregister the disk, below. */ | 1992 | /* Save the lunid in case we deregister the disk, below. */ |
1952 | memcpy(drvinfo->LunID, h->drv[drv_index]->LunID, | 1993 | memcpy(drvinfo->LunID, h->drv[drv_index]->LunID, |
@@ -1971,10 +2012,10 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, | |||
1971 | * (unless it's the first disk (for the controller node). | 2012 | * (unless it's the first disk (for the controller node). |
1972 | */ | 2013 | */ |
1973 | if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) { | 2014 | if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) { |
1974 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); | 2015 | dev_warn(&h->pdev->dev, "disk %d has changed.\n", drv_index); |
1975 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 2016 | spin_lock_irqsave(&h->lock, flags); |
1976 | h->drv[drv_index]->busy_configuring = 1; | 2017 | h->drv[drv_index]->busy_configuring = 1; |
1977 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 2018 | spin_unlock_irqrestore(&h->lock, flags); |
1978 | 2019 | ||
1979 | /* deregister_disk sets h->drv[drv_index]->queue = NULL | 2020 | /* deregister_disk sets h->drv[drv_index]->queue = NULL |
1980 | * which keeps the interrupt handler from starting | 2021 | * which keeps the interrupt handler from starting |
@@ -2024,8 +2065,8 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, | |||
2024 | if (cciss_add_disk(h, disk, drv_index) != 0) { | 2065 | if (cciss_add_disk(h, disk, drv_index) != 0) { |
2025 | cciss_free_gendisk(h, drv_index); | 2066 | cciss_free_gendisk(h, drv_index); |
2026 | cciss_free_drive_info(h, drv_index); | 2067 | cciss_free_drive_info(h, drv_index); |
2027 | printk(KERN_WARNING "cciss:%d could not update " | 2068 | dev_warn(&h->pdev->dev, "could not update disk %d\n", |
2028 | "disk %d\n", h->ctlr, drv_index); | 2069 | drv_index); |
2029 | --h->num_luns; | 2070 | --h->num_luns; |
2030 | } | 2071 | } |
2031 | } | 2072 | } |
@@ -2035,7 +2076,7 @@ freeret: | |||
2035 | kfree(drvinfo); | 2076 | kfree(drvinfo); |
2036 | return; | 2077 | return; |
2037 | mem_msg: | 2078 | mem_msg: |
2038 | printk(KERN_ERR "cciss: out of memory\n"); | 2079 | dev_err(&h->pdev->dev, "out of memory\n"); |
2039 | goto freeret; | 2080 | goto freeret; |
2040 | } | 2081 | } |
2041 | 2082 | ||
@@ -2127,9 +2168,9 @@ static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[], | |||
2127 | h->gendisk[drv_index] = | 2168 | h->gendisk[drv_index] = |
2128 | alloc_disk(1 << NWD_SHIFT); | 2169 | alloc_disk(1 << NWD_SHIFT); |
2129 | if (!h->gendisk[drv_index]) { | 2170 | if (!h->gendisk[drv_index]) { |
2130 | printk(KERN_ERR "cciss%d: could not " | 2171 | dev_err(&h->pdev->dev, |
2131 | "allocate a new disk %d\n", | 2172 | "could not allocate a new disk %d\n", |
2132 | h->ctlr, drv_index); | 2173 | drv_index); |
2133 | goto err_free_drive_info; | 2174 | goto err_free_drive_info; |
2134 | } | 2175 | } |
2135 | } | 2176 | } |
@@ -2180,8 +2221,7 @@ static void cciss_add_controller_node(ctlr_info_t *h) | |||
2180 | cciss_free_gendisk(h, drv_index); | 2221 | cciss_free_gendisk(h, drv_index); |
2181 | cciss_free_drive_info(h, drv_index); | 2222 | cciss_free_drive_info(h, drv_index); |
2182 | error: | 2223 | error: |
2183 | printk(KERN_WARNING "cciss%d: could not " | 2224 | dev_warn(&h->pdev->dev, "could not add disk 0.\n"); |
2184 | "add disk 0.\n", h->ctlr); | ||
2185 | return; | 2225 | return; |
2186 | } | 2226 | } |
2187 | 2227 | ||
@@ -2196,7 +2236,6 @@ error: | |||
2196 | static int rebuild_lun_table(ctlr_info_t *h, int first_time, | 2236 | static int rebuild_lun_table(ctlr_info_t *h, int first_time, |
2197 | int via_ioctl) | 2237 | int via_ioctl) |
2198 | { | 2238 | { |
2199 | int ctlr = h->ctlr; | ||
2200 | int num_luns; | 2239 | int num_luns; |
2201 | ReportLunData_struct *ld_buff = NULL; | 2240 | ReportLunData_struct *ld_buff = NULL; |
2202 | int return_code; | 2241 | int return_code; |
@@ -2211,27 +2250,27 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, | |||
2211 | return -EPERM; | 2250 | return -EPERM; |
2212 | 2251 | ||
2213 | /* Set busy_configuring flag for this operation */ | 2252 | /* Set busy_configuring flag for this operation */ |
2214 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 2253 | spin_lock_irqsave(&h->lock, flags); |
2215 | if (h->busy_configuring) { | 2254 | if (h->busy_configuring) { |
2216 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 2255 | spin_unlock_irqrestore(&h->lock, flags); |
2217 | return -EBUSY; | 2256 | return -EBUSY; |
2218 | } | 2257 | } |
2219 | h->busy_configuring = 1; | 2258 | h->busy_configuring = 1; |
2220 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 2259 | spin_unlock_irqrestore(&h->lock, flags); |
2221 | 2260 | ||
2222 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | 2261 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); |
2223 | if (ld_buff == NULL) | 2262 | if (ld_buff == NULL) |
2224 | goto mem_msg; | 2263 | goto mem_msg; |
2225 | 2264 | ||
2226 | return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, | 2265 | return_code = sendcmd_withirq(h, CISS_REPORT_LOG, ld_buff, |
2227 | sizeof(ReportLunData_struct), | 2266 | sizeof(ReportLunData_struct), |
2228 | 0, CTLR_LUNID, TYPE_CMD); | 2267 | 0, CTLR_LUNID, TYPE_CMD); |
2229 | 2268 | ||
2230 | if (return_code == IO_OK) | 2269 | if (return_code == IO_OK) |
2231 | listlength = be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); | 2270 | listlength = be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); |
2232 | else { /* reading number of logical volumes failed */ | 2271 | else { /* reading number of logical volumes failed */ |
2233 | printk(KERN_WARNING "cciss: report logical volume" | 2272 | dev_warn(&h->pdev->dev, |
2234 | " command failed\n"); | 2273 | "report logical volume command failed\n"); |
2235 | listlength = 0; | 2274 | listlength = 0; |
2236 | goto freeret; | 2275 | goto freeret; |
2237 | } | 2276 | } |
@@ -2239,7 +2278,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, | |||
2239 | num_luns = listlength / 8; /* 8 bytes per entry */ | 2278 | num_luns = listlength / 8; /* 8 bytes per entry */ |
2240 | if (num_luns > CISS_MAX_LUN) { | 2279 | if (num_luns > CISS_MAX_LUN) { |
2241 | num_luns = CISS_MAX_LUN; | 2280 | num_luns = CISS_MAX_LUN; |
2242 | printk(KERN_WARNING "cciss: more luns configured" | 2281 | dev_warn(&h->pdev->dev, "more luns configured" |
2243 | " on controller than can be handled by" | 2282 | " on controller than can be handled by" |
2244 | " this driver.\n"); | 2283 | " this driver.\n"); |
2245 | } | 2284 | } |
@@ -2270,9 +2309,9 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, | |||
2270 | } | 2309 | } |
2271 | if (!drv_found) { | 2310 | if (!drv_found) { |
2272 | /* Deregister it from the OS, it's gone. */ | 2311 | /* Deregister it from the OS, it's gone. */ |
2273 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 2312 | spin_lock_irqsave(&h->lock, flags); |
2274 | h->drv[i]->busy_configuring = 1; | 2313 | h->drv[i]->busy_configuring = 1; |
2275 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 2314 | spin_unlock_irqrestore(&h->lock, flags); |
2276 | return_code = deregister_disk(h, i, 1, via_ioctl); | 2315 | return_code = deregister_disk(h, i, 1, via_ioctl); |
2277 | if (h->drv[i] != NULL) | 2316 | if (h->drv[i] != NULL) |
2278 | h->drv[i]->busy_configuring = 0; | 2317 | h->drv[i]->busy_configuring = 0; |
@@ -2311,8 +2350,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, | |||
2311 | if (drv_index == -1) | 2350 | if (drv_index == -1) |
2312 | goto freeret; | 2351 | goto freeret; |
2313 | } | 2352 | } |
2314 | cciss_update_drive_info(ctlr, drv_index, first_time, | 2353 | cciss_update_drive_info(h, drv_index, first_time, via_ioctl); |
2315 | via_ioctl); | ||
2316 | } /* end for */ | 2354 | } /* end for */ |
2317 | 2355 | ||
2318 | freeret: | 2356 | freeret: |
@@ -2324,7 +2362,7 @@ freeret: | |||
2324 | */ | 2362 | */ |
2325 | return -1; | 2363 | return -1; |
2326 | mem_msg: | 2364 | mem_msg: |
2327 | printk(KERN_ERR "cciss: out of memory\n"); | 2365 | dev_err(&h->pdev->dev, "out of memory\n"); |
2328 | h->busy_configuring = 0; | 2366 | h->busy_configuring = 0; |
2329 | goto freeret; | 2367 | goto freeret; |
2330 | } | 2368 | } |
@@ -2444,11 +2482,10 @@ static int deregister_disk(ctlr_info_t *h, int drv_index, | |||
2444 | return 0; | 2482 | return 0; |
2445 | } | 2483 | } |
2446 | 2484 | ||
2447 | static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, | 2485 | static int fill_cmd(ctlr_info_t *h, CommandList_struct *c, __u8 cmd, void *buff, |
2448 | size_t size, __u8 page_code, unsigned char *scsi3addr, | 2486 | size_t size, __u8 page_code, unsigned char *scsi3addr, |
2449 | int cmd_type) | 2487 | int cmd_type) |
2450 | { | 2488 | { |
2451 | ctlr_info_t *h = hba[ctlr]; | ||
2452 | u64bit buff_dma_handle; | 2489 | u64bit buff_dma_handle; |
2453 | int status = IO_OK; | 2490 | int status = IO_OK; |
2454 | 2491 | ||
@@ -2532,8 +2569,7 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, | |||
2532 | c->Request.Timeout = 0; | 2569 | c->Request.Timeout = 0; |
2533 | break; | 2570 | break; |
2534 | default: | 2571 | default: |
2535 | printk(KERN_WARNING | 2572 | dev_warn(&h->pdev->dev, "Unknown Command 0x%c\n", cmd); |
2536 | "cciss%d: Unknown Command 0x%c\n", ctlr, cmd); | ||
2537 | return IO_ERROR; | 2573 | return IO_ERROR; |
2538 | } | 2574 | } |
2539 | } else if (cmd_type == TYPE_MSG) { | 2575 | } else if (cmd_type == TYPE_MSG) { |
@@ -2565,13 +2601,12 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, | |||
2565 | c->Request.CDB[0] = cmd; | 2601 | c->Request.CDB[0] = cmd; |
2566 | break; | 2602 | break; |
2567 | default: | 2603 | default: |
2568 | printk(KERN_WARNING | 2604 | dev_warn(&h->pdev->dev, |
2569 | "cciss%d: unknown message type %d\n", ctlr, cmd); | 2605 | "unknown message type %d\n", cmd); |
2570 | return IO_ERROR; | 2606 | return IO_ERROR; |
2571 | } | 2607 | } |
2572 | } else { | 2608 | } else { |
2573 | printk(KERN_WARNING | 2609 | dev_warn(&h->pdev->dev, "unknown command type %d\n", cmd_type); |
2574 | "cciss%d: unknown command type %d\n", ctlr, cmd_type); | ||
2575 | return IO_ERROR; | 2610 | return IO_ERROR; |
2576 | } | 2611 | } |
2577 | /* Fill in the scatter gather information */ | 2612 | /* Fill in the scatter gather information */ |
@@ -2599,15 +2634,14 @@ static int check_target_status(ctlr_info_t *h, CommandList_struct *c) | |||
2599 | default: | 2634 | default: |
2600 | if (check_for_unit_attention(h, c)) | 2635 | if (check_for_unit_attention(h, c)) |
2601 | return IO_NEEDS_RETRY; | 2636 | return IO_NEEDS_RETRY; |
2602 | printk(KERN_WARNING "cciss%d: cmd 0x%02x " | 2637 | dev_warn(&h->pdev->dev, "cmd 0x%02x " |
2603 | "check condition, sense key = 0x%02x\n", | 2638 | "check condition, sense key = 0x%02x\n", |
2604 | h->ctlr, c->Request.CDB[0], | 2639 | c->Request.CDB[0], c->err_info->SenseInfo[2]); |
2605 | c->err_info->SenseInfo[2]); | ||
2606 | } | 2640 | } |
2607 | break; | 2641 | break; |
2608 | default: | 2642 | default: |
2609 | printk(KERN_WARNING "cciss%d: cmd 0x%02x" | 2643 | dev_warn(&h->pdev->dev, "cmd 0x%02x" |
2610 | "scsi status = 0x%02x\n", h->ctlr, | 2644 | "scsi status = 0x%02x\n", |
2611 | c->Request.CDB[0], c->err_info->ScsiStatus); | 2645 | c->Request.CDB[0], c->err_info->ScsiStatus); |
2612 | break; | 2646 | break; |
2613 | } | 2647 | } |
@@ -2630,43 +2664,42 @@ static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c) | |||
2630 | /* expected for inquiry and report lun commands */ | 2664 | /* expected for inquiry and report lun commands */ |
2631 | break; | 2665 | break; |
2632 | case CMD_INVALID: | 2666 | case CMD_INVALID: |
2633 | printk(KERN_WARNING "cciss: cmd 0x%02x is " | 2667 | dev_warn(&h->pdev->dev, "cmd 0x%02x is " |
2634 | "reported invalid\n", c->Request.CDB[0]); | 2668 | "reported invalid\n", c->Request.CDB[0]); |
2635 | return_status = IO_ERROR; | 2669 | return_status = IO_ERROR; |
2636 | break; | 2670 | break; |
2637 | case CMD_PROTOCOL_ERR: | 2671 | case CMD_PROTOCOL_ERR: |
2638 | printk(KERN_WARNING "cciss: cmd 0x%02x has " | 2672 | dev_warn(&h->pdev->dev, "cmd 0x%02x has " |
2639 | "protocol error \n", c->Request.CDB[0]); | 2673 | "protocol error\n", c->Request.CDB[0]); |
2640 | return_status = IO_ERROR; | 2674 | return_status = IO_ERROR; |
2641 | break; | 2675 | break; |
2642 | case CMD_HARDWARE_ERR: | 2676 | case CMD_HARDWARE_ERR: |
2643 | printk(KERN_WARNING "cciss: cmd 0x%02x had " | 2677 | dev_warn(&h->pdev->dev, "cmd 0x%02x had " |
2644 | " hardware error\n", c->Request.CDB[0]); | 2678 | " hardware error\n", c->Request.CDB[0]); |
2645 | return_status = IO_ERROR; | 2679 | return_status = IO_ERROR; |
2646 | break; | 2680 | break; |
2647 | case CMD_CONNECTION_LOST: | 2681 | case CMD_CONNECTION_LOST: |
2648 | printk(KERN_WARNING "cciss: cmd 0x%02x had " | 2682 | dev_warn(&h->pdev->dev, "cmd 0x%02x had " |
2649 | "connection lost\n", c->Request.CDB[0]); | 2683 | "connection lost\n", c->Request.CDB[0]); |
2650 | return_status = IO_ERROR; | 2684 | return_status = IO_ERROR; |
2651 | break; | 2685 | break; |
2652 | case CMD_ABORTED: | 2686 | case CMD_ABORTED: |
2653 | printk(KERN_WARNING "cciss: cmd 0x%02x was " | 2687 | dev_warn(&h->pdev->dev, "cmd 0x%02x was " |
2654 | "aborted\n", c->Request.CDB[0]); | 2688 | "aborted\n", c->Request.CDB[0]); |
2655 | return_status = IO_ERROR; | 2689 | return_status = IO_ERROR; |
2656 | break; | 2690 | break; |
2657 | case CMD_ABORT_FAILED: | 2691 | case CMD_ABORT_FAILED: |
2658 | printk(KERN_WARNING "cciss: cmd 0x%02x reports " | 2692 | dev_warn(&h->pdev->dev, "cmd 0x%02x reports " |
2659 | "abort failed\n", c->Request.CDB[0]); | 2693 | "abort failed\n", c->Request.CDB[0]); |
2660 | return_status = IO_ERROR; | 2694 | return_status = IO_ERROR; |
2661 | break; | 2695 | break; |
2662 | case CMD_UNSOLICITED_ABORT: | 2696 | case CMD_UNSOLICITED_ABORT: |
2663 | printk(KERN_WARNING | 2697 | dev_warn(&h->pdev->dev, "unsolicited abort 0x%02x\n", |
2664 | "cciss%d: unsolicited abort 0x%02x\n", h->ctlr, | ||
2665 | c->Request.CDB[0]); | 2698 | c->Request.CDB[0]); |
2666 | return_status = IO_NEEDS_RETRY; | 2699 | return_status = IO_NEEDS_RETRY; |
2667 | break; | 2700 | break; |
2668 | default: | 2701 | default: |
2669 | printk(KERN_WARNING "cciss: cmd 0x%02x returned " | 2702 | dev_warn(&h->pdev->dev, "cmd 0x%02x returned " |
2670 | "unknown status %x\n", c->Request.CDB[0], | 2703 | "unknown status %x\n", c->Request.CDB[0], |
2671 | c->err_info->CommandStatus); | 2704 | c->err_info->CommandStatus); |
2672 | return_status = IO_ERROR; | 2705 | return_status = IO_ERROR; |
@@ -2679,17 +2712,11 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c, | |||
2679 | { | 2712 | { |
2680 | DECLARE_COMPLETION_ONSTACK(wait); | 2713 | DECLARE_COMPLETION_ONSTACK(wait); |
2681 | u64bit buff_dma_handle; | 2714 | u64bit buff_dma_handle; |
2682 | unsigned long flags; | ||
2683 | int return_status = IO_OK; | 2715 | int return_status = IO_OK; |
2684 | 2716 | ||
2685 | resend_cmd2: | 2717 | resend_cmd2: |
2686 | c->waiting = &wait; | 2718 | c->waiting = &wait; |
2687 | /* Put the request on the tail of the queue and send it */ | 2719 | enqueue_cmd_and_start_io(h, c); |
2688 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
2689 | addQ(&h->reqQ, c); | ||
2690 | h->Qdepth++; | ||
2691 | start_io(h); | ||
2692 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
2693 | 2720 | ||
2694 | wait_for_completion(&wait); | 2721 | wait_for_completion(&wait); |
2695 | 2722 | ||
@@ -2700,7 +2727,7 @@ resend_cmd2: | |||
2700 | 2727 | ||
2701 | if (return_status == IO_NEEDS_RETRY && | 2728 | if (return_status == IO_NEEDS_RETRY && |
2702 | c->retry_count < MAX_CMD_RETRIES) { | 2729 | c->retry_count < MAX_CMD_RETRIES) { |
2703 | printk(KERN_WARNING "cciss%d: retrying 0x%02x\n", h->ctlr, | 2730 | dev_warn(&h->pdev->dev, "retrying 0x%02x\n", |
2704 | c->Request.CDB[0]); | 2731 | c->Request.CDB[0]); |
2705 | c->retry_count++; | 2732 | c->retry_count++; |
2706 | /* erase the old error information */ | 2733 | /* erase the old error information */ |
@@ -2719,27 +2746,26 @@ command_done: | |||
2719 | return return_status; | 2746 | return return_status; |
2720 | } | 2747 | } |
2721 | 2748 | ||
2722 | static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size, | 2749 | static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size, |
2723 | __u8 page_code, unsigned char scsi3addr[], | 2750 | __u8 page_code, unsigned char scsi3addr[], |
2724 | int cmd_type) | 2751 | int cmd_type) |
2725 | { | 2752 | { |
2726 | ctlr_info_t *h = hba[ctlr]; | ||
2727 | CommandList_struct *c; | 2753 | CommandList_struct *c; |
2728 | int return_status; | 2754 | int return_status; |
2729 | 2755 | ||
2730 | c = cmd_alloc(h, 0); | 2756 | c = cmd_special_alloc(h); |
2731 | if (!c) | 2757 | if (!c) |
2732 | return -ENOMEM; | 2758 | return -ENOMEM; |
2733 | return_status = fill_cmd(c, cmd, ctlr, buff, size, page_code, | 2759 | return_status = fill_cmd(h, c, cmd, buff, size, page_code, |
2734 | scsi3addr, cmd_type); | 2760 | scsi3addr, cmd_type); |
2735 | if (return_status == IO_OK) | 2761 | if (return_status == IO_OK) |
2736 | return_status = sendcmd_withirq_core(h, c, 1); | 2762 | return_status = sendcmd_withirq_core(h, c, 1); |
2737 | 2763 | ||
2738 | cmd_free(h, c, 0); | 2764 | cmd_special_free(h, c); |
2739 | return return_status; | 2765 | return return_status; |
2740 | } | 2766 | } |
2741 | 2767 | ||
2742 | static void cciss_geometry_inquiry(int ctlr, int logvol, | 2768 | static void cciss_geometry_inquiry(ctlr_info_t *h, int logvol, |
2743 | sector_t total_size, | 2769 | sector_t total_size, |
2744 | unsigned int block_size, | 2770 | unsigned int block_size, |
2745 | InquiryData_struct *inq_buff, | 2771 | InquiryData_struct *inq_buff, |
@@ -2750,13 +2776,13 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, | |||
2750 | unsigned char scsi3addr[8]; | 2776 | unsigned char scsi3addr[8]; |
2751 | 2777 | ||
2752 | memset(inq_buff, 0, sizeof(InquiryData_struct)); | 2778 | memset(inq_buff, 0, sizeof(InquiryData_struct)); |
2753 | log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol); | 2779 | log_unit_to_scsi3addr(h, scsi3addr, logvol); |
2754 | return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buff, | 2780 | return_code = sendcmd_withirq(h, CISS_INQUIRY, inq_buff, |
2755 | sizeof(*inq_buff), 0xC1, scsi3addr, TYPE_CMD); | 2781 | sizeof(*inq_buff), 0xC1, scsi3addr, TYPE_CMD); |
2756 | if (return_code == IO_OK) { | 2782 | if (return_code == IO_OK) { |
2757 | if (inq_buff->data_byte[8] == 0xFF) { | 2783 | if (inq_buff->data_byte[8] == 0xFF) { |
2758 | printk(KERN_WARNING | 2784 | dev_warn(&h->pdev->dev, |
2759 | "cciss: reading geometry failed, volume " | 2785 | "reading geometry failed, volume " |
2760 | "does not support reading geometry\n"); | 2786 | "does not support reading geometry\n"); |
2761 | drv->heads = 255; | 2787 | drv->heads = 255; |
2762 | drv->sectors = 32; /* Sectors per track */ | 2788 | drv->sectors = 32; /* Sectors per track */ |
@@ -2780,12 +2806,12 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, | |||
2780 | drv->cylinders = real_size; | 2806 | drv->cylinders = real_size; |
2781 | } | 2807 | } |
2782 | } else { /* Get geometry failed */ | 2808 | } else { /* Get geometry failed */ |
2783 | printk(KERN_WARNING "cciss: reading geometry failed\n"); | 2809 | dev_warn(&h->pdev->dev, "reading geometry failed\n"); |
2784 | } | 2810 | } |
2785 | } | 2811 | } |
2786 | 2812 | ||
2787 | static void | 2813 | static void |
2788 | cciss_read_capacity(int ctlr, int logvol, sector_t *total_size, | 2814 | cciss_read_capacity(ctlr_info_t *h, int logvol, sector_t *total_size, |
2789 | unsigned int *block_size) | 2815 | unsigned int *block_size) |
2790 | { | 2816 | { |
2791 | ReadCapdata_struct *buf; | 2817 | ReadCapdata_struct *buf; |
@@ -2794,25 +2820,25 @@ cciss_read_capacity(int ctlr, int logvol, sector_t *total_size, | |||
2794 | 2820 | ||
2795 | buf = kzalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); | 2821 | buf = kzalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); |
2796 | if (!buf) { | 2822 | if (!buf) { |
2797 | printk(KERN_WARNING "cciss: out of memory\n"); | 2823 | dev_warn(&h->pdev->dev, "out of memory\n"); |
2798 | return; | 2824 | return; |
2799 | } | 2825 | } |
2800 | 2826 | ||
2801 | log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol); | 2827 | log_unit_to_scsi3addr(h, scsi3addr, logvol); |
2802 | return_code = sendcmd_withirq(CCISS_READ_CAPACITY, ctlr, buf, | 2828 | return_code = sendcmd_withirq(h, CCISS_READ_CAPACITY, buf, |
2803 | sizeof(ReadCapdata_struct), 0, scsi3addr, TYPE_CMD); | 2829 | sizeof(ReadCapdata_struct), 0, scsi3addr, TYPE_CMD); |
2804 | if (return_code == IO_OK) { | 2830 | if (return_code == IO_OK) { |
2805 | *total_size = be32_to_cpu(*(__be32 *) buf->total_size); | 2831 | *total_size = be32_to_cpu(*(__be32 *) buf->total_size); |
2806 | *block_size = be32_to_cpu(*(__be32 *) buf->block_size); | 2832 | *block_size = be32_to_cpu(*(__be32 *) buf->block_size); |
2807 | } else { /* read capacity command failed */ | 2833 | } else { /* read capacity command failed */ |
2808 | printk(KERN_WARNING "cciss: read capacity failed\n"); | 2834 | dev_warn(&h->pdev->dev, "read capacity failed\n"); |
2809 | *total_size = 0; | 2835 | *total_size = 0; |
2810 | *block_size = BLOCK_SIZE; | 2836 | *block_size = BLOCK_SIZE; |
2811 | } | 2837 | } |
2812 | kfree(buf); | 2838 | kfree(buf); |
2813 | } | 2839 | } |
2814 | 2840 | ||
2815 | static void cciss_read_capacity_16(int ctlr, int logvol, | 2841 | static void cciss_read_capacity_16(ctlr_info_t *h, int logvol, |
2816 | sector_t *total_size, unsigned int *block_size) | 2842 | sector_t *total_size, unsigned int *block_size) |
2817 | { | 2843 | { |
2818 | ReadCapdata_struct_16 *buf; | 2844 | ReadCapdata_struct_16 *buf; |
@@ -2821,23 +2847,23 @@ static void cciss_read_capacity_16(int ctlr, int logvol, | |||
2821 | 2847 | ||
2822 | buf = kzalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); | 2848 | buf = kzalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); |
2823 | if (!buf) { | 2849 | if (!buf) { |
2824 | printk(KERN_WARNING "cciss: out of memory\n"); | 2850 | dev_warn(&h->pdev->dev, "out of memory\n"); |
2825 | return; | 2851 | return; |
2826 | } | 2852 | } |
2827 | 2853 | ||
2828 | log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol); | 2854 | log_unit_to_scsi3addr(h, scsi3addr, logvol); |
2829 | return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16, | 2855 | return_code = sendcmd_withirq(h, CCISS_READ_CAPACITY_16, |
2830 | ctlr, buf, sizeof(ReadCapdata_struct_16), | 2856 | buf, sizeof(ReadCapdata_struct_16), |
2831 | 0, scsi3addr, TYPE_CMD); | 2857 | 0, scsi3addr, TYPE_CMD); |
2832 | if (return_code == IO_OK) { | 2858 | if (return_code == IO_OK) { |
2833 | *total_size = be64_to_cpu(*(__be64 *) buf->total_size); | 2859 | *total_size = be64_to_cpu(*(__be64 *) buf->total_size); |
2834 | *block_size = be32_to_cpu(*(__be32 *) buf->block_size); | 2860 | *block_size = be32_to_cpu(*(__be32 *) buf->block_size); |
2835 | } else { /* read capacity command failed */ | 2861 | } else { /* read capacity command failed */ |
2836 | printk(KERN_WARNING "cciss: read capacity failed\n"); | 2862 | dev_warn(&h->pdev->dev, "read capacity failed\n"); |
2837 | *total_size = 0; | 2863 | *total_size = 0; |
2838 | *block_size = BLOCK_SIZE; | 2864 | *block_size = BLOCK_SIZE; |
2839 | } | 2865 | } |
2840 | printk(KERN_INFO " blocks= %llu block_size= %d\n", | 2866 | dev_info(&h->pdev->dev, " blocks= %llu block_size= %d\n", |
2841 | (unsigned long long)*total_size+1, *block_size); | 2867 | (unsigned long long)*total_size+1, *block_size); |
2842 | kfree(buf); | 2868 | kfree(buf); |
2843 | } | 2869 | } |
@@ -2865,17 +2891,17 @@ static int cciss_revalidate(struct gendisk *disk) | |||
2865 | 2891 | ||
2866 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | 2892 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); |
2867 | if (inq_buff == NULL) { | 2893 | if (inq_buff == NULL) { |
2868 | printk(KERN_WARNING "cciss: out of memory\n"); | 2894 | dev_warn(&h->pdev->dev, "out of memory\n"); |
2869 | return 1; | 2895 | return 1; |
2870 | } | 2896 | } |
2871 | if (h->cciss_read == CCISS_READ_10) { | 2897 | if (h->cciss_read == CCISS_READ_10) { |
2872 | cciss_read_capacity(h->ctlr, logvol, | 2898 | cciss_read_capacity(h, logvol, |
2873 | &total_size, &block_size); | 2899 | &total_size, &block_size); |
2874 | } else { | 2900 | } else { |
2875 | cciss_read_capacity_16(h->ctlr, logvol, | 2901 | cciss_read_capacity_16(h, logvol, |
2876 | &total_size, &block_size); | 2902 | &total_size, &block_size); |
2877 | } | 2903 | } |
2878 | cciss_geometry_inquiry(h->ctlr, logvol, total_size, block_size, | 2904 | cciss_geometry_inquiry(h, logvol, total_size, block_size, |
2879 | inq_buff, drv); | 2905 | inq_buff, drv); |
2880 | 2906 | ||
2881 | blk_queue_logical_block_size(drv->queue, drv->block_size); | 2907 | blk_queue_logical_block_size(drv->queue, drv->block_size); |
@@ -2909,7 +2935,7 @@ static void start_io(ctlr_info_t *h) | |||
2909 | c = hlist_entry(h->reqQ.first, CommandList_struct, list); | 2935 | c = hlist_entry(h->reqQ.first, CommandList_struct, list); |
2910 | /* can't do anything if fifo is full */ | 2936 | /* can't do anything if fifo is full */ |
2911 | if ((h->access.fifo_full(h))) { | 2937 | if ((h->access.fifo_full(h))) { |
2912 | printk(KERN_WARNING "cciss: fifo full\n"); | 2938 | dev_warn(&h->pdev->dev, "fifo full\n"); |
2913 | break; | 2939 | break; |
2914 | } | 2940 | } |
2915 | 2941 | ||
@@ -2925,7 +2951,7 @@ static void start_io(ctlr_info_t *h) | |||
2925 | } | 2951 | } |
2926 | } | 2952 | } |
2927 | 2953 | ||
2928 | /* Assumes that CCISS_LOCK(h->ctlr) is held. */ | 2954 | /* Assumes that h->lock is held. */ |
2929 | /* Zeros out the error record and then resends the command back */ | 2955 | /* Zeros out the error record and then resends the command back */ |
2930 | /* to the controller */ | 2956 | /* to the controller */ |
2931 | static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c) | 2957 | static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c) |
@@ -2966,7 +2992,7 @@ static inline int evaluate_target_status(ctlr_info_t *h, | |||
2966 | driver_byte = DRIVER_OK; | 2992 | driver_byte = DRIVER_OK; |
2967 | msg_byte = cmd->err_info->CommandStatus; /* correct? seems too device specific */ | 2993 | msg_byte = cmd->err_info->CommandStatus; /* correct? seems too device specific */ |
2968 | 2994 | ||
2969 | if (blk_pc_request(cmd->rq)) | 2995 | if (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) |
2970 | host_byte = DID_PASSTHROUGH; | 2996 | host_byte = DID_PASSTHROUGH; |
2971 | else | 2997 | else |
2972 | host_byte = DID_OK; | 2998 | host_byte = DID_OK; |
@@ -2975,8 +3001,8 @@ static inline int evaluate_target_status(ctlr_info_t *h, | |||
2975 | host_byte, driver_byte); | 3001 | host_byte, driver_byte); |
2976 | 3002 | ||
2977 | if (cmd->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) { | 3003 | if (cmd->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) { |
2978 | if (!blk_pc_request(cmd->rq)) | 3004 | if (cmd->rq->cmd_type != REQ_TYPE_BLOCK_PC) |
2979 | printk(KERN_WARNING "cciss: cmd %p " | 3005 | dev_warn(&h->pdev->dev, "cmd %p " |
2980 | "has SCSI Status 0x%x\n", | 3006 | "has SCSI Status 0x%x\n", |
2981 | cmd, cmd->err_info->ScsiStatus); | 3007 | cmd, cmd->err_info->ScsiStatus); |
2982 | return error_value; | 3008 | return error_value; |
@@ -2985,17 +3011,19 @@ static inline int evaluate_target_status(ctlr_info_t *h, | |||
2985 | /* check the sense key */ | 3011 | /* check the sense key */ |
2986 | sense_key = 0xf & cmd->err_info->SenseInfo[2]; | 3012 | sense_key = 0xf & cmd->err_info->SenseInfo[2]; |
2987 | /* no status or recovered error */ | 3013 | /* no status or recovered error */ |
2988 | if (((sense_key == 0x0) || (sense_key == 0x1)) && !blk_pc_request(cmd->rq)) | 3014 | if (((sense_key == 0x0) || (sense_key == 0x1)) && |
3015 | (cmd->rq->cmd_type != REQ_TYPE_BLOCK_PC)) | ||
2989 | error_value = 0; | 3016 | error_value = 0; |
2990 | 3017 | ||
2991 | if (check_for_unit_attention(h, cmd)) { | 3018 | if (check_for_unit_attention(h, cmd)) { |
2992 | *retry_cmd = !blk_pc_request(cmd->rq); | 3019 | *retry_cmd = !(cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC); |
2993 | return 0; | 3020 | return 0; |
2994 | } | 3021 | } |
2995 | 3022 | ||
2996 | if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */ | 3023 | /* Not SG_IO or similar? */ |
3024 | if (cmd->rq->cmd_type != REQ_TYPE_BLOCK_PC) { | ||
2997 | if (error_value != 0) | 3025 | if (error_value != 0) |
2998 | printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION" | 3026 | dev_warn(&h->pdev->dev, "cmd %p has CHECK CONDITION" |
2999 | " sense key = 0x%x\n", cmd, sense_key); | 3027 | " sense key = 0x%x\n", cmd, sense_key); |
3000 | return error_value; | 3028 | return error_value; |
3001 | } | 3029 | } |
@@ -3035,90 +3063,97 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, | |||
3035 | rq->errors = evaluate_target_status(h, cmd, &retry_cmd); | 3063 | rq->errors = evaluate_target_status(h, cmd, &retry_cmd); |
3036 | break; | 3064 | break; |
3037 | case CMD_DATA_UNDERRUN: | 3065 | case CMD_DATA_UNDERRUN: |
3038 | if (blk_fs_request(cmd->rq)) { | 3066 | if (cmd->rq->cmd_type == REQ_TYPE_FS) { |
3039 | printk(KERN_WARNING "cciss: cmd %p has" | 3067 | dev_warn(&h->pdev->dev, "cmd %p has" |
3040 | " completed with data underrun " | 3068 | " completed with data underrun " |
3041 | "reported\n", cmd); | 3069 | "reported\n", cmd); |
3042 | cmd->rq->resid_len = cmd->err_info->ResidualCnt; | 3070 | cmd->rq->resid_len = cmd->err_info->ResidualCnt; |
3043 | } | 3071 | } |
3044 | break; | 3072 | break; |
3045 | case CMD_DATA_OVERRUN: | 3073 | case CMD_DATA_OVERRUN: |
3046 | if (blk_fs_request(cmd->rq)) | 3074 | if (cmd->rq->cmd_type == REQ_TYPE_FS) |
3047 | printk(KERN_WARNING "cciss: cmd %p has" | 3075 | dev_warn(&h->pdev->dev, "cciss: cmd %p has" |
3048 | " completed with data overrun " | 3076 | " completed with data overrun " |
3049 | "reported\n", cmd); | 3077 | "reported\n", cmd); |
3050 | break; | 3078 | break; |
3051 | case CMD_INVALID: | 3079 | case CMD_INVALID: |
3052 | printk(KERN_WARNING "cciss: cmd %p is " | 3080 | dev_warn(&h->pdev->dev, "cciss: cmd %p is " |
3053 | "reported invalid\n", cmd); | 3081 | "reported invalid\n", cmd); |
3054 | rq->errors = make_status_bytes(SAM_STAT_GOOD, | 3082 | rq->errors = make_status_bytes(SAM_STAT_GOOD, |
3055 | cmd->err_info->CommandStatus, DRIVER_OK, | 3083 | cmd->err_info->CommandStatus, DRIVER_OK, |
3056 | blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); | 3084 | (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? |
3085 | DID_PASSTHROUGH : DID_ERROR); | ||
3057 | break; | 3086 | break; |
3058 | case CMD_PROTOCOL_ERR: | 3087 | case CMD_PROTOCOL_ERR: |
3059 | printk(KERN_WARNING "cciss: cmd %p has " | 3088 | dev_warn(&h->pdev->dev, "cciss: cmd %p has " |
3060 | "protocol error \n", cmd); | 3089 | "protocol error\n", cmd); |
3061 | rq->errors = make_status_bytes(SAM_STAT_GOOD, | 3090 | rq->errors = make_status_bytes(SAM_STAT_GOOD, |
3062 | cmd->err_info->CommandStatus, DRIVER_OK, | 3091 | cmd->err_info->CommandStatus, DRIVER_OK, |
3063 | blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); | 3092 | (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? |
3093 | DID_PASSTHROUGH : DID_ERROR); | ||
3064 | break; | 3094 | break; |
3065 | case CMD_HARDWARE_ERR: | 3095 | case CMD_HARDWARE_ERR: |
3066 | printk(KERN_WARNING "cciss: cmd %p had " | 3096 | dev_warn(&h->pdev->dev, "cciss: cmd %p had " |
3067 | " hardware error\n", cmd); | 3097 | " hardware error\n", cmd); |
3068 | rq->errors = make_status_bytes(SAM_STAT_GOOD, | 3098 | rq->errors = make_status_bytes(SAM_STAT_GOOD, |
3069 | cmd->err_info->CommandStatus, DRIVER_OK, | 3099 | cmd->err_info->CommandStatus, DRIVER_OK, |
3070 | blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); | 3100 | (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? |
3101 | DID_PASSTHROUGH : DID_ERROR); | ||
3071 | break; | 3102 | break; |
3072 | case CMD_CONNECTION_LOST: | 3103 | case CMD_CONNECTION_LOST: |
3073 | printk(KERN_WARNING "cciss: cmd %p had " | 3104 | dev_warn(&h->pdev->dev, "cciss: cmd %p had " |
3074 | "connection lost\n", cmd); | 3105 | "connection lost\n", cmd); |
3075 | rq->errors = make_status_bytes(SAM_STAT_GOOD, | 3106 | rq->errors = make_status_bytes(SAM_STAT_GOOD, |
3076 | cmd->err_info->CommandStatus, DRIVER_OK, | 3107 | cmd->err_info->CommandStatus, DRIVER_OK, |
3077 | blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); | 3108 | (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? |
3109 | DID_PASSTHROUGH : DID_ERROR); | ||
3078 | break; | 3110 | break; |
3079 | case CMD_ABORTED: | 3111 | case CMD_ABORTED: |
3080 | printk(KERN_WARNING "cciss: cmd %p was " | 3112 | dev_warn(&h->pdev->dev, "cciss: cmd %p was " |
3081 | "aborted\n", cmd); | 3113 | "aborted\n", cmd); |
3082 | rq->errors = make_status_bytes(SAM_STAT_GOOD, | 3114 | rq->errors = make_status_bytes(SAM_STAT_GOOD, |
3083 | cmd->err_info->CommandStatus, DRIVER_OK, | 3115 | cmd->err_info->CommandStatus, DRIVER_OK, |
3084 | blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ABORT); | 3116 | (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? |
3117 | DID_PASSTHROUGH : DID_ABORT); | ||
3085 | break; | 3118 | break; |
3086 | case CMD_ABORT_FAILED: | 3119 | case CMD_ABORT_FAILED: |
3087 | printk(KERN_WARNING "cciss: cmd %p reports " | 3120 | dev_warn(&h->pdev->dev, "cciss: cmd %p reports " |
3088 | "abort failed\n", cmd); | 3121 | "abort failed\n", cmd); |
3089 | rq->errors = make_status_bytes(SAM_STAT_GOOD, | 3122 | rq->errors = make_status_bytes(SAM_STAT_GOOD, |
3090 | cmd->err_info->CommandStatus, DRIVER_OK, | 3123 | cmd->err_info->CommandStatus, DRIVER_OK, |
3091 | blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); | 3124 | (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? |
3125 | DID_PASSTHROUGH : DID_ERROR); | ||
3092 | break; | 3126 | break; |
3093 | case CMD_UNSOLICITED_ABORT: | 3127 | case CMD_UNSOLICITED_ABORT: |
3094 | printk(KERN_WARNING "cciss%d: unsolicited " | 3128 | dev_warn(&h->pdev->dev, "cciss%d: unsolicited " |
3095 | "abort %p\n", h->ctlr, cmd); | 3129 | "abort %p\n", h->ctlr, cmd); |
3096 | if (cmd->retry_count < MAX_CMD_RETRIES) { | 3130 | if (cmd->retry_count < MAX_CMD_RETRIES) { |
3097 | retry_cmd = 1; | 3131 | retry_cmd = 1; |
3098 | printk(KERN_WARNING | 3132 | dev_warn(&h->pdev->dev, "retrying %p\n", cmd); |
3099 | "cciss%d: retrying %p\n", h->ctlr, cmd); | ||
3100 | cmd->retry_count++; | 3133 | cmd->retry_count++; |
3101 | } else | 3134 | } else |
3102 | printk(KERN_WARNING | 3135 | dev_warn(&h->pdev->dev, |
3103 | "cciss%d: %p retried too " | 3136 | "%p retried too many times\n", cmd); |
3104 | "many times\n", h->ctlr, cmd); | ||
3105 | rq->errors = make_status_bytes(SAM_STAT_GOOD, | 3137 | rq->errors = make_status_bytes(SAM_STAT_GOOD, |
3106 | cmd->err_info->CommandStatus, DRIVER_OK, | 3138 | cmd->err_info->CommandStatus, DRIVER_OK, |
3107 | blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ABORT); | 3139 | (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? |
3140 | DID_PASSTHROUGH : DID_ABORT); | ||
3108 | break; | 3141 | break; |
3109 | case CMD_TIMEOUT: | 3142 | case CMD_TIMEOUT: |
3110 | printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); | 3143 | dev_warn(&h->pdev->dev, "cmd %p timedout\n", cmd); |
3111 | rq->errors = make_status_bytes(SAM_STAT_GOOD, | 3144 | rq->errors = make_status_bytes(SAM_STAT_GOOD, |
3112 | cmd->err_info->CommandStatus, DRIVER_OK, | 3145 | cmd->err_info->CommandStatus, DRIVER_OK, |
3113 | blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); | 3146 | (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? |
3147 | DID_PASSTHROUGH : DID_ERROR); | ||
3114 | break; | 3148 | break; |
3115 | default: | 3149 | default: |
3116 | printk(KERN_WARNING "cciss: cmd %p returned " | 3150 | dev_warn(&h->pdev->dev, "cmd %p returned " |
3117 | "unknown status %x\n", cmd, | 3151 | "unknown status %x\n", cmd, |
3118 | cmd->err_info->CommandStatus); | 3152 | cmd->err_info->CommandStatus); |
3119 | rq->errors = make_status_bytes(SAM_STAT_GOOD, | 3153 | rq->errors = make_status_bytes(SAM_STAT_GOOD, |
3120 | cmd->err_info->CommandStatus, DRIVER_OK, | 3154 | cmd->err_info->CommandStatus, DRIVER_OK, |
3121 | blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); | 3155 | (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? |
3156 | DID_PASSTHROUGH : DID_ERROR); | ||
3122 | } | 3157 | } |
3123 | 3158 | ||
3124 | after_error_processing: | 3159 | after_error_processing: |
@@ -3132,6 +3167,34 @@ after_error_processing: | |||
3132 | blk_complete_request(cmd->rq); | 3167 | blk_complete_request(cmd->rq); |
3133 | } | 3168 | } |
3134 | 3169 | ||
3170 | static inline u32 cciss_tag_contains_index(u32 tag) | ||
3171 | { | ||
3172 | #define DIRECT_LOOKUP_BIT 0x10 | ||
3173 | return tag & DIRECT_LOOKUP_BIT; | ||
3174 | } | ||
3175 | |||
3176 | static inline u32 cciss_tag_to_index(u32 tag) | ||
3177 | { | ||
3178 | #define DIRECT_LOOKUP_SHIFT 5 | ||
3179 | return tag >> DIRECT_LOOKUP_SHIFT; | ||
3180 | } | ||
3181 | |||
3182 | static inline u32 cciss_tag_discard_error_bits(u32 tag) | ||
3183 | { | ||
3184 | #define CCISS_ERROR_BITS 0x03 | ||
3185 | return tag & ~CCISS_ERROR_BITS; | ||
3186 | } | ||
3187 | |||
3188 | static inline void cciss_mark_tag_indexed(u32 *tag) | ||
3189 | { | ||
3190 | *tag |= DIRECT_LOOKUP_BIT; | ||
3191 | } | ||
3192 | |||
3193 | static inline void cciss_set_tag_index(u32 *tag, u32 index) | ||
3194 | { | ||
3195 | *tag |= (index << DIRECT_LOOKUP_SHIFT); | ||
3196 | } | ||
3197 | |||
3135 | /* | 3198 | /* |
3136 | * Get a request and submit it to the controller. | 3199 | * Get a request and submit it to the controller. |
3137 | */ | 3200 | */ |
@@ -3163,7 +3226,8 @@ static void do_cciss_request(struct request_queue *q) | |||
3163 | 3226 | ||
3164 | BUG_ON(creq->nr_phys_segments > h->maxsgentries); | 3227 | BUG_ON(creq->nr_phys_segments > h->maxsgentries); |
3165 | 3228 | ||
3166 | if ((c = cmd_alloc(h, 1)) == NULL) | 3229 | c = cmd_alloc(h); |
3230 | if (!c) | ||
3167 | goto full; | 3231 | goto full; |
3168 | 3232 | ||
3169 | blk_start_request(creq); | 3233 | blk_start_request(creq); |
@@ -3180,8 +3244,8 @@ static void do_cciss_request(struct request_queue *q) | |||
3180 | /* got command from pool, so use the command block index instead */ | 3244 | /* got command from pool, so use the command block index instead */ |
3181 | /* for direct lookups. */ | 3245 | /* for direct lookups. */ |
3182 | /* The first 2 bits are reserved for controller error reporting. */ | 3246 | /* The first 2 bits are reserved for controller error reporting. */ |
3183 | c->Header.Tag.lower = (c->cmdindex << 3); | 3247 | cciss_set_tag_index(&c->Header.Tag.lower, c->cmdindex); |
3184 | c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ | 3248 | cciss_mark_tag_indexed(&c->Header.Tag.lower); |
3185 | memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID)); | 3249 | memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID)); |
3186 | c->Request.CDBLen = 10; /* 12 byte commands not in FW yet; */ | 3250 | c->Request.CDBLen = 10; /* 12 byte commands not in FW yet; */ |
3187 | c->Request.Type.Type = TYPE_CMD; /* It is a command. */ | 3251 | c->Request.Type.Type = TYPE_CMD; /* It is a command. */ |
@@ -3192,11 +3256,8 @@ static void do_cciss_request(struct request_queue *q) | |||
3192 | c->Request.CDB[0] = | 3256 | c->Request.CDB[0] = |
3193 | (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; | 3257 | (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; |
3194 | start_blk = blk_rq_pos(creq); | 3258 | start_blk = blk_rq_pos(creq); |
3195 | #ifdef CCISS_DEBUG | 3259 | dev_dbg(&h->pdev->dev, "sector =%d nr_sectors=%d\n", |
3196 | printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", | ||
3197 | (int)blk_rq_pos(creq), (int)blk_rq_sectors(creq)); | 3260 | (int)blk_rq_pos(creq), (int)blk_rq_sectors(creq)); |
3198 | #endif /* CCISS_DEBUG */ | ||
3199 | |||
3200 | sg_init_table(tmp_sg, h->maxsgentries); | 3261 | sg_init_table(tmp_sg, h->maxsgentries); |
3201 | seg = blk_rq_map_sg(q, creq, tmp_sg); | 3262 | seg = blk_rq_map_sg(q, creq, tmp_sg); |
3202 | 3263 | ||
@@ -3236,17 +3297,18 @@ static void do_cciss_request(struct request_queue *q) | |||
3236 | if (seg > h->maxSG) | 3297 | if (seg > h->maxSG) |
3237 | h->maxSG = seg; | 3298 | h->maxSG = seg; |
3238 | 3299 | ||
3239 | #ifdef CCISS_DEBUG | 3300 | dev_dbg(&h->pdev->dev, "Submitting %u sectors in %d segments " |
3240 | printk(KERN_DEBUG "cciss: Submitting %ld sectors in %d segments " | ||
3241 | "chained[%d]\n", | 3301 | "chained[%d]\n", |
3242 | blk_rq_sectors(creq), seg, chained); | 3302 | blk_rq_sectors(creq), seg, chained); |
3243 | #endif /* CCISS_DEBUG */ | ||
3244 | 3303 | ||
3245 | c->Header.SGList = c->Header.SGTotal = seg + chained; | 3304 | c->Header.SGTotal = seg + chained; |
3246 | if (seg > h->max_cmd_sgentries) | 3305 | if (seg <= h->max_cmd_sgentries) |
3306 | c->Header.SGList = c->Header.SGTotal; | ||
3307 | else | ||
3247 | c->Header.SGList = h->max_cmd_sgentries; | 3308 | c->Header.SGList = h->max_cmd_sgentries; |
3309 | set_performant_mode(h, c); | ||
3248 | 3310 | ||
3249 | if (likely(blk_fs_request(creq))) { | 3311 | if (likely(creq->cmd_type == REQ_TYPE_FS)) { |
3250 | if(h->cciss_read == CCISS_READ_10) { | 3312 | if(h->cciss_read == CCISS_READ_10) { |
3251 | c->Request.CDB[1] = 0; | 3313 | c->Request.CDB[1] = 0; |
3252 | c->Request.CDB[2] = (start_blk >> 24) & 0xff; /* MSB */ | 3314 | c->Request.CDB[2] = (start_blk >> 24) & 0xff; /* MSB */ |
@@ -3276,11 +3338,12 @@ static void do_cciss_request(struct request_queue *q) | |||
3276 | c->Request.CDB[13]= blk_rq_sectors(creq) & 0xff; | 3338 | c->Request.CDB[13]= blk_rq_sectors(creq) & 0xff; |
3277 | c->Request.CDB[14] = c->Request.CDB[15] = 0; | 3339 | c->Request.CDB[14] = c->Request.CDB[15] = 0; |
3278 | } | 3340 | } |
3279 | } else if (blk_pc_request(creq)) { | 3341 | } else if (creq->cmd_type == REQ_TYPE_BLOCK_PC) { |
3280 | c->Request.CDBLen = creq->cmd_len; | 3342 | c->Request.CDBLen = creq->cmd_len; |
3281 | memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB); | 3343 | memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB); |
3282 | } else { | 3344 | } else { |
3283 | printk(KERN_WARNING "cciss%d: bad request type %d\n", h->ctlr, creq->cmd_type); | 3345 | dev_warn(&h->pdev->dev, "bad request type %d\n", |
3346 | creq->cmd_type); | ||
3284 | BUG(); | 3347 | BUG(); |
3285 | } | 3348 | } |
3286 | 3349 | ||
@@ -3313,72 +3376,131 @@ static inline int interrupt_pending(ctlr_info_t *h) | |||
3313 | 3376 | ||
3314 | static inline long interrupt_not_for_us(ctlr_info_t *h) | 3377 | static inline long interrupt_not_for_us(ctlr_info_t *h) |
3315 | { | 3378 | { |
3316 | return (((h->access.intr_pending(h) == 0) || | 3379 | return ((h->access.intr_pending(h) == 0) || |
3317 | (h->interrupts_enabled == 0))); | 3380 | (h->interrupts_enabled == 0)); |
3318 | } | 3381 | } |
3319 | 3382 | ||
3320 | static irqreturn_t do_cciss_intr(int irq, void *dev_id) | 3383 | static inline int bad_tag(ctlr_info_t *h, u32 tag_index, |
3384 | u32 raw_tag) | ||
3321 | { | 3385 | { |
3322 | ctlr_info_t *h = dev_id; | 3386 | if (unlikely(tag_index >= h->nr_cmds)) { |
3387 | dev_warn(&h->pdev->dev, "bad tag 0x%08x ignored.\n", raw_tag); | ||
3388 | return 1; | ||
3389 | } | ||
3390 | return 0; | ||
3391 | } | ||
3392 | |||
3393 | static inline void finish_cmd(ctlr_info_t *h, CommandList_struct *c, | ||
3394 | u32 raw_tag) | ||
3395 | { | ||
3396 | removeQ(c); | ||
3397 | if (likely(c->cmd_type == CMD_RWREQ)) | ||
3398 | complete_command(h, c, 0); | ||
3399 | else if (c->cmd_type == CMD_IOCTL_PEND) | ||
3400 | complete(c->waiting); | ||
3401 | #ifdef CONFIG_CISS_SCSI_TAPE | ||
3402 | else if (c->cmd_type == CMD_SCSI) | ||
3403 | complete_scsi_command(c, 0, raw_tag); | ||
3404 | #endif | ||
3405 | } | ||
3406 | |||
3407 | static inline u32 next_command(ctlr_info_t *h) | ||
3408 | { | ||
3409 | u32 a; | ||
3410 | |||
3411 | if (unlikely(h->transMethod != CFGTBL_Trans_Performant)) | ||
3412 | return h->access.command_completed(h); | ||
3413 | |||
3414 | if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { | ||
3415 | a = *(h->reply_pool_head); /* Next cmd in ring buffer */ | ||
3416 | (h->reply_pool_head)++; | ||
3417 | h->commands_outstanding--; | ||
3418 | } else { | ||
3419 | a = FIFO_EMPTY; | ||
3420 | } | ||
3421 | /* Check for wraparound */ | ||
3422 | if (h->reply_pool_head == (h->reply_pool + h->max_commands)) { | ||
3423 | h->reply_pool_head = h->reply_pool; | ||
3424 | h->reply_pool_wraparound ^= 1; | ||
3425 | } | ||
3426 | return a; | ||
3427 | } | ||
3428 | |||
3429 | /* process completion of an indexed ("direct lookup") command */ | ||
3430 | static inline u32 process_indexed_cmd(ctlr_info_t *h, u32 raw_tag) | ||
3431 | { | ||
3432 | u32 tag_index; | ||
3323 | CommandList_struct *c; | 3433 | CommandList_struct *c; |
3434 | |||
3435 | tag_index = cciss_tag_to_index(raw_tag); | ||
3436 | if (bad_tag(h, tag_index, raw_tag)) | ||
3437 | return next_command(h); | ||
3438 | c = h->cmd_pool + tag_index; | ||
3439 | finish_cmd(h, c, raw_tag); | ||
3440 | return next_command(h); | ||
3441 | } | ||
3442 | |||
3443 | /* process completion of a non-indexed command */ | ||
3444 | static inline u32 process_nonindexed_cmd(ctlr_info_t *h, u32 raw_tag) | ||
3445 | { | ||
3446 | u32 tag; | ||
3447 | CommandList_struct *c = NULL; | ||
3448 | struct hlist_node *tmp; | ||
3449 | __u32 busaddr_masked, tag_masked; | ||
3450 | |||
3451 | tag = cciss_tag_discard_error_bits(raw_tag); | ||
3452 | hlist_for_each_entry(c, tmp, &h->cmpQ, list) { | ||
3453 | busaddr_masked = cciss_tag_discard_error_bits(c->busaddr); | ||
3454 | tag_masked = cciss_tag_discard_error_bits(tag); | ||
3455 | if (busaddr_masked == tag_masked) { | ||
3456 | finish_cmd(h, c, raw_tag); | ||
3457 | return next_command(h); | ||
3458 | } | ||
3459 | } | ||
3460 | bad_tag(h, h->nr_cmds + 1, raw_tag); | ||
3461 | return next_command(h); | ||
3462 | } | ||
3463 | |||
3464 | static irqreturn_t do_cciss_intx(int irq, void *dev_id) | ||
3465 | { | ||
3466 | ctlr_info_t *h = dev_id; | ||
3324 | unsigned long flags; | 3467 | unsigned long flags; |
3325 | __u32 a, a1, a2; | 3468 | u32 raw_tag; |
3326 | 3469 | ||
3327 | if (interrupt_not_for_us(h)) | 3470 | if (interrupt_not_for_us(h)) |
3328 | return IRQ_NONE; | 3471 | return IRQ_NONE; |
3329 | /* | 3472 | spin_lock_irqsave(&h->lock, flags); |
3330 | * If there are completed commands in the completion queue, | ||
3331 | * we had better do something about it. | ||
3332 | */ | ||
3333 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
3334 | while (interrupt_pending(h)) { | 3473 | while (interrupt_pending(h)) { |
3335 | while ((a = get_next_completion(h)) != FIFO_EMPTY) { | 3474 | raw_tag = get_next_completion(h); |
3336 | a1 = a; | 3475 | while (raw_tag != FIFO_EMPTY) { |
3337 | if ((a & 0x04)) { | 3476 | if (cciss_tag_contains_index(raw_tag)) |
3338 | a2 = (a >> 3); | 3477 | raw_tag = process_indexed_cmd(h, raw_tag); |
3339 | if (a2 >= h->nr_cmds) { | 3478 | else |
3340 | printk(KERN_WARNING | 3479 | raw_tag = process_nonindexed_cmd(h, raw_tag); |
3341 | "cciss: controller cciss%d failed, stopping.\n", | ||
3342 | h->ctlr); | ||
3343 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
3344 | fail_all_cmds(h->ctlr); | ||
3345 | return IRQ_HANDLED; | ||
3346 | } | ||
3347 | |||
3348 | c = h->cmd_pool + a2; | ||
3349 | a = c->busaddr; | ||
3350 | |||
3351 | } else { | ||
3352 | struct hlist_node *tmp; | ||
3353 | |||
3354 | a &= ~3; | ||
3355 | c = NULL; | ||
3356 | hlist_for_each_entry(c, tmp, &h->cmpQ, list) { | ||
3357 | if (c->busaddr == a) | ||
3358 | break; | ||
3359 | } | ||
3360 | } | ||
3361 | /* | ||
3362 | * If we've found the command, take it off the | ||
3363 | * completion Q and free it | ||
3364 | */ | ||
3365 | if (c && c->busaddr == a) { | ||
3366 | removeQ(c); | ||
3367 | if (c->cmd_type == CMD_RWREQ) { | ||
3368 | complete_command(h, c, 0); | ||
3369 | } else if (c->cmd_type == CMD_IOCTL_PEND) { | ||
3370 | complete(c->waiting); | ||
3371 | } | ||
3372 | # ifdef CONFIG_CISS_SCSI_TAPE | ||
3373 | else if (c->cmd_type == CMD_SCSI) | ||
3374 | complete_scsi_command(c, 0, a1); | ||
3375 | # endif | ||
3376 | continue; | ||
3377 | } | ||
3378 | } | 3480 | } |
3379 | } | 3481 | } |
3482 | spin_unlock_irqrestore(&h->lock, flags); | ||
3483 | return IRQ_HANDLED; | ||
3484 | } | ||
3380 | 3485 | ||
3381 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 3486 | /* Add a second interrupt handler for MSI/MSI-X mode. In this mode we never |
3487 | * check the interrupt pending register because it is not set. | ||
3488 | */ | ||
3489 | static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id) | ||
3490 | { | ||
3491 | ctlr_info_t *h = dev_id; | ||
3492 | unsigned long flags; | ||
3493 | u32 raw_tag; | ||
3494 | |||
3495 | spin_lock_irqsave(&h->lock, flags); | ||
3496 | raw_tag = get_next_completion(h); | ||
3497 | while (raw_tag != FIFO_EMPTY) { | ||
3498 | if (cciss_tag_contains_index(raw_tag)) | ||
3499 | raw_tag = process_indexed_cmd(h, raw_tag); | ||
3500 | else | ||
3501 | raw_tag = process_nonindexed_cmd(h, raw_tag); | ||
3502 | } | ||
3503 | spin_unlock_irqrestore(&h->lock, flags); | ||
3382 | return IRQ_HANDLED; | 3504 | return IRQ_HANDLED; |
3383 | } | 3505 | } |
3384 | 3506 | ||
@@ -3510,18 +3632,17 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) | |||
3510 | 3632 | ||
3511 | switch (c->err_info->SenseInfo[12]) { | 3633 | switch (c->err_info->SenseInfo[12]) { |
3512 | case STATE_CHANGED: | 3634 | case STATE_CHANGED: |
3513 | printk(KERN_WARNING "cciss%d: a state change " | 3635 | dev_warn(&h->pdev->dev, "a state change " |
3514 | "detected, command retried\n", h->ctlr); | 3636 | "detected, command retried\n"); |
3515 | return 1; | 3637 | return 1; |
3516 | break; | 3638 | break; |
3517 | case LUN_FAILED: | 3639 | case LUN_FAILED: |
3518 | printk(KERN_WARNING "cciss%d: LUN failure " | 3640 | dev_warn(&h->pdev->dev, "LUN failure " |
3519 | "detected, action required\n", h->ctlr); | 3641 | "detected, action required\n"); |
3520 | return 1; | 3642 | return 1; |
3521 | break; | 3643 | break; |
3522 | case REPORT_LUNS_CHANGED: | 3644 | case REPORT_LUNS_CHANGED: |
3523 | printk(KERN_WARNING "cciss%d: report LUN data " | 3645 | dev_warn(&h->pdev->dev, "report LUN data changed\n"); |
3524 | "changed\n", h->ctlr); | ||
3525 | /* | 3646 | /* |
3526 | * Here, we could call add_to_scan_list and wake up the scan thread, | 3647 | * Here, we could call add_to_scan_list and wake up the scan thread, |
3527 | * except that it's quite likely that we will get more than one | 3648 | * except that it's quite likely that we will get more than one |
@@ -3541,19 +3662,18 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) | |||
3541 | return 1; | 3662 | return 1; |
3542 | break; | 3663 | break; |
3543 | case POWER_OR_RESET: | 3664 | case POWER_OR_RESET: |
3544 | printk(KERN_WARNING "cciss%d: a power on " | 3665 | dev_warn(&h->pdev->dev, |
3545 | "or device reset detected\n", h->ctlr); | 3666 | "a power on or device reset detected\n"); |
3546 | return 1; | 3667 | return 1; |
3547 | break; | 3668 | break; |
3548 | case UNIT_ATTENTION_CLEARED: | 3669 | case UNIT_ATTENTION_CLEARED: |
3549 | printk(KERN_WARNING "cciss%d: unit attention " | 3670 | dev_warn(&h->pdev->dev, |
3550 | "cleared by another initiator\n", h->ctlr); | 3671 | "unit attention cleared by another initiator\n"); |
3551 | return 1; | 3672 | return 1; |
3552 | break; | 3673 | break; |
3553 | default: | 3674 | default: |
3554 | printk(KERN_WARNING "cciss%d: unknown " | 3675 | dev_warn(&h->pdev->dev, "unknown unit attention detected\n"); |
3555 | "unit attention detected\n", h->ctlr); | 3676 | return 1; |
3556 | return 1; | ||
3557 | } | 3677 | } |
3558 | } | 3678 | } |
3559 | 3679 | ||
@@ -3562,39 +3682,41 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) | |||
3562 | * the io functions. | 3682 | * the io functions. |
3563 | * This is for debug only. | 3683 | * This is for debug only. |
3564 | */ | 3684 | */ |
3565 | #ifdef CCISS_DEBUG | 3685 | static void print_cfg_table(ctlr_info_t *h) |
3566 | static void print_cfg_table(CfgTable_struct *tb) | ||
3567 | { | 3686 | { |
3568 | int i; | 3687 | int i; |
3569 | char temp_name[17]; | 3688 | char temp_name[17]; |
3689 | CfgTable_struct *tb = h->cfgtable; | ||
3570 | 3690 | ||
3571 | printk("Controller Configuration information\n"); | 3691 | dev_dbg(&h->pdev->dev, "Controller Configuration information\n"); |
3572 | printk("------------------------------------\n"); | 3692 | dev_dbg(&h->pdev->dev, "------------------------------------\n"); |
3573 | for (i = 0; i < 4; i++) | 3693 | for (i = 0; i < 4; i++) |
3574 | temp_name[i] = readb(&(tb->Signature[i])); | 3694 | temp_name[i] = readb(&(tb->Signature[i])); |
3575 | temp_name[4] = '\0'; | 3695 | temp_name[4] = '\0'; |
3576 | printk(" Signature = %s\n", temp_name); | 3696 | dev_dbg(&h->pdev->dev, " Signature = %s\n", temp_name); |
3577 | printk(" Spec Number = %d\n", readl(&(tb->SpecValence))); | 3697 | dev_dbg(&h->pdev->dev, " Spec Number = %d\n", |
3578 | printk(" Transport methods supported = 0x%x\n", | 3698 | readl(&(tb->SpecValence))); |
3699 | dev_dbg(&h->pdev->dev, " Transport methods supported = 0x%x\n", | ||
3579 | readl(&(tb->TransportSupport))); | 3700 | readl(&(tb->TransportSupport))); |
3580 | printk(" Transport methods active = 0x%x\n", | 3701 | dev_dbg(&h->pdev->dev, " Transport methods active = 0x%x\n", |
3581 | readl(&(tb->TransportActive))); | 3702 | readl(&(tb->TransportActive))); |
3582 | printk(" Requested transport Method = 0x%x\n", | 3703 | dev_dbg(&h->pdev->dev, " Requested transport Method = 0x%x\n", |
3583 | readl(&(tb->HostWrite.TransportRequest))); | 3704 | readl(&(tb->HostWrite.TransportRequest))); |
3584 | printk(" Coalesce Interrupt Delay = 0x%x\n", | 3705 | dev_dbg(&h->pdev->dev, " Coalesce Interrupt Delay = 0x%x\n", |
3585 | readl(&(tb->HostWrite.CoalIntDelay))); | 3706 | readl(&(tb->HostWrite.CoalIntDelay))); |
3586 | printk(" Coalesce Interrupt Count = 0x%x\n", | 3707 | dev_dbg(&h->pdev->dev, " Coalesce Interrupt Count = 0x%x\n", |
3587 | readl(&(tb->HostWrite.CoalIntCount))); | 3708 | readl(&(tb->HostWrite.CoalIntCount))); |
3588 | printk(" Max outstanding commands = 0x%d\n", | 3709 | dev_dbg(&h->pdev->dev, " Max outstanding commands = 0x%d\n", |
3589 | readl(&(tb->CmdsOutMax))); | 3710 | readl(&(tb->CmdsOutMax))); |
3590 | printk(" Bus Types = 0x%x\n", readl(&(tb->BusTypes))); | 3711 | dev_dbg(&h->pdev->dev, " Bus Types = 0x%x\n", |
3712 | readl(&(tb->BusTypes))); | ||
3591 | for (i = 0; i < 16; i++) | 3713 | for (i = 0; i < 16; i++) |
3592 | temp_name[i] = readb(&(tb->ServerName[i])); | 3714 | temp_name[i] = readb(&(tb->ServerName[i])); |
3593 | temp_name[16] = '\0'; | 3715 | temp_name[16] = '\0'; |
3594 | printk(" Server Name = %s\n", temp_name); | 3716 | dev_dbg(&h->pdev->dev, " Server Name = %s\n", temp_name); |
3595 | printk(" Heartbeat Counter = 0x%x\n\n\n", readl(&(tb->HeartBeat))); | 3717 | dev_dbg(&h->pdev->dev, " Heartbeat Counter = 0x%x\n\n\n", |
3718 | readl(&(tb->HeartBeat))); | ||
3596 | } | 3719 | } |
3597 | #endif /* CCISS_DEBUG */ | ||
3598 | 3720 | ||
3599 | static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) | 3721 | static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) |
3600 | { | 3722 | { |
@@ -3618,7 +3740,7 @@ static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) | |||
3618 | offset += 8; | 3740 | offset += 8; |
3619 | break; | 3741 | break; |
3620 | default: /* reserved in PCI 2.2 */ | 3742 | default: /* reserved in PCI 2.2 */ |
3621 | printk(KERN_WARNING | 3743 | dev_warn(&pdev->dev, |
3622 | "Base address is invalid\n"); | 3744 | "Base address is invalid\n"); |
3623 | return -1; | 3745 | return -1; |
3624 | break; | 3746 | break; |
@@ -3630,12 +3752,182 @@ static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) | |||
3630 | return -1; | 3752 | return -1; |
3631 | } | 3753 | } |
3632 | 3754 | ||
3755 | /* Fill in bucket_map[], given nsgs (the max number of | ||
3756 | * scatter gather elements supported) and bucket[], | ||
3757 | * which is an array of 8 integers. The bucket[] array | ||
3758 | * contains 8 different DMA transfer sizes (in 16 | ||
3759 | * byte increments) which the controller uses to fetch | ||
3760 | * commands. This function fills in bucket_map[], which | ||
3761 | * maps a given number of scatter gather elements to one of | ||
3762 | * the 8 DMA transfer sizes. The point of it is to allow the | ||
3763 | * controller to only do as much DMA as needed to fetch the | ||
3764 | * command, with the DMA transfer size encoded in the lower | ||
3765 | * bits of the command address. | ||
3766 | */ | ||
3767 | static void calc_bucket_map(int bucket[], int num_buckets, | ||
3768 | int nsgs, int *bucket_map) | ||
3769 | { | ||
3770 | int i, j, b, size; | ||
3771 | |||
3772 | /* even a command with 0 SGs requires 4 blocks */ | ||
3773 | #define MINIMUM_TRANSFER_BLOCKS 4 | ||
3774 | #define NUM_BUCKETS 8 | ||
3775 | /* Note, bucket_map must have nsgs+1 entries. */ | ||
3776 | for (i = 0; i <= nsgs; i++) { | ||
3777 | /* Compute size of a command with i SG entries */ | ||
3778 | size = i + MINIMUM_TRANSFER_BLOCKS; | ||
3779 | b = num_buckets; /* Assume the biggest bucket */ | ||
3780 | /* Find the bucket that is just big enough */ | ||
3781 | for (j = 0; j < 8; j++) { | ||
3782 | if (bucket[j] >= size) { | ||
3783 | b = j; | ||
3784 | break; | ||
3785 | } | ||
3786 | } | ||
3787 | /* for a command with i SG entries, use bucket b. */ | ||
3788 | bucket_map[i] = b; | ||
3789 | } | ||
3790 | } | ||
3791 | |||
3792 | static void __devinit cciss_wait_for_mode_change_ack(ctlr_info_t *h) | ||
3793 | { | ||
3794 | int i; | ||
3795 | |||
3796 | /* under certain very rare conditions, this can take awhile. | ||
3797 | * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right | ||
3798 | * as we enter this code.) */ | ||
3799 | for (i = 0; i < MAX_CONFIG_WAIT; i++) { | ||
3800 | if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) | ||
3801 | break; | ||
3802 | msleep(10); | ||
3803 | } | ||
3804 | } | ||
3805 | |||
3806 | static __devinit void cciss_enter_performant_mode(ctlr_info_t *h) | ||
3807 | { | ||
3808 | /* This is a bit complicated. There are 8 registers on | ||
3809 | * the controller which we write to to tell it 8 different | ||
3810 | * sizes of commands which there may be. It's a way of | ||
3811 | * reducing the DMA done to fetch each command. Encoded into | ||
3812 | * each command's tag are 3 bits which communicate to the controller | ||
3813 | * which of the eight sizes that command fits within. The size of | ||
3814 | * each command depends on how many scatter gather entries there are. | ||
3815 | * Each SG entry requires 16 bytes. The eight registers are programmed | ||
3816 | * with the number of 16-byte blocks a command of that size requires. | ||
3817 | * The smallest command possible requires 5 such 16 byte blocks. | ||
3818 | * the largest command possible requires MAXSGENTRIES + 4 16-byte | ||
3819 | * blocks. Note, this only extends to the SG entries contained | ||
3820 | * within the command block, and does not extend to chained blocks | ||
3821 | * of SG elements. bft[] contains the eight values we write to | ||
3822 | * the registers. They are not evenly distributed, but have more | ||
3823 | * sizes for small commands, and fewer sizes for larger commands. | ||
3824 | */ | ||
3825 | __u32 trans_offset; | ||
3826 | int bft[8] = { 5, 6, 8, 10, 12, 20, 28, MAXSGENTRIES + 4}; | ||
3827 | /* | ||
3828 | * 5 = 1 s/g entry or 4k | ||
3829 | * 6 = 2 s/g entry or 8k | ||
3830 | * 8 = 4 s/g entry or 16k | ||
3831 | * 10 = 6 s/g entry or 24k | ||
3832 | */ | ||
3833 | unsigned long register_value; | ||
3834 | BUILD_BUG_ON(28 > MAXSGENTRIES + 4); | ||
3835 | |||
3836 | h->reply_pool_wraparound = 1; /* spec: init to 1 */ | ||
3837 | |||
3838 | /* Controller spec: zero out this buffer. */ | ||
3839 | memset(h->reply_pool, 0, h->max_commands * sizeof(__u64)); | ||
3840 | h->reply_pool_head = h->reply_pool; | ||
3841 | |||
3842 | trans_offset = readl(&(h->cfgtable->TransMethodOffset)); | ||
3843 | calc_bucket_map(bft, ARRAY_SIZE(bft), h->maxsgentries, | ||
3844 | h->blockFetchTable); | ||
3845 | writel(bft[0], &h->transtable->BlockFetch0); | ||
3846 | writel(bft[1], &h->transtable->BlockFetch1); | ||
3847 | writel(bft[2], &h->transtable->BlockFetch2); | ||
3848 | writel(bft[3], &h->transtable->BlockFetch3); | ||
3849 | writel(bft[4], &h->transtable->BlockFetch4); | ||
3850 | writel(bft[5], &h->transtable->BlockFetch5); | ||
3851 | writel(bft[6], &h->transtable->BlockFetch6); | ||
3852 | writel(bft[7], &h->transtable->BlockFetch7); | ||
3853 | |||
3854 | /* size of controller ring buffer */ | ||
3855 | writel(h->max_commands, &h->transtable->RepQSize); | ||
3856 | writel(1, &h->transtable->RepQCount); | ||
3857 | writel(0, &h->transtable->RepQCtrAddrLow32); | ||
3858 | writel(0, &h->transtable->RepQCtrAddrHigh32); | ||
3859 | writel(h->reply_pool_dhandle, &h->transtable->RepQAddr0Low32); | ||
3860 | writel(0, &h->transtable->RepQAddr0High32); | ||
3861 | writel(CFGTBL_Trans_Performant, | ||
3862 | &(h->cfgtable->HostWrite.TransportRequest)); | ||
3863 | |||
3864 | writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); | ||
3865 | cciss_wait_for_mode_change_ack(h); | ||
3866 | register_value = readl(&(h->cfgtable->TransportActive)); | ||
3867 | if (!(register_value & CFGTBL_Trans_Performant)) | ||
3868 | dev_warn(&h->pdev->dev, "cciss: unable to get board into" | ||
3869 | " performant mode\n"); | ||
3870 | } | ||
3871 | |||
3872 | static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h) | ||
3873 | { | ||
3874 | __u32 trans_support; | ||
3875 | |||
3876 | dev_dbg(&h->pdev->dev, "Trying to put board into Performant mode\n"); | ||
3877 | /* Attempt to put controller into performant mode if supported */ | ||
3878 | /* Does board support performant mode? */ | ||
3879 | trans_support = readl(&(h->cfgtable->TransportSupport)); | ||
3880 | if (!(trans_support & PERFORMANT_MODE)) | ||
3881 | return; | ||
3882 | |||
3883 | dev_dbg(&h->pdev->dev, "Placing controller into performant mode\n"); | ||
3884 | /* Performant mode demands commands on a 32 byte boundary | ||
3885 | * pci_alloc_consistent aligns on page boundarys already. | ||
3886 | * Just need to check if divisible by 32 | ||
3887 | */ | ||
3888 | if ((sizeof(CommandList_struct) % 32) != 0) { | ||
3889 | dev_warn(&h->pdev->dev, "%s %d %s\n", | ||
3890 | "cciss info: command size[", | ||
3891 | (int)sizeof(CommandList_struct), | ||
3892 | "] not divisible by 32, no performant mode..\n"); | ||
3893 | return; | ||
3894 | } | ||
3895 | |||
3896 | /* Performant mode ring buffer and supporting data structures */ | ||
3897 | h->reply_pool = (__u64 *)pci_alloc_consistent( | ||
3898 | h->pdev, h->max_commands * sizeof(__u64), | ||
3899 | &(h->reply_pool_dhandle)); | ||
3900 | |||
3901 | /* Need a block fetch table for performant mode */ | ||
3902 | h->blockFetchTable = kmalloc(((h->maxsgentries+1) * | ||
3903 | sizeof(__u32)), GFP_KERNEL); | ||
3904 | |||
3905 | if ((h->reply_pool == NULL) || (h->blockFetchTable == NULL)) | ||
3906 | goto clean_up; | ||
3907 | |||
3908 | cciss_enter_performant_mode(h); | ||
3909 | |||
3910 | /* Change the access methods to the performant access methods */ | ||
3911 | h->access = SA5_performant_access; | ||
3912 | h->transMethod = CFGTBL_Trans_Performant; | ||
3913 | |||
3914 | return; | ||
3915 | clean_up: | ||
3916 | kfree(h->blockFetchTable); | ||
3917 | if (h->reply_pool) | ||
3918 | pci_free_consistent(h->pdev, | ||
3919 | h->max_commands * sizeof(__u64), | ||
3920 | h->reply_pool, | ||
3921 | h->reply_pool_dhandle); | ||
3922 | return; | ||
3923 | |||
3924 | } /* cciss_put_controller_into_performant_mode */ | ||
3925 | |||
3633 | /* If MSI/MSI-X is supported by the kernel we will try to enable it on | 3926 | /* If MSI/MSI-X is supported by the kernel we will try to enable it on |
3634 | * controllers that are capable. If not, we use IO-APIC mode. | 3927 | * controllers that are capable. If not, we use IO-APIC mode. |
3635 | */ | 3928 | */ |
3636 | 3929 | ||
3637 | static void __devinit cciss_interrupt_mode(ctlr_info_t *c, | 3930 | static void __devinit cciss_interrupt_mode(ctlr_info_t *h) |
3638 | struct pci_dev *pdev, __u32 board_id) | ||
3639 | { | 3931 | { |
3640 | #ifdef CONFIG_PCI_MSI | 3932 | #ifdef CONFIG_PCI_MSI |
3641 | int err; | 3933 | int err; |
@@ -3644,268 +3936,283 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c, | |||
3644 | }; | 3936 | }; |
3645 | 3937 | ||
3646 | /* Some boards advertise MSI but don't really support it */ | 3938 | /* Some boards advertise MSI but don't really support it */ |
3647 | if ((board_id == 0x40700E11) || | 3939 | if ((h->board_id == 0x40700E11) || (h->board_id == 0x40800E11) || |
3648 | (board_id == 0x40800E11) || | 3940 | (h->board_id == 0x40820E11) || (h->board_id == 0x40830E11)) |
3649 | (board_id == 0x40820E11) || (board_id == 0x40830E11)) | ||
3650 | goto default_int_mode; | 3941 | goto default_int_mode; |
3651 | 3942 | ||
3652 | if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { | 3943 | if (pci_find_capability(h->pdev, PCI_CAP_ID_MSIX)) { |
3653 | err = pci_enable_msix(pdev, cciss_msix_entries, 4); | 3944 | err = pci_enable_msix(h->pdev, cciss_msix_entries, 4); |
3654 | if (!err) { | 3945 | if (!err) { |
3655 | c->intr[0] = cciss_msix_entries[0].vector; | 3946 | h->intr[0] = cciss_msix_entries[0].vector; |
3656 | c->intr[1] = cciss_msix_entries[1].vector; | 3947 | h->intr[1] = cciss_msix_entries[1].vector; |
3657 | c->intr[2] = cciss_msix_entries[2].vector; | 3948 | h->intr[2] = cciss_msix_entries[2].vector; |
3658 | c->intr[3] = cciss_msix_entries[3].vector; | 3949 | h->intr[3] = cciss_msix_entries[3].vector; |
3659 | c->msix_vector = 1; | 3950 | h->msix_vector = 1; |
3660 | return; | 3951 | return; |
3661 | } | 3952 | } |
3662 | if (err > 0) { | 3953 | if (err > 0) { |
3663 | printk(KERN_WARNING "cciss: only %d MSI-X vectors " | 3954 | dev_warn(&h->pdev->dev, |
3664 | "available\n", err); | 3955 | "only %d MSI-X vectors available\n", err); |
3665 | goto default_int_mode; | 3956 | goto default_int_mode; |
3666 | } else { | 3957 | } else { |
3667 | printk(KERN_WARNING "cciss: MSI-X init failed %d\n", | 3958 | dev_warn(&h->pdev->dev, |
3668 | err); | 3959 | "MSI-X init failed %d\n", err); |
3669 | goto default_int_mode; | 3960 | goto default_int_mode; |
3670 | } | 3961 | } |
3671 | } | 3962 | } |
3672 | if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) { | 3963 | if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) { |
3673 | if (!pci_enable_msi(pdev)) { | 3964 | if (!pci_enable_msi(h->pdev)) |
3674 | c->msi_vector = 1; | 3965 | h->msi_vector = 1; |
3675 | } else { | 3966 | else |
3676 | printk(KERN_WARNING "cciss: MSI init failed\n"); | 3967 | dev_warn(&h->pdev->dev, "MSI init failed\n"); |
3677 | } | ||
3678 | } | 3968 | } |
3679 | default_int_mode: | 3969 | default_int_mode: |
3680 | #endif /* CONFIG_PCI_MSI */ | 3970 | #endif /* CONFIG_PCI_MSI */ |
3681 | /* if we get here we're going to use the default interrupt mode */ | 3971 | /* if we get here we're going to use the default interrupt mode */ |
3682 | c->intr[SIMPLE_MODE_INT] = pdev->irq; | 3972 | h->intr[PERF_MODE_INT] = h->pdev->irq; |
3683 | return; | 3973 | return; |
3684 | } | 3974 | } |
3685 | 3975 | ||
3686 | static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | 3976 | static int __devinit cciss_lookup_board_id(struct pci_dev *pdev, u32 *board_id) |
3687 | { | 3977 | { |
3688 | ushort subsystem_vendor_id, subsystem_device_id, command; | 3978 | int i; |
3689 | __u32 board_id, scratchpad = 0; | 3979 | u32 subsystem_vendor_id, subsystem_device_id; |
3690 | __u64 cfg_offset; | ||
3691 | __u32 cfg_base_addr; | ||
3692 | __u64 cfg_base_addr_index; | ||
3693 | int i, prod_index, err; | ||
3694 | 3980 | ||
3695 | subsystem_vendor_id = pdev->subsystem_vendor; | 3981 | subsystem_vendor_id = pdev->subsystem_vendor; |
3696 | subsystem_device_id = pdev->subsystem_device; | 3982 | subsystem_device_id = pdev->subsystem_device; |
3697 | board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | | 3983 | *board_id = ((subsystem_device_id << 16) & 0xffff0000) | |
3698 | subsystem_vendor_id); | 3984 | subsystem_vendor_id; |
3699 | 3985 | ||
3700 | for (i = 0; i < ARRAY_SIZE(products); i++) { | 3986 | for (i = 0; i < ARRAY_SIZE(products); i++) { |
3701 | /* Stand aside for hpsa driver on request */ | 3987 | /* Stand aside for hpsa driver on request */ |
3702 | if (cciss_allow_hpsa && products[i].board_id == HPSA_BOUNDARY) | 3988 | if (cciss_allow_hpsa && products[i].board_id == HPSA_BOUNDARY) |
3703 | return -ENODEV; | 3989 | return -ENODEV; |
3704 | if (board_id == products[i].board_id) | 3990 | if (*board_id == products[i].board_id) |
3705 | break; | 3991 | return i; |
3706 | } | ||
3707 | prod_index = i; | ||
3708 | if (prod_index == ARRAY_SIZE(products)) { | ||
3709 | dev_warn(&pdev->dev, | ||
3710 | "unrecognized board ID: 0x%08lx, ignoring.\n", | ||
3711 | (unsigned long) board_id); | ||
3712 | return -ENODEV; | ||
3713 | } | 3992 | } |
3993 | dev_warn(&pdev->dev, "unrecognized board ID: 0x%08x, ignoring.\n", | ||
3994 | *board_id); | ||
3995 | return -ENODEV; | ||
3996 | } | ||
3714 | 3997 | ||
3715 | /* check to see if controller has been disabled */ | 3998 | static inline bool cciss_board_disabled(ctlr_info_t *h) |
3716 | /* BEFORE trying to enable it */ | 3999 | { |
3717 | (void)pci_read_config_word(pdev, PCI_COMMAND, &command); | 4000 | u16 command; |
3718 | if (!(command & 0x02)) { | ||
3719 | printk(KERN_WARNING | ||
3720 | "cciss: controller appears to be disabled\n"); | ||
3721 | return -ENODEV; | ||
3722 | } | ||
3723 | 4001 | ||
3724 | err = pci_enable_device(pdev); | 4002 | (void) pci_read_config_word(h->pdev, PCI_COMMAND, &command); |
3725 | if (err) { | 4003 | return ((command & PCI_COMMAND_MEMORY) == 0); |
3726 | printk(KERN_ERR "cciss: Unable to Enable PCI device\n"); | 4004 | } |
3727 | return err; | ||
3728 | } | ||
3729 | 4005 | ||
3730 | err = pci_request_regions(pdev, "cciss"); | 4006 | static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev, |
3731 | if (err) { | 4007 | unsigned long *memory_bar) |
3732 | printk(KERN_ERR "cciss: Cannot obtain PCI resources, " | 4008 | { |
3733 | "aborting\n"); | 4009 | int i; |
3734 | return err; | ||
3735 | } | ||
3736 | 4010 | ||
3737 | #ifdef CCISS_DEBUG | 4011 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) |
3738 | printk("command = %x\n", command); | 4012 | if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) { |
3739 | printk("irq = %x\n", pdev->irq); | 4013 | /* addressing mode bits already removed */ |
3740 | printk("board_id = %x\n", board_id); | 4014 | *memory_bar = pci_resource_start(pdev, i); |
3741 | #endif /* CCISS_DEBUG */ | 4015 | dev_dbg(&pdev->dev, "memory BAR = %lx\n", |
4016 | *memory_bar); | ||
4017 | return 0; | ||
4018 | } | ||
4019 | dev_warn(&pdev->dev, "no memory BAR found\n"); | ||
4020 | return -ENODEV; | ||
4021 | } | ||
3742 | 4022 | ||
3743 | /* If the kernel supports MSI/MSI-X we will try to enable that functionality, | 4023 | static int __devinit cciss_wait_for_board_ready(ctlr_info_t *h) |
3744 | * else we use the IO-APIC interrupt assigned to us by system ROM. | 4024 | { |
3745 | */ | 4025 | int i; |
3746 | cciss_interrupt_mode(c, pdev, board_id); | 4026 | u32 scratchpad; |
3747 | 4027 | ||
3748 | /* find the memory BAR */ | 4028 | for (i = 0; i < CCISS_BOARD_READY_ITERATIONS; i++) { |
3749 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 4029 | scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); |
3750 | if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) | 4030 | if (scratchpad == CCISS_FIRMWARE_READY) |
3751 | break; | 4031 | return 0; |
3752 | } | 4032 | msleep(CCISS_BOARD_READY_POLL_INTERVAL_MSECS); |
3753 | if (i == DEVICE_COUNT_RESOURCE) { | ||
3754 | printk(KERN_WARNING "cciss: No memory BAR found\n"); | ||
3755 | err = -ENODEV; | ||
3756 | goto err_out_free_res; | ||
3757 | } | 4033 | } |
4034 | dev_warn(&h->pdev->dev, "board not ready, timed out.\n"); | ||
4035 | return -ENODEV; | ||
4036 | } | ||
3758 | 4037 | ||
3759 | c->paddr = pci_resource_start(pdev, i); /* addressing mode bits | 4038 | static int __devinit cciss_find_cfg_addrs(struct pci_dev *pdev, |
3760 | * already removed | 4039 | void __iomem *vaddr, u32 *cfg_base_addr, u64 *cfg_base_addr_index, |
3761 | */ | 4040 | u64 *cfg_offset) |
4041 | { | ||
4042 | *cfg_base_addr = readl(vaddr + SA5_CTCFG_OFFSET); | ||
4043 | *cfg_offset = readl(vaddr + SA5_CTMEM_OFFSET); | ||
4044 | *cfg_base_addr &= (u32) 0x0000ffff; | ||
4045 | *cfg_base_addr_index = find_PCI_BAR_index(pdev, *cfg_base_addr); | ||
4046 | if (*cfg_base_addr_index == -1) { | ||
4047 | dev_warn(&pdev->dev, "cannot find cfg_base_addr_index, " | ||
4048 | "*cfg_base_addr = 0x%08x\n", *cfg_base_addr); | ||
4049 | return -ENODEV; | ||
4050 | } | ||
4051 | return 0; | ||
4052 | } | ||
3762 | 4053 | ||
3763 | #ifdef CCISS_DEBUG | 4054 | static int __devinit cciss_find_cfgtables(ctlr_info_t *h) |
3764 | printk("address 0 = %lx\n", c->paddr); | 4055 | { |
3765 | #endif /* CCISS_DEBUG */ | 4056 | u64 cfg_offset; |
3766 | c->vaddr = remap_pci_mem(c->paddr, 0x250); | 4057 | u32 cfg_base_addr; |
4058 | u64 cfg_base_addr_index; | ||
4059 | u32 trans_offset; | ||
4060 | int rc; | ||
3767 | 4061 | ||
3768 | /* Wait for the board to become ready. (PCI hotplug needs this.) | 4062 | rc = cciss_find_cfg_addrs(h->pdev, h->vaddr, &cfg_base_addr, |
3769 | * We poll for up to 120 secs, once per 100ms. */ | 4063 | &cfg_base_addr_index, &cfg_offset); |
3770 | for (i = 0; i < 1200; i++) { | 4064 | if (rc) |
3771 | scratchpad = readl(c->vaddr + SA5_SCRATCHPAD_OFFSET); | 4065 | return rc; |
3772 | if (scratchpad == CCISS_FIRMWARE_READY) | 4066 | h->cfgtable = remap_pci_mem(pci_resource_start(h->pdev, |
3773 | break; | 4067 | cfg_base_addr_index) + cfg_offset, sizeof(h->cfgtable)); |
3774 | set_current_state(TASK_INTERRUPTIBLE); | 4068 | if (!h->cfgtable) |
3775 | schedule_timeout(msecs_to_jiffies(100)); /* wait 100ms */ | 4069 | return -ENOMEM; |
3776 | } | 4070 | /* Find performant mode table. */ |
3777 | if (scratchpad != CCISS_FIRMWARE_READY) { | 4071 | trans_offset = readl(&h->cfgtable->TransMethodOffset); |
3778 | printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); | 4072 | h->transtable = remap_pci_mem(pci_resource_start(h->pdev, |
3779 | err = -ENODEV; | 4073 | cfg_base_addr_index)+cfg_offset+trans_offset, |
3780 | goto err_out_free_res; | 4074 | sizeof(*h->transtable)); |
3781 | } | 4075 | if (!h->transtable) |
4076 | return -ENOMEM; | ||
4077 | return 0; | ||
4078 | } | ||
3782 | 4079 | ||
3783 | /* get the address index number */ | 4080 | static void __devinit cciss_get_max_perf_mode_cmds(struct ctlr_info *h) |
3784 | cfg_base_addr = readl(c->vaddr + SA5_CTCFG_OFFSET); | 4081 | { |
3785 | cfg_base_addr &= (__u32) 0x0000ffff; | 4082 | h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); |
3786 | #ifdef CCISS_DEBUG | 4083 | if (h->max_commands < 16) { |
3787 | printk("cfg base address = %x\n", cfg_base_addr); | 4084 | dev_warn(&h->pdev->dev, "Controller reports " |
3788 | #endif /* CCISS_DEBUG */ | 4085 | "max supported commands of %d, an obvious lie. " |
3789 | cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr); | 4086 | "Using 16. Ensure that firmware is up to date.\n", |
3790 | #ifdef CCISS_DEBUG | 4087 | h->max_commands); |
3791 | printk("cfg base address index = %llx\n", | 4088 | h->max_commands = 16; |
3792 | (unsigned long long)cfg_base_addr_index); | ||
3793 | #endif /* CCISS_DEBUG */ | ||
3794 | if (cfg_base_addr_index == -1) { | ||
3795 | printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n"); | ||
3796 | err = -ENODEV; | ||
3797 | goto err_out_free_res; | ||
3798 | } | 4089 | } |
4090 | } | ||
3799 | 4091 | ||
3800 | cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET); | 4092 | /* Interrogate the hardware for some limits: |
3801 | #ifdef CCISS_DEBUG | 4093 | * max commands, max SG elements without chaining, and with chaining, |
3802 | printk("cfg offset = %llx\n", (unsigned long long)cfg_offset); | 4094 | * SG chain block size, etc. |
3803 | #endif /* CCISS_DEBUG */ | 4095 | */ |
3804 | c->cfgtable = remap_pci_mem(pci_resource_start(pdev, | 4096 | static void __devinit cciss_find_board_params(ctlr_info_t *h) |
3805 | cfg_base_addr_index) + | 4097 | { |
3806 | cfg_offset, sizeof(CfgTable_struct)); | 4098 | cciss_get_max_perf_mode_cmds(h); |
3807 | c->board_id = board_id; | 4099 | h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ |
3808 | 4100 | h->maxsgentries = readl(&(h->cfgtable->MaxSGElements)); | |
3809 | #ifdef CCISS_DEBUG | ||
3810 | print_cfg_table(c->cfgtable); | ||
3811 | #endif /* CCISS_DEBUG */ | ||
3812 | |||
3813 | /* Some controllers support Zero Memory Raid (ZMR). | ||
3814 | * When configured in ZMR mode the number of supported | ||
3815 | * commands drops to 64. So instead of just setting an | ||
3816 | * arbitrary value we make the driver a little smarter. | ||
3817 | * We read the config table to tell us how many commands | ||
3818 | * are supported on the controller then subtract 4 to | ||
3819 | * leave a little room for ioctl calls. | ||
3820 | */ | ||
3821 | c->max_commands = readl(&(c->cfgtable->CmdsOutMax)); | ||
3822 | c->maxsgentries = readl(&(c->cfgtable->MaxSGElements)); | ||
3823 | |||
3824 | /* | 4101 | /* |
3825 | * Limit native command to 32 s/g elements to save dma'able memory. | 4102 | * Limit in-command s/g elements to 32 save dma'able memory. |
3826 | * Howvever spec says if 0, use 31 | 4103 | * Howvever spec says if 0, use 31 |
3827 | */ | 4104 | */ |
3828 | 4105 | h->max_cmd_sgentries = 31; | |
3829 | c->max_cmd_sgentries = 31; | 4106 | if (h->maxsgentries > 512) { |
3830 | if (c->maxsgentries > 512) { | 4107 | h->max_cmd_sgentries = 32; |
3831 | c->max_cmd_sgentries = 32; | 4108 | h->chainsize = h->maxsgentries - h->max_cmd_sgentries + 1; |
3832 | c->chainsize = c->maxsgentries - c->max_cmd_sgentries + 1; | 4109 | h->maxsgentries--; /* save one for chain pointer */ |
3833 | c->maxsgentries -= 1; /* account for chain pointer */ | ||
3834 | } else { | 4110 | } else { |
3835 | c->maxsgentries = 31; /* Default to traditional value */ | 4111 | h->maxsgentries = 31; /* default to traditional values */ |
3836 | c->chainsize = 0; /* traditional */ | 4112 | h->chainsize = 0; |
3837 | } | 4113 | } |
4114 | } | ||
3838 | 4115 | ||
3839 | c->product_name = products[prod_index].product_name; | 4116 | static inline bool CISS_signature_present(ctlr_info_t *h) |
3840 | c->access = *(products[prod_index].access); | 4117 | { |
3841 | c->nr_cmds = c->max_commands - 4; | 4118 | if ((readb(&h->cfgtable->Signature[0]) != 'C') || |
3842 | if ((readb(&c->cfgtable->Signature[0]) != 'C') || | 4119 | (readb(&h->cfgtable->Signature[1]) != 'I') || |
3843 | (readb(&c->cfgtable->Signature[1]) != 'I') || | 4120 | (readb(&h->cfgtable->Signature[2]) != 'S') || |
3844 | (readb(&c->cfgtable->Signature[2]) != 'S') || | 4121 | (readb(&h->cfgtable->Signature[3]) != 'S')) { |
3845 | (readb(&c->cfgtable->Signature[3]) != 'S')) { | 4122 | dev_warn(&h->pdev->dev, "not a valid CISS config table\n"); |
3846 | printk("Does not appear to be a valid CISS config table\n"); | 4123 | return false; |
3847 | err = -ENODEV; | ||
3848 | goto err_out_free_res; | ||
3849 | } | 4124 | } |
4125 | return true; | ||
4126 | } | ||
4127 | |||
4128 | /* Need to enable prefetch in the SCSI core for 6400 in x86 */ | ||
4129 | static inline void cciss_enable_scsi_prefetch(ctlr_info_t *h) | ||
4130 | { | ||
3850 | #ifdef CONFIG_X86 | 4131 | #ifdef CONFIG_X86 |
3851 | { | 4132 | u32 prefetch; |
3852 | /* Need to enable prefetch in the SCSI core for 6400 in x86 */ | 4133 | |
3853 | __u32 prefetch; | 4134 | prefetch = readl(&(h->cfgtable->SCSI_Prefetch)); |
3854 | prefetch = readl(&(c->cfgtable->SCSI_Prefetch)); | 4135 | prefetch |= 0x100; |
3855 | prefetch |= 0x100; | 4136 | writel(prefetch, &(h->cfgtable->SCSI_Prefetch)); |
3856 | writel(prefetch, &(c->cfgtable->SCSI_Prefetch)); | ||
3857 | } | ||
3858 | #endif | 4137 | #endif |
4138 | } | ||
3859 | 4139 | ||
3860 | /* Disabling DMA prefetch and refetch for the P600. | 4140 | /* Disable DMA prefetch for the P600. Otherwise an ASIC bug may result |
3861 | * An ASIC bug may result in accesses to invalid memory addresses. | 4141 | * in a prefetch beyond physical memory. |
3862 | * We've disabled prefetch for some time now. Testing with XEN | 4142 | */ |
3863 | * kernels revealed a bug in the refetch if dom0 resides on a P600. | 4143 | static inline void cciss_p600_dma_prefetch_quirk(ctlr_info_t *h) |
3864 | */ | 4144 | { |
3865 | if(board_id == 0x3225103C) { | 4145 | u32 dma_prefetch; |
3866 | __u32 dma_prefetch; | 4146 | __u32 dma_refetch; |
3867 | __u32 dma_refetch; | 4147 | |
3868 | dma_prefetch = readl(c->vaddr + I2O_DMA1_CFG); | 4148 | if (h->board_id != 0x3225103C) |
3869 | dma_prefetch |= 0x8000; | 4149 | return; |
3870 | writel(dma_prefetch, c->vaddr + I2O_DMA1_CFG); | 4150 | dma_prefetch = readl(h->vaddr + I2O_DMA1_CFG); |
3871 | pci_read_config_dword(pdev, PCI_COMMAND_PARITY, &dma_refetch); | 4151 | dma_prefetch |= 0x8000; |
3872 | dma_refetch |= 0x1; | 4152 | writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG); |
3873 | pci_write_config_dword(pdev, PCI_COMMAND_PARITY, dma_refetch); | 4153 | pci_read_config_dword(h->pdev, PCI_COMMAND_PARITY, &dma_refetch); |
4154 | dma_refetch |= 0x1; | ||
4155 | pci_write_config_dword(h->pdev, PCI_COMMAND_PARITY, dma_refetch); | ||
4156 | } | ||
4157 | |||
4158 | static int __devinit cciss_pci_init(ctlr_info_t *h) | ||
4159 | { | ||
4160 | int prod_index, err; | ||
4161 | |||
4162 | prod_index = cciss_lookup_board_id(h->pdev, &h->board_id); | ||
4163 | if (prod_index < 0) | ||
4164 | return -ENODEV; | ||
4165 | h->product_name = products[prod_index].product_name; | ||
4166 | h->access = *(products[prod_index].access); | ||
4167 | |||
4168 | if (cciss_board_disabled(h)) { | ||
4169 | dev_warn(&h->pdev->dev, "controller appears to be disabled\n"); | ||
4170 | return -ENODEV; | ||
4171 | } | ||
4172 | err = pci_enable_device(h->pdev); | ||
4173 | if (err) { | ||
4174 | dev_warn(&h->pdev->dev, "Unable to Enable PCI device\n"); | ||
4175 | return err; | ||
3874 | } | 4176 | } |
3875 | 4177 | ||
3876 | #ifdef CCISS_DEBUG | 4178 | err = pci_request_regions(h->pdev, "cciss"); |
3877 | printk("Trying to put board into Simple mode\n"); | 4179 | if (err) { |
3878 | #endif /* CCISS_DEBUG */ | 4180 | dev_warn(&h->pdev->dev, |
3879 | c->max_commands = readl(&(c->cfgtable->CmdsOutMax)); | 4181 | "Cannot obtain PCI resources, aborting\n"); |
3880 | /* Update the field, and then ring the doorbell */ | 4182 | return err; |
3881 | writel(CFGTBL_Trans_Simple, &(c->cfgtable->HostWrite.TransportRequest)); | 4183 | } |
3882 | writel(CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); | ||
3883 | 4184 | ||
3884 | /* under certain very rare conditions, this can take awhile. | 4185 | dev_dbg(&h->pdev->dev, "irq = %x\n", h->pdev->irq); |
3885 | * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right | 4186 | dev_dbg(&h->pdev->dev, "board_id = %x\n", h->board_id); |
3886 | * as we enter this code.) */ | 4187 | |
3887 | for (i = 0; i < MAX_CONFIG_WAIT; i++) { | 4188 | /* If the kernel supports MSI/MSI-X we will try to enable that functionality, |
3888 | if (!(readl(c->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) | 4189 | * else we use the IO-APIC interrupt assigned to us by system ROM. |
3889 | break; | 4190 | */ |
3890 | /* delay and try again */ | 4191 | cciss_interrupt_mode(h); |
3891 | set_current_state(TASK_INTERRUPTIBLE); | 4192 | err = cciss_pci_find_memory_BAR(h->pdev, &h->paddr); |
3892 | schedule_timeout(msecs_to_jiffies(1)); | 4193 | if (err) |
4194 | goto err_out_free_res; | ||
4195 | h->vaddr = remap_pci_mem(h->paddr, 0x250); | ||
4196 | if (!h->vaddr) { | ||
4197 | err = -ENOMEM; | ||
4198 | goto err_out_free_res; | ||
3893 | } | 4199 | } |
4200 | err = cciss_wait_for_board_ready(h); | ||
4201 | if (err) | ||
4202 | goto err_out_free_res; | ||
4203 | err = cciss_find_cfgtables(h); | ||
4204 | if (err) | ||
4205 | goto err_out_free_res; | ||
4206 | print_cfg_table(h); | ||
4207 | cciss_find_board_params(h); | ||
3894 | 4208 | ||
3895 | #ifdef CCISS_DEBUG | 4209 | if (!CISS_signature_present(h)) { |
3896 | printk(KERN_DEBUG "I counter got to %d %x\n", i, | ||
3897 | readl(c->vaddr + SA5_DOORBELL)); | ||
3898 | #endif /* CCISS_DEBUG */ | ||
3899 | #ifdef CCISS_DEBUG | ||
3900 | print_cfg_table(c->cfgtable); | ||
3901 | #endif /* CCISS_DEBUG */ | ||
3902 | |||
3903 | if (!(readl(&(c->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) { | ||
3904 | printk(KERN_WARNING "cciss: unable to get board into" | ||
3905 | " simple mode\n"); | ||
3906 | err = -ENODEV; | 4210 | err = -ENODEV; |
3907 | goto err_out_free_res; | 4211 | goto err_out_free_res; |
3908 | } | 4212 | } |
4213 | cciss_enable_scsi_prefetch(h); | ||
4214 | cciss_p600_dma_prefetch_quirk(h); | ||
4215 | cciss_put_controller_into_performant_mode(h); | ||
3909 | return 0; | 4216 | return 0; |
3910 | 4217 | ||
3911 | err_out_free_res: | 4218 | err_out_free_res: |
@@ -3913,42 +4220,47 @@ err_out_free_res: | |||
3913 | * Deliberately omit pci_disable_device(): it does something nasty to | 4220 | * Deliberately omit pci_disable_device(): it does something nasty to |
3914 | * Smart Array controllers that pci_enable_device does not undo | 4221 | * Smart Array controllers that pci_enable_device does not undo |
3915 | */ | 4222 | */ |
3916 | pci_release_regions(pdev); | 4223 | if (h->transtable) |
4224 | iounmap(h->transtable); | ||
4225 | if (h->cfgtable) | ||
4226 | iounmap(h->cfgtable); | ||
4227 | if (h->vaddr) | ||
4228 | iounmap(h->vaddr); | ||
4229 | pci_release_regions(h->pdev); | ||
3917 | return err; | 4230 | return err; |
3918 | } | 4231 | } |
3919 | 4232 | ||
3920 | /* Function to find the first free pointer into our hba[] array | 4233 | /* Function to find the first free pointer into our hba[] array |
3921 | * Returns -1 if no free entries are left. | 4234 | * Returns -1 if no free entries are left. |
3922 | */ | 4235 | */ |
3923 | static int alloc_cciss_hba(void) | 4236 | static int alloc_cciss_hba(struct pci_dev *pdev) |
3924 | { | 4237 | { |
3925 | int i; | 4238 | int i; |
3926 | 4239 | ||
3927 | for (i = 0; i < MAX_CTLR; i++) { | 4240 | for (i = 0; i < MAX_CTLR; i++) { |
3928 | if (!hba[i]) { | 4241 | if (!hba[i]) { |
3929 | ctlr_info_t *p; | 4242 | ctlr_info_t *h; |
3930 | 4243 | ||
3931 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); | 4244 | h = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); |
3932 | if (!p) | 4245 | if (!h) |
3933 | goto Enomem; | 4246 | goto Enomem; |
3934 | hba[i] = p; | 4247 | hba[i] = h; |
3935 | return i; | 4248 | return i; |
3936 | } | 4249 | } |
3937 | } | 4250 | } |
3938 | printk(KERN_WARNING "cciss: This driver supports a maximum" | 4251 | dev_warn(&pdev->dev, "This driver supports a maximum" |
3939 | " of %d controllers.\n", MAX_CTLR); | 4252 | " of %d controllers.\n", MAX_CTLR); |
3940 | return -1; | 4253 | return -1; |
3941 | Enomem: | 4254 | Enomem: |
3942 | printk(KERN_ERR "cciss: out of memory.\n"); | 4255 | dev_warn(&pdev->dev, "out of memory.\n"); |
3943 | return -1; | 4256 | return -1; |
3944 | } | 4257 | } |
3945 | 4258 | ||
3946 | static void free_hba(int n) | 4259 | static void free_hba(ctlr_info_t *h) |
3947 | { | 4260 | { |
3948 | ctlr_info_t *h = hba[n]; | ||
3949 | int i; | 4261 | int i; |
3950 | 4262 | ||
3951 | hba[n] = NULL; | 4263 | hba[h->ctlr] = NULL; |
3952 | for (i = 0; i < h->highest_lun + 1; i++) | 4264 | for (i = 0; i < h->highest_lun + 1; i++) |
3953 | if (h->gendisk[i] != NULL) | 4265 | if (h->gendisk[i] != NULL) |
3954 | put_disk(h->gendisk[i]); | 4266 | put_disk(h->gendisk[i]); |
@@ -4028,7 +4340,8 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u | |||
4028 | /* we leak the DMA buffer here ... no choice since the controller could | 4340 | /* we leak the DMA buffer here ... no choice since the controller could |
4029 | still complete the command. */ | 4341 | still complete the command. */ |
4030 | if (i == 10) { | 4342 | if (i == 10) { |
4031 | printk(KERN_ERR "cciss: controller message %02x:%02x timed out\n", | 4343 | dev_err(&pdev->dev, |
4344 | "controller message %02x:%02x timed out\n", | ||
4032 | opcode, type); | 4345 | opcode, type); |
4033 | return -ETIMEDOUT; | 4346 | return -ETIMEDOUT; |
4034 | } | 4347 | } |
@@ -4036,12 +4349,12 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u | |||
4036 | pci_free_consistent(pdev, cmd_sz, cmd, paddr64); | 4349 | pci_free_consistent(pdev, cmd_sz, cmd, paddr64); |
4037 | 4350 | ||
4038 | if (tag & 2) { | 4351 | if (tag & 2) { |
4039 | printk(KERN_ERR "cciss: controller message %02x:%02x failed\n", | 4352 | dev_err(&pdev->dev, "controller message %02x:%02x failed\n", |
4040 | opcode, type); | 4353 | opcode, type); |
4041 | return -EIO; | 4354 | return -EIO; |
4042 | } | 4355 | } |
4043 | 4356 | ||
4044 | printk(KERN_INFO "cciss: controller message %02x:%02x succeeded\n", | 4357 | dev_info(&pdev->dev, "controller message %02x:%02x succeeded\n", |
4045 | opcode, type); | 4358 | opcode, type); |
4046 | return 0; | 4359 | return 0; |
4047 | } | 4360 | } |
@@ -4062,7 +4375,7 @@ static __devinit int cciss_reset_msi(struct pci_dev *pdev) | |||
4062 | if (pos) { | 4375 | if (pos) { |
4063 | pci_read_config_word(pdev, msi_control_reg(pos), &control); | 4376 | pci_read_config_word(pdev, msi_control_reg(pos), &control); |
4064 | if (control & PCI_MSI_FLAGS_ENABLE) { | 4377 | if (control & PCI_MSI_FLAGS_ENABLE) { |
4065 | printk(KERN_INFO "cciss: resetting MSI\n"); | 4378 | dev_info(&pdev->dev, "resetting MSI\n"); |
4066 | pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE); | 4379 | pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE); |
4067 | } | 4380 | } |
4068 | } | 4381 | } |
@@ -4071,7 +4384,7 @@ static __devinit int cciss_reset_msi(struct pci_dev *pdev) | |||
4071 | if (pos) { | 4384 | if (pos) { |
4072 | pci_read_config_word(pdev, msi_control_reg(pos), &control); | 4385 | pci_read_config_word(pdev, msi_control_reg(pos), &control); |
4073 | if (control & PCI_MSIX_FLAGS_ENABLE) { | 4386 | if (control & PCI_MSIX_FLAGS_ENABLE) { |
4074 | printk(KERN_INFO "cciss: resetting MSI-X\n"); | 4387 | dev_info(&pdev->dev, "resetting MSI-X\n"); |
4075 | pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); | 4388 | pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); |
4076 | } | 4389 | } |
4077 | } | 4390 | } |
@@ -4079,68 +4392,144 @@ static __devinit int cciss_reset_msi(struct pci_dev *pdev) | |||
4079 | return 0; | 4392 | return 0; |
4080 | } | 4393 | } |
4081 | 4394 | ||
4082 | /* This does a hard reset of the controller using PCI power management | 4395 | static int cciss_controller_hard_reset(struct pci_dev *pdev, |
4083 | * states. */ | 4396 | void * __iomem vaddr, bool use_doorbell) |
4084 | static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev) | ||
4085 | { | 4397 | { |
4086 | u16 pmcsr, saved_config_space[32]; | 4398 | u16 pmcsr; |
4087 | int i, pos; | 4399 | int pos; |
4088 | 4400 | ||
4089 | printk(KERN_INFO "cciss: using PCI PM to reset controller\n"); | 4401 | if (use_doorbell) { |
4402 | /* For everything after the P600, the PCI power state method | ||
4403 | * of resetting the controller doesn't work, so we have this | ||
4404 | * other way using the doorbell register. | ||
4405 | */ | ||
4406 | dev_info(&pdev->dev, "using doorbell to reset controller\n"); | ||
4407 | writel(DOORBELL_CTLR_RESET, vaddr + SA5_DOORBELL); | ||
4408 | msleep(1000); | ||
4409 | } else { /* Try to do it the PCI power state way */ | ||
4410 | |||
4411 | /* Quoting from the Open CISS Specification: "The Power | ||
4412 | * Management Control/Status Register (CSR) controls the power | ||
4413 | * state of the device. The normal operating state is D0, | ||
4414 | * CSR=00h. The software off state is D3, CSR=03h. To reset | ||
4415 | * the controller, place the interface device in D3 then to D0, | ||
4416 | * this causes a secondary PCI reset which will reset the | ||
4417 | * controller." */ | ||
4418 | |||
4419 | pos = pci_find_capability(pdev, PCI_CAP_ID_PM); | ||
4420 | if (pos == 0) { | ||
4421 | dev_err(&pdev->dev, | ||
4422 | "cciss_controller_hard_reset: " | ||
4423 | "PCI PM not supported\n"); | ||
4424 | return -ENODEV; | ||
4425 | } | ||
4426 | dev_info(&pdev->dev, "using PCI PM to reset controller\n"); | ||
4427 | /* enter the D3hot power management state */ | ||
4428 | pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); | ||
4429 | pmcsr &= ~PCI_PM_CTRL_STATE_MASK; | ||
4430 | pmcsr |= PCI_D3hot; | ||
4431 | pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); | ||
4090 | 4432 | ||
4091 | /* This is very nearly the same thing as | 4433 | msleep(500); |
4092 | 4434 | ||
4093 | pci_save_state(pci_dev); | 4435 | /* enter the D0 power management state */ |
4094 | pci_set_power_state(pci_dev, PCI_D3hot); | 4436 | pmcsr &= ~PCI_PM_CTRL_STATE_MASK; |
4095 | pci_set_power_state(pci_dev, PCI_D0); | 4437 | pmcsr |= PCI_D0; |
4096 | pci_restore_state(pci_dev); | 4438 | pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); |
4097 | 4439 | ||
4098 | but we can't use these nice canned kernel routines on | 4440 | msleep(500); |
4099 | kexec, because they also check the MSI/MSI-X state in PCI | 4441 | } |
4100 | configuration space and do the wrong thing when it is | 4442 | return 0; |
4101 | set/cleared. Also, the pci_save/restore_state functions | 4443 | } |
4102 | violate the ordering requirements for restoring the | ||
4103 | configuration space from the CCISS document (see the | ||
4104 | comment below). So we roll our own .... */ | ||
4105 | 4444 | ||
4106 | for (i = 0; i < 32; i++) | 4445 | /* This does a hard reset of the controller using PCI power management |
4107 | pci_read_config_word(pdev, 2*i, &saved_config_space[i]); | 4446 | * states or using the doorbell register. */ |
4447 | static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) | ||
4448 | { | ||
4449 | u16 saved_config_space[32]; | ||
4450 | u64 cfg_offset; | ||
4451 | u32 cfg_base_addr; | ||
4452 | u64 cfg_base_addr_index; | ||
4453 | void __iomem *vaddr; | ||
4454 | unsigned long paddr; | ||
4455 | u32 misc_fw_support, active_transport; | ||
4456 | int rc, i; | ||
4457 | CfgTable_struct __iomem *cfgtable; | ||
4458 | bool use_doorbell; | ||
4459 | u32 board_id; | ||
4460 | |||
4461 | /* For controllers as old a the p600, this is very nearly | ||
4462 | * the same thing as | ||
4463 | * | ||
4464 | * pci_save_state(pci_dev); | ||
4465 | * pci_set_power_state(pci_dev, PCI_D3hot); | ||
4466 | * pci_set_power_state(pci_dev, PCI_D0); | ||
4467 | * pci_restore_state(pci_dev); | ||
4468 | * | ||
4469 | * but we can't use these nice canned kernel routines on | ||
4470 | * kexec, because they also check the MSI/MSI-X state in PCI | ||
4471 | * configuration space and do the wrong thing when it is | ||
4472 | * set/cleared. Also, the pci_save/restore_state functions | ||
4473 | * violate the ordering requirements for restoring the | ||
4474 | * configuration space from the CCISS document (see the | ||
4475 | * comment below). So we roll our own .... | ||
4476 | * | ||
4477 | * For controllers newer than the P600, the pci power state | ||
4478 | * method of resetting doesn't work so we have another way | ||
4479 | * using the doorbell register. | ||
4480 | */ | ||
4108 | 4481 | ||
4109 | pos = pci_find_capability(pdev, PCI_CAP_ID_PM); | 4482 | /* Exclude 640x boards. These are two pci devices in one slot |
4110 | if (pos == 0) { | 4483 | * which share a battery backed cache module. One controls the |
4111 | printk(KERN_ERR "cciss_reset_controller: PCI PM not supported\n"); | 4484 | * cache, the other accesses the cache through the one that controls |
4485 | * it. If we reset the one controlling the cache, the other will | ||
4486 | * likely not be happy. Just forbid resetting this conjoined mess. | ||
4487 | */ | ||
4488 | cciss_lookup_board_id(pdev, &board_id); | ||
4489 | if (board_id == 0x409C0E11 || board_id == 0x409D0E11) { | ||
4490 | dev_warn(&pdev->dev, "Cannot reset Smart Array 640x " | ||
4491 | "due to shared cache module."); | ||
4112 | return -ENODEV; | 4492 | return -ENODEV; |
4113 | } | 4493 | } |
4114 | 4494 | ||
4115 | /* Quoting from the Open CISS Specification: "The Power | 4495 | for (i = 0; i < 32; i++) |
4116 | * Management Control/Status Register (CSR) controls the power | 4496 | pci_read_config_word(pdev, 2*i, &saved_config_space[i]); |
4117 | * state of the device. The normal operating state is D0, | ||
4118 | * CSR=00h. The software off state is D3, CSR=03h. To reset | ||
4119 | * the controller, place the interface device in D3 then to | ||
4120 | * D0, this causes a secondary PCI reset which will reset the | ||
4121 | * controller." */ | ||
4122 | 4497 | ||
4123 | /* enter the D3hot power management state */ | 4498 | /* find the first memory BAR, so we can find the cfg table */ |
4124 | pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); | 4499 | rc = cciss_pci_find_memory_BAR(pdev, &paddr); |
4125 | pmcsr &= ~PCI_PM_CTRL_STATE_MASK; | 4500 | if (rc) |
4126 | pmcsr |= PCI_D3hot; | 4501 | return rc; |
4127 | pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); | 4502 | vaddr = remap_pci_mem(paddr, 0x250); |
4503 | if (!vaddr) | ||
4504 | return -ENOMEM; | ||
4128 | 4505 | ||
4129 | schedule_timeout_uninterruptible(HZ >> 1); | 4506 | /* find cfgtable in order to check if reset via doorbell is supported */ |
4507 | rc = cciss_find_cfg_addrs(pdev, vaddr, &cfg_base_addr, | ||
4508 | &cfg_base_addr_index, &cfg_offset); | ||
4509 | if (rc) | ||
4510 | goto unmap_vaddr; | ||
4511 | cfgtable = remap_pci_mem(pci_resource_start(pdev, | ||
4512 | cfg_base_addr_index) + cfg_offset, sizeof(*cfgtable)); | ||
4513 | if (!cfgtable) { | ||
4514 | rc = -ENOMEM; | ||
4515 | goto unmap_vaddr; | ||
4516 | } | ||
4130 | 4517 | ||
4131 | /* enter the D0 power management state */ | 4518 | /* If reset via doorbell register is supported, use that. */ |
4132 | pmcsr &= ~PCI_PM_CTRL_STATE_MASK; | 4519 | misc_fw_support = readl(&cfgtable->misc_fw_support); |
4133 | pmcsr |= PCI_D0; | 4520 | use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET; |
4134 | pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); | ||
4135 | 4521 | ||
4136 | schedule_timeout_uninterruptible(HZ >> 1); | 4522 | rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell); |
4523 | if (rc) | ||
4524 | goto unmap_cfgtable; | ||
4137 | 4525 | ||
4138 | /* Restore the PCI configuration space. The Open CISS | 4526 | /* Restore the PCI configuration space. The Open CISS |
4139 | * Specification says, "Restore the PCI Configuration | 4527 | * Specification says, "Restore the PCI Configuration |
4140 | * Registers, offsets 00h through 60h. It is important to | 4528 | * Registers, offsets 00h through 60h. It is important to |
4141 | * restore the command register, 16-bits at offset 04h, | 4529 | * restore the command register, 16-bits at offset 04h, |
4142 | * last. Do not restore the configuration status register, | 4530 | * last. Do not restore the configuration status register, |
4143 | * 16-bits at offset 06h." Note that the offset is 2*i. */ | 4531 | * 16-bits at offset 06h." Note that the offset is 2*i. |
4532 | */ | ||
4144 | for (i = 0; i < 32; i++) { | 4533 | for (i = 0; i < 32; i++) { |
4145 | if (i == 2 || i == 3) | 4534 | if (i == 2 || i == 3) |
4146 | continue; | 4535 | continue; |
@@ -4149,6 +4538,63 @@ static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev) | |||
4149 | wmb(); | 4538 | wmb(); |
4150 | pci_write_config_word(pdev, 4, saved_config_space[2]); | 4539 | pci_write_config_word(pdev, 4, saved_config_space[2]); |
4151 | 4540 | ||
4541 | /* Some devices (notably the HP Smart Array 5i Controller) | ||
4542 | need a little pause here */ | ||
4543 | msleep(CCISS_POST_RESET_PAUSE_MSECS); | ||
4544 | |||
4545 | /* Controller should be in simple mode at this point. If it's not, | ||
4546 | * It means we're on one of those controllers which doesn't support | ||
4547 | * the doorbell reset method and on which the PCI power management reset | ||
4548 | * method doesn't work (P800, for example.) | ||
4549 | * In those cases, don't try to proceed, as it generally doesn't work. | ||
4550 | */ | ||
4551 | active_transport = readl(&cfgtable->TransportActive); | ||
4552 | if (active_transport & PERFORMANT_MODE) { | ||
4553 | dev_warn(&pdev->dev, "Unable to successfully reset controller," | ||
4554 | " Ignoring controller.\n"); | ||
4555 | rc = -ENODEV; | ||
4556 | } | ||
4557 | |||
4558 | unmap_cfgtable: | ||
4559 | iounmap(cfgtable); | ||
4560 | |||
4561 | unmap_vaddr: | ||
4562 | iounmap(vaddr); | ||
4563 | return rc; | ||
4564 | } | ||
4565 | |||
4566 | static __devinit int cciss_init_reset_devices(struct pci_dev *pdev) | ||
4567 | { | ||
4568 | int rc, i; | ||
4569 | |||
4570 | if (!reset_devices) | ||
4571 | return 0; | ||
4572 | |||
4573 | /* Reset the controller with a PCI power-cycle or via doorbell */ | ||
4574 | rc = cciss_kdump_hard_reset_controller(pdev); | ||
4575 | |||
4576 | /* -ENOTSUPP here means we cannot reset the controller | ||
4577 | * but it's already (and still) up and running in | ||
4578 | * "performant mode". Or, it might be 640x, which can't reset | ||
4579 | * due to concerns about shared bbwc between 6402/6404 pair. | ||
4580 | */ | ||
4581 | if (rc == -ENOTSUPP) | ||
4582 | return 0; /* just try to do the kdump anyhow. */ | ||
4583 | if (rc) | ||
4584 | return -ENODEV; | ||
4585 | if (cciss_reset_msi(pdev)) | ||
4586 | return -ENODEV; | ||
4587 | |||
4588 | /* Now try to get the controller to respond to a no-op */ | ||
4589 | for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) { | ||
4590 | if (cciss_noop(pdev) == 0) | ||
4591 | break; | ||
4592 | else | ||
4593 | dev_warn(&pdev->dev, "no-op failed%s\n", | ||
4594 | (i < CCISS_POST_RESET_NOOP_RETRIES - 1 ? | ||
4595 | "; re-trying" : "")); | ||
4596 | msleep(CCISS_POST_RESET_NOOP_INTERVAL_MSECS); | ||
4597 | } | ||
4152 | return 0; | 4598 | return 0; |
4153 | } | 4599 | } |
4154 | 4600 | ||
@@ -4166,46 +4612,31 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
4166 | int rc; | 4612 | int rc; |
4167 | int dac, return_code; | 4613 | int dac, return_code; |
4168 | InquiryData_struct *inq_buff; | 4614 | InquiryData_struct *inq_buff; |
4615 | ctlr_info_t *h; | ||
4169 | 4616 | ||
4170 | if (reset_devices) { | 4617 | rc = cciss_init_reset_devices(pdev); |
4171 | /* Reset the controller with a PCI power-cycle */ | 4618 | if (rc) |
4172 | if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev)) | 4619 | return rc; |
4173 | return -ENODEV; | 4620 | i = alloc_cciss_hba(pdev); |
4174 | |||
4175 | /* Now try to get the controller to respond to a no-op. Some | ||
4176 | devices (notably the HP Smart Array 5i Controller) need | ||
4177 | up to 30 seconds to respond. */ | ||
4178 | for (i=0; i<30; i++) { | ||
4179 | if (cciss_noop(pdev) == 0) | ||
4180 | break; | ||
4181 | |||
4182 | schedule_timeout_uninterruptible(HZ); | ||
4183 | } | ||
4184 | if (i == 30) { | ||
4185 | printk(KERN_ERR "cciss: controller seems dead\n"); | ||
4186 | return -EBUSY; | ||
4187 | } | ||
4188 | } | ||
4189 | |||
4190 | i = alloc_cciss_hba(); | ||
4191 | if (i < 0) | 4621 | if (i < 0) |
4192 | return -1; | 4622 | return -1; |
4193 | 4623 | ||
4194 | hba[i]->busy_initializing = 1; | 4624 | h = hba[i]; |
4195 | INIT_HLIST_HEAD(&hba[i]->cmpQ); | 4625 | h->pdev = pdev; |
4196 | INIT_HLIST_HEAD(&hba[i]->reqQ); | 4626 | h->busy_initializing = 1; |
4197 | mutex_init(&hba[i]->busy_shutting_down); | 4627 | INIT_HLIST_HEAD(&h->cmpQ); |
4628 | INIT_HLIST_HEAD(&h->reqQ); | ||
4629 | mutex_init(&h->busy_shutting_down); | ||
4198 | 4630 | ||
4199 | if (cciss_pci_init(hba[i], pdev) != 0) | 4631 | if (cciss_pci_init(h) != 0) |
4200 | goto clean_no_release_regions; | 4632 | goto clean_no_release_regions; |
4201 | 4633 | ||
4202 | sprintf(hba[i]->devname, "cciss%d", i); | 4634 | sprintf(h->devname, "cciss%d", i); |
4203 | hba[i]->ctlr = i; | 4635 | h->ctlr = i; |
4204 | hba[i]->pdev = pdev; | ||
4205 | 4636 | ||
4206 | init_completion(&hba[i]->scan_wait); | 4637 | init_completion(&h->scan_wait); |
4207 | 4638 | ||
4208 | if (cciss_create_hba_sysfs_entry(hba[i])) | 4639 | if (cciss_create_hba_sysfs_entry(h)) |
4209 | goto clean0; | 4640 | goto clean0; |
4210 | 4641 | ||
4211 | /* configure PCI DMA stuff */ | 4642 | /* configure PCI DMA stuff */ |
@@ -4214,7 +4645,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
4214 | else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) | 4645 | else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) |
4215 | dac = 0; | 4646 | dac = 0; |
4216 | else { | 4647 | else { |
4217 | printk(KERN_ERR "cciss: no suitable DMA available\n"); | 4648 | dev_err(&h->pdev->dev, "no suitable DMA available\n"); |
4218 | goto clean1; | 4649 | goto clean1; |
4219 | } | 4650 | } |
4220 | 4651 | ||
@@ -4224,151 +4655,161 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
4224 | * 8 controller support. | 4655 | * 8 controller support. |
4225 | */ | 4656 | */ |
4226 | if (i < MAX_CTLR_ORIG) | 4657 | if (i < MAX_CTLR_ORIG) |
4227 | hba[i]->major = COMPAQ_CISS_MAJOR + i; | 4658 | h->major = COMPAQ_CISS_MAJOR + i; |
4228 | rc = register_blkdev(hba[i]->major, hba[i]->devname); | 4659 | rc = register_blkdev(h->major, h->devname); |
4229 | if (rc == -EBUSY || rc == -EINVAL) { | 4660 | if (rc == -EBUSY || rc == -EINVAL) { |
4230 | printk(KERN_ERR | 4661 | dev_err(&h->pdev->dev, |
4231 | "cciss: Unable to get major number %d for %s " | 4662 | "Unable to get major number %d for %s " |
4232 | "on hba %d\n", hba[i]->major, hba[i]->devname, i); | 4663 | "on hba %d\n", h->major, h->devname, i); |
4233 | goto clean1; | 4664 | goto clean1; |
4234 | } else { | 4665 | } else { |
4235 | if (i >= MAX_CTLR_ORIG) | 4666 | if (i >= MAX_CTLR_ORIG) |
4236 | hba[i]->major = rc; | 4667 | h->major = rc; |
4237 | } | 4668 | } |
4238 | 4669 | ||
4239 | /* make sure the board interrupts are off */ | 4670 | /* make sure the board interrupts are off */ |
4240 | hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); | 4671 | h->access.set_intr_mask(h, CCISS_INTR_OFF); |
4241 | if (request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr, | 4672 | if (h->msi_vector || h->msix_vector) { |
4242 | IRQF_DISABLED | IRQF_SHARED, hba[i]->devname, hba[i])) { | 4673 | if (request_irq(h->intr[PERF_MODE_INT], |
4243 | printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", | 4674 | do_cciss_msix_intr, |
4244 | hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname); | 4675 | IRQF_DISABLED, h->devname, h)) { |
4245 | goto clean2; | 4676 | dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n", |
4677 | h->intr[PERF_MODE_INT], h->devname); | ||
4678 | goto clean2; | ||
4679 | } | ||
4680 | } else { | ||
4681 | if (request_irq(h->intr[PERF_MODE_INT], do_cciss_intx, | ||
4682 | IRQF_DISABLED, h->devname, h)) { | ||
4683 | dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n", | ||
4684 | h->intr[PERF_MODE_INT], h->devname); | ||
4685 | goto clean2; | ||
4686 | } | ||
4246 | } | 4687 | } |
4247 | 4688 | ||
4248 | printk(KERN_INFO "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n", | 4689 | dev_info(&h->pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n", |
4249 | hba[i]->devname, pdev->device, pci_name(pdev), | 4690 | h->devname, pdev->device, pci_name(pdev), |
4250 | hba[i]->intr[SIMPLE_MODE_INT], dac ? "" : " not"); | 4691 | h->intr[PERF_MODE_INT], dac ? "" : " not"); |
4251 | 4692 | ||
4252 | hba[i]->cmd_pool_bits = | 4693 | h->cmd_pool_bits = |
4253 | kmalloc(DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG) | 4694 | kmalloc(DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG) |
4254 | * sizeof(unsigned long), GFP_KERNEL); | 4695 | * sizeof(unsigned long), GFP_KERNEL); |
4255 | hba[i]->cmd_pool = (CommandList_struct *) | 4696 | h->cmd_pool = (CommandList_struct *) |
4256 | pci_alloc_consistent(hba[i]->pdev, | 4697 | pci_alloc_consistent(h->pdev, |
4257 | hba[i]->nr_cmds * sizeof(CommandList_struct), | 4698 | h->nr_cmds * sizeof(CommandList_struct), |
4258 | &(hba[i]->cmd_pool_dhandle)); | 4699 | &(h->cmd_pool_dhandle)); |
4259 | hba[i]->errinfo_pool = (ErrorInfo_struct *) | 4700 | h->errinfo_pool = (ErrorInfo_struct *) |
4260 | pci_alloc_consistent(hba[i]->pdev, | 4701 | pci_alloc_consistent(h->pdev, |
4261 | hba[i]->nr_cmds * sizeof(ErrorInfo_struct), | 4702 | h->nr_cmds * sizeof(ErrorInfo_struct), |
4262 | &(hba[i]->errinfo_pool_dhandle)); | 4703 | &(h->errinfo_pool_dhandle)); |
4263 | if ((hba[i]->cmd_pool_bits == NULL) | 4704 | if ((h->cmd_pool_bits == NULL) |
4264 | || (hba[i]->cmd_pool == NULL) | 4705 | || (h->cmd_pool == NULL) |
4265 | || (hba[i]->errinfo_pool == NULL)) { | 4706 | || (h->errinfo_pool == NULL)) { |
4266 | printk(KERN_ERR "cciss: out of memory"); | 4707 | dev_err(&h->pdev->dev, "out of memory"); |
4267 | goto clean4; | 4708 | goto clean4; |
4268 | } | 4709 | } |
4269 | 4710 | ||
4270 | /* Need space for temp scatter list */ | 4711 | /* Need space for temp scatter list */ |
4271 | hba[i]->scatter_list = kmalloc(hba[i]->max_commands * | 4712 | h->scatter_list = kmalloc(h->max_commands * |
4272 | sizeof(struct scatterlist *), | 4713 | sizeof(struct scatterlist *), |
4273 | GFP_KERNEL); | 4714 | GFP_KERNEL); |
4274 | for (k = 0; k < hba[i]->nr_cmds; k++) { | 4715 | for (k = 0; k < h->nr_cmds; k++) { |
4275 | hba[i]->scatter_list[k] = kmalloc(sizeof(struct scatterlist) * | 4716 | h->scatter_list[k] = kmalloc(sizeof(struct scatterlist) * |
4276 | hba[i]->maxsgentries, | 4717 | h->maxsgentries, |
4277 | GFP_KERNEL); | 4718 | GFP_KERNEL); |
4278 | if (hba[i]->scatter_list[k] == NULL) { | 4719 | if (h->scatter_list[k] == NULL) { |
4279 | printk(KERN_ERR "cciss%d: could not allocate " | 4720 | dev_err(&h->pdev->dev, |
4280 | "s/g lists\n", i); | 4721 | "could not allocate s/g lists\n"); |
4281 | goto clean4; | 4722 | goto clean4; |
4282 | } | 4723 | } |
4283 | } | 4724 | } |
4284 | hba[i]->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[i], | 4725 | h->cmd_sg_list = cciss_allocate_sg_chain_blocks(h, |
4285 | hba[i]->chainsize, hba[i]->nr_cmds); | 4726 | h->chainsize, h->nr_cmds); |
4286 | if (!hba[i]->cmd_sg_list && hba[i]->chainsize > 0) | 4727 | if (!h->cmd_sg_list && h->chainsize > 0) |
4287 | goto clean4; | 4728 | goto clean4; |
4288 | 4729 | ||
4289 | spin_lock_init(&hba[i]->lock); | 4730 | spin_lock_init(&h->lock); |
4290 | 4731 | ||
4291 | /* Initialize the pdev driver private data. | 4732 | /* Initialize the pdev driver private data. |
4292 | have it point to hba[i]. */ | 4733 | have it point to h. */ |
4293 | pci_set_drvdata(pdev, hba[i]); | 4734 | pci_set_drvdata(pdev, h); |
4294 | /* command and error info recs zeroed out before | 4735 | /* command and error info recs zeroed out before |
4295 | they are used */ | 4736 | they are used */ |
4296 | memset(hba[i]->cmd_pool_bits, 0, | 4737 | memset(h->cmd_pool_bits, 0, |
4297 | DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG) | 4738 | DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG) |
4298 | * sizeof(unsigned long)); | 4739 | * sizeof(unsigned long)); |
4299 | 4740 | ||
4300 | hba[i]->num_luns = 0; | 4741 | h->num_luns = 0; |
4301 | hba[i]->highest_lun = -1; | 4742 | h->highest_lun = -1; |
4302 | for (j = 0; j < CISS_MAX_LUN; j++) { | 4743 | for (j = 0; j < CISS_MAX_LUN; j++) { |
4303 | hba[i]->drv[j] = NULL; | 4744 | h->drv[j] = NULL; |
4304 | hba[i]->gendisk[j] = NULL; | 4745 | h->gendisk[j] = NULL; |
4305 | } | 4746 | } |
4306 | 4747 | ||
4307 | cciss_scsi_setup(i); | 4748 | cciss_scsi_setup(h); |
4308 | 4749 | ||
4309 | /* Turn the interrupts on so we can service requests */ | 4750 | /* Turn the interrupts on so we can service requests */ |
4310 | hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); | 4751 | h->access.set_intr_mask(h, CCISS_INTR_ON); |
4311 | 4752 | ||
4312 | /* Get the firmware version */ | 4753 | /* Get the firmware version */ |
4313 | inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL); | 4754 | inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL); |
4314 | if (inq_buff == NULL) { | 4755 | if (inq_buff == NULL) { |
4315 | printk(KERN_ERR "cciss: out of memory\n"); | 4756 | dev_err(&h->pdev->dev, "out of memory\n"); |
4316 | goto clean4; | 4757 | goto clean4; |
4317 | } | 4758 | } |
4318 | 4759 | ||
4319 | return_code = sendcmd_withirq(CISS_INQUIRY, i, inq_buff, | 4760 | return_code = sendcmd_withirq(h, CISS_INQUIRY, inq_buff, |
4320 | sizeof(InquiryData_struct), 0, CTLR_LUNID, TYPE_CMD); | 4761 | sizeof(InquiryData_struct), 0, CTLR_LUNID, TYPE_CMD); |
4321 | if (return_code == IO_OK) { | 4762 | if (return_code == IO_OK) { |
4322 | hba[i]->firm_ver[0] = inq_buff->data_byte[32]; | 4763 | h->firm_ver[0] = inq_buff->data_byte[32]; |
4323 | hba[i]->firm_ver[1] = inq_buff->data_byte[33]; | 4764 | h->firm_ver[1] = inq_buff->data_byte[33]; |
4324 | hba[i]->firm_ver[2] = inq_buff->data_byte[34]; | 4765 | h->firm_ver[2] = inq_buff->data_byte[34]; |
4325 | hba[i]->firm_ver[3] = inq_buff->data_byte[35]; | 4766 | h->firm_ver[3] = inq_buff->data_byte[35]; |
4326 | } else { /* send command failed */ | 4767 | } else { /* send command failed */ |
4327 | printk(KERN_WARNING "cciss: unable to determine firmware" | 4768 | dev_warn(&h->pdev->dev, "unable to determine firmware" |
4328 | " version of controller\n"); | 4769 | " version of controller\n"); |
4329 | } | 4770 | } |
4330 | kfree(inq_buff); | 4771 | kfree(inq_buff); |
4331 | 4772 | ||
4332 | cciss_procinit(i); | 4773 | cciss_procinit(h); |
4333 | 4774 | ||
4334 | hba[i]->cciss_max_sectors = 8192; | 4775 | h->cciss_max_sectors = 8192; |
4335 | 4776 | ||
4336 | rebuild_lun_table(hba[i], 1, 0); | 4777 | rebuild_lun_table(h, 1, 0); |
4337 | hba[i]->busy_initializing = 0; | 4778 | h->busy_initializing = 0; |
4338 | return 1; | 4779 | return 1; |
4339 | 4780 | ||
4340 | clean4: | 4781 | clean4: |
4341 | kfree(hba[i]->cmd_pool_bits); | 4782 | kfree(h->cmd_pool_bits); |
4342 | /* Free up sg elements */ | 4783 | /* Free up sg elements */ |
4343 | for (k = 0; k < hba[i]->nr_cmds; k++) | 4784 | for (k = 0; k < h->nr_cmds; k++) |
4344 | kfree(hba[i]->scatter_list[k]); | 4785 | kfree(h->scatter_list[k]); |
4345 | kfree(hba[i]->scatter_list); | 4786 | kfree(h->scatter_list); |
4346 | cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds); | 4787 | cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds); |
4347 | if (hba[i]->cmd_pool) | 4788 | if (h->cmd_pool) |
4348 | pci_free_consistent(hba[i]->pdev, | 4789 | pci_free_consistent(h->pdev, |
4349 | hba[i]->nr_cmds * sizeof(CommandList_struct), | 4790 | h->nr_cmds * sizeof(CommandList_struct), |
4350 | hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); | 4791 | h->cmd_pool, h->cmd_pool_dhandle); |
4351 | if (hba[i]->errinfo_pool) | 4792 | if (h->errinfo_pool) |
4352 | pci_free_consistent(hba[i]->pdev, | 4793 | pci_free_consistent(h->pdev, |
4353 | hba[i]->nr_cmds * sizeof(ErrorInfo_struct), | 4794 | h->nr_cmds * sizeof(ErrorInfo_struct), |
4354 | hba[i]->errinfo_pool, | 4795 | h->errinfo_pool, |
4355 | hba[i]->errinfo_pool_dhandle); | 4796 | h->errinfo_pool_dhandle); |
4356 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); | 4797 | free_irq(h->intr[PERF_MODE_INT], h); |
4357 | clean2: | 4798 | clean2: |
4358 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 4799 | unregister_blkdev(h->major, h->devname); |
4359 | clean1: | 4800 | clean1: |
4360 | cciss_destroy_hba_sysfs_entry(hba[i]); | 4801 | cciss_destroy_hba_sysfs_entry(h); |
4361 | clean0: | 4802 | clean0: |
4362 | pci_release_regions(pdev); | 4803 | pci_release_regions(pdev); |
4363 | clean_no_release_regions: | 4804 | clean_no_release_regions: |
4364 | hba[i]->busy_initializing = 0; | 4805 | h->busy_initializing = 0; |
4365 | 4806 | ||
4366 | /* | 4807 | /* |
4367 | * Deliberately omit pci_disable_device(): it does something nasty to | 4808 | * Deliberately omit pci_disable_device(): it does something nasty to |
4368 | * Smart Array controllers that pci_enable_device does not undo | 4809 | * Smart Array controllers that pci_enable_device does not undo |
4369 | */ | 4810 | */ |
4370 | pci_set_drvdata(pdev, NULL); | 4811 | pci_set_drvdata(pdev, NULL); |
4371 | free_hba(i); | 4812 | free_hba(h); |
4372 | return -1; | 4813 | return -1; |
4373 | } | 4814 | } |
4374 | 4815 | ||
@@ -4381,55 +4822,51 @@ static void cciss_shutdown(struct pci_dev *pdev) | |||
4381 | h = pci_get_drvdata(pdev); | 4822 | h = pci_get_drvdata(pdev); |
4382 | flush_buf = kzalloc(4, GFP_KERNEL); | 4823 | flush_buf = kzalloc(4, GFP_KERNEL); |
4383 | if (!flush_buf) { | 4824 | if (!flush_buf) { |
4384 | printk(KERN_WARNING | 4825 | dev_warn(&h->pdev->dev, "cache not flushed, out of memory.\n"); |
4385 | "cciss:%d cache not flushed, out of memory.\n", | ||
4386 | h->ctlr); | ||
4387 | return; | 4826 | return; |
4388 | } | 4827 | } |
4389 | /* write all data in the battery backed cache to disk */ | 4828 | /* write all data in the battery backed cache to disk */ |
4390 | memset(flush_buf, 0, 4); | 4829 | memset(flush_buf, 0, 4); |
4391 | return_code = sendcmd_withirq(CCISS_CACHE_FLUSH, h->ctlr, flush_buf, | 4830 | return_code = sendcmd_withirq(h, CCISS_CACHE_FLUSH, flush_buf, |
4392 | 4, 0, CTLR_LUNID, TYPE_CMD); | 4831 | 4, 0, CTLR_LUNID, TYPE_CMD); |
4393 | kfree(flush_buf); | 4832 | kfree(flush_buf); |
4394 | if (return_code != IO_OK) | 4833 | if (return_code != IO_OK) |
4395 | printk(KERN_WARNING "cciss%d: Error flushing cache\n", | 4834 | dev_warn(&h->pdev->dev, "Error flushing cache\n"); |
4396 | h->ctlr); | ||
4397 | h->access.set_intr_mask(h, CCISS_INTR_OFF); | 4835 | h->access.set_intr_mask(h, CCISS_INTR_OFF); |
4398 | free_irq(h->intr[2], h); | 4836 | free_irq(h->intr[PERF_MODE_INT], h); |
4399 | } | 4837 | } |
4400 | 4838 | ||
4401 | static void __devexit cciss_remove_one(struct pci_dev *pdev) | 4839 | static void __devexit cciss_remove_one(struct pci_dev *pdev) |
4402 | { | 4840 | { |
4403 | ctlr_info_t *tmp_ptr; | 4841 | ctlr_info_t *h; |
4404 | int i, j; | 4842 | int i, j; |
4405 | 4843 | ||
4406 | if (pci_get_drvdata(pdev) == NULL) { | 4844 | if (pci_get_drvdata(pdev) == NULL) { |
4407 | printk(KERN_ERR "cciss: Unable to remove device \n"); | 4845 | dev_err(&pdev->dev, "Unable to remove device\n"); |
4408 | return; | 4846 | return; |
4409 | } | 4847 | } |
4410 | 4848 | ||
4411 | tmp_ptr = pci_get_drvdata(pdev); | 4849 | h = pci_get_drvdata(pdev); |
4412 | i = tmp_ptr->ctlr; | 4850 | i = h->ctlr; |
4413 | if (hba[i] == NULL) { | 4851 | if (hba[i] == NULL) { |
4414 | printk(KERN_ERR "cciss: device appears to " | 4852 | dev_err(&pdev->dev, "device appears to already be removed\n"); |
4415 | "already be removed \n"); | ||
4416 | return; | 4853 | return; |
4417 | } | 4854 | } |
4418 | 4855 | ||
4419 | mutex_lock(&hba[i]->busy_shutting_down); | 4856 | mutex_lock(&h->busy_shutting_down); |
4420 | 4857 | ||
4421 | remove_from_scan_list(hba[i]); | 4858 | remove_from_scan_list(h); |
4422 | remove_proc_entry(hba[i]->devname, proc_cciss); | 4859 | remove_proc_entry(h->devname, proc_cciss); |
4423 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 4860 | unregister_blkdev(h->major, h->devname); |
4424 | 4861 | ||
4425 | /* remove it from the disk list */ | 4862 | /* remove it from the disk list */ |
4426 | for (j = 0; j < CISS_MAX_LUN; j++) { | 4863 | for (j = 0; j < CISS_MAX_LUN; j++) { |
4427 | struct gendisk *disk = hba[i]->gendisk[j]; | 4864 | struct gendisk *disk = h->gendisk[j]; |
4428 | if (disk) { | 4865 | if (disk) { |
4429 | struct request_queue *q = disk->queue; | 4866 | struct request_queue *q = disk->queue; |
4430 | 4867 | ||
4431 | if (disk->flags & GENHD_FL_UP) { | 4868 | if (disk->flags & GENHD_FL_UP) { |
4432 | cciss_destroy_ld_sysfs_entry(hba[i], j, 1); | 4869 | cciss_destroy_ld_sysfs_entry(h, j, 1); |
4433 | del_gendisk(disk); | 4870 | del_gendisk(disk); |
4434 | } | 4871 | } |
4435 | if (q) | 4872 | if (q) |
@@ -4438,39 +4875,41 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
4438 | } | 4875 | } |
4439 | 4876 | ||
4440 | #ifdef CONFIG_CISS_SCSI_TAPE | 4877 | #ifdef CONFIG_CISS_SCSI_TAPE |
4441 | cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ | 4878 | cciss_unregister_scsi(h); /* unhook from SCSI subsystem */ |
4442 | #endif | 4879 | #endif |
4443 | 4880 | ||
4444 | cciss_shutdown(pdev); | 4881 | cciss_shutdown(pdev); |
4445 | 4882 | ||
4446 | #ifdef CONFIG_PCI_MSI | 4883 | #ifdef CONFIG_PCI_MSI |
4447 | if (hba[i]->msix_vector) | 4884 | if (h->msix_vector) |
4448 | pci_disable_msix(hba[i]->pdev); | 4885 | pci_disable_msix(h->pdev); |
4449 | else if (hba[i]->msi_vector) | 4886 | else if (h->msi_vector) |
4450 | pci_disable_msi(hba[i]->pdev); | 4887 | pci_disable_msi(h->pdev); |
4451 | #endif /* CONFIG_PCI_MSI */ | 4888 | #endif /* CONFIG_PCI_MSI */ |
4452 | 4889 | ||
4453 | iounmap(hba[i]->vaddr); | 4890 | iounmap(h->transtable); |
4891 | iounmap(h->cfgtable); | ||
4892 | iounmap(h->vaddr); | ||
4454 | 4893 | ||
4455 | pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(CommandList_struct), | 4894 | pci_free_consistent(h->pdev, h->nr_cmds * sizeof(CommandList_struct), |
4456 | hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); | 4895 | h->cmd_pool, h->cmd_pool_dhandle); |
4457 | pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(ErrorInfo_struct), | 4896 | pci_free_consistent(h->pdev, h->nr_cmds * sizeof(ErrorInfo_struct), |
4458 | hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle); | 4897 | h->errinfo_pool, h->errinfo_pool_dhandle); |
4459 | kfree(hba[i]->cmd_pool_bits); | 4898 | kfree(h->cmd_pool_bits); |
4460 | /* Free up sg elements */ | 4899 | /* Free up sg elements */ |
4461 | for (j = 0; j < hba[i]->nr_cmds; j++) | 4900 | for (j = 0; j < h->nr_cmds; j++) |
4462 | kfree(hba[i]->scatter_list[j]); | 4901 | kfree(h->scatter_list[j]); |
4463 | kfree(hba[i]->scatter_list); | 4902 | kfree(h->scatter_list); |
4464 | cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds); | 4903 | cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds); |
4465 | /* | 4904 | /* |
4466 | * Deliberately omit pci_disable_device(): it does something nasty to | 4905 | * Deliberately omit pci_disable_device(): it does something nasty to |
4467 | * Smart Array controllers that pci_enable_device does not undo | 4906 | * Smart Array controllers that pci_enable_device does not undo |
4468 | */ | 4907 | */ |
4469 | pci_release_regions(pdev); | 4908 | pci_release_regions(pdev); |
4470 | pci_set_drvdata(pdev, NULL); | 4909 | pci_set_drvdata(pdev, NULL); |
4471 | cciss_destroy_hba_sysfs_entry(hba[i]); | 4910 | cciss_destroy_hba_sysfs_entry(h); |
4472 | mutex_unlock(&hba[i]->busy_shutting_down); | 4911 | mutex_unlock(&h->busy_shutting_down); |
4473 | free_hba(i); | 4912 | free_hba(h); |
4474 | } | 4913 | } |
4475 | 4914 | ||
4476 | static struct pci_driver cciss_pci_driver = { | 4915 | static struct pci_driver cciss_pci_driver = { |
@@ -4495,7 +4934,6 @@ static int __init cciss_init(void) | |||
4495 | * array of them, the size must be a multiple of 8 bytes. | 4934 | * array of them, the size must be a multiple of 8 bytes. |
4496 | */ | 4935 | */ |
4497 | BUILD_BUG_ON(sizeof(CommandList_struct) % COMMANDLIST_ALIGNMENT); | 4936 | BUILD_BUG_ON(sizeof(CommandList_struct) % COMMANDLIST_ALIGNMENT); |
4498 | |||
4499 | printk(KERN_INFO DRIVER_NAME "\n"); | 4937 | printk(KERN_INFO DRIVER_NAME "\n"); |
4500 | 4938 | ||
4501 | err = bus_register(&cciss_bus_type); | 4939 | err = bus_register(&cciss_bus_type); |
@@ -4532,8 +4970,8 @@ static void __exit cciss_cleanup(void) | |||
4532 | /* double check that all controller entrys have been removed */ | 4970 | /* double check that all controller entrys have been removed */ |
4533 | for (i = 0; i < MAX_CTLR; i++) { | 4971 | for (i = 0; i < MAX_CTLR; i++) { |
4534 | if (hba[i] != NULL) { | 4972 | if (hba[i] != NULL) { |
4535 | printk(KERN_WARNING "cciss: had to remove" | 4973 | dev_warn(&hba[i]->pdev->dev, |
4536 | " controller %d\n", i); | 4974 | "had to remove controller\n"); |
4537 | cciss_remove_one(hba[i]->pdev); | 4975 | cciss_remove_one(hba[i]->pdev); |
4538 | } | 4976 | } |
4539 | } | 4977 | } |
@@ -4542,46 +4980,5 @@ static void __exit cciss_cleanup(void) | |||
4542 | bus_unregister(&cciss_bus_type); | 4980 | bus_unregister(&cciss_bus_type); |
4543 | } | 4981 | } |
4544 | 4982 | ||
4545 | static void fail_all_cmds(unsigned long ctlr) | ||
4546 | { | ||
4547 | /* If we get here, the board is apparently dead. */ | ||
4548 | ctlr_info_t *h = hba[ctlr]; | ||
4549 | CommandList_struct *c; | ||
4550 | unsigned long flags; | ||
4551 | |||
4552 | printk(KERN_WARNING "cciss%d: controller not responding.\n", h->ctlr); | ||
4553 | h->alive = 0; /* the controller apparently died... */ | ||
4554 | |||
4555 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | ||
4556 | |||
4557 | pci_disable_device(h->pdev); /* Make sure it is really dead. */ | ||
4558 | |||
4559 | /* move everything off the request queue onto the completed queue */ | ||
4560 | while (!hlist_empty(&h->reqQ)) { | ||
4561 | c = hlist_entry(h->reqQ.first, CommandList_struct, list); | ||
4562 | removeQ(c); | ||
4563 | h->Qdepth--; | ||
4564 | addQ(&h->cmpQ, c); | ||
4565 | } | ||
4566 | |||
4567 | /* Now, fail everything on the completed queue with a HW error */ | ||
4568 | while (!hlist_empty(&h->cmpQ)) { | ||
4569 | c = hlist_entry(h->cmpQ.first, CommandList_struct, list); | ||
4570 | removeQ(c); | ||
4571 | if (c->cmd_type != CMD_MSG_STALE) | ||
4572 | c->err_info->CommandStatus = CMD_HARDWARE_ERR; | ||
4573 | if (c->cmd_type == CMD_RWREQ) { | ||
4574 | complete_command(h, c, 0); | ||
4575 | } else if (c->cmd_type == CMD_IOCTL_PEND) | ||
4576 | complete(c->waiting); | ||
4577 | #ifdef CONFIG_CISS_SCSI_TAPE | ||
4578 | else if (c->cmd_type == CMD_SCSI) | ||
4579 | complete_scsi_command(c, 0, 0); | ||
4580 | #endif | ||
4581 | } | ||
4582 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | ||
4583 | return; | ||
4584 | } | ||
4585 | |||
4586 | module_init(cciss_init); | 4983 | module_init(cciss_init); |
4587 | module_exit(cciss_cleanup); | 4984 | module_exit(cciss_cleanup); |
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index c5d411174db0..ae340ffc8f81 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -25,7 +25,7 @@ struct access_method { | |||
25 | void (*submit_command)(ctlr_info_t *h, CommandList_struct *c); | 25 | void (*submit_command)(ctlr_info_t *h, CommandList_struct *c); |
26 | void (*set_intr_mask)(ctlr_info_t *h, unsigned long val); | 26 | void (*set_intr_mask)(ctlr_info_t *h, unsigned long val); |
27 | unsigned long (*fifo_full)(ctlr_info_t *h); | 27 | unsigned long (*fifo_full)(ctlr_info_t *h); |
28 | unsigned long (*intr_pending)(ctlr_info_t *h); | 28 | bool (*intr_pending)(ctlr_info_t *h); |
29 | unsigned long (*command_completed)(ctlr_info_t *h); | 29 | unsigned long (*command_completed)(ctlr_info_t *h); |
30 | }; | 30 | }; |
31 | typedef struct _drive_info_struct | 31 | typedef struct _drive_info_struct |
@@ -85,8 +85,8 @@ struct ctlr_info | |||
85 | int max_cmd_sgentries; | 85 | int max_cmd_sgentries; |
86 | SGDescriptor_struct **cmd_sg_list; | 86 | SGDescriptor_struct **cmd_sg_list; |
87 | 87 | ||
88 | # define DOORBELL_INT 0 | 88 | # define PERF_MODE_INT 0 |
89 | # define PERF_MODE_INT 1 | 89 | # define DOORBELL_INT 1 |
90 | # define SIMPLE_MODE_INT 2 | 90 | # define SIMPLE_MODE_INT 2 |
91 | # define MEMQ_MODE_INT 3 | 91 | # define MEMQ_MODE_INT 3 |
92 | unsigned int intr[4]; | 92 | unsigned int intr[4]; |
@@ -137,10 +137,27 @@ struct ctlr_info | |||
137 | struct list_head scan_list; | 137 | struct list_head scan_list; |
138 | struct completion scan_wait; | 138 | struct completion scan_wait; |
139 | struct device dev; | 139 | struct device dev; |
140 | /* | ||
141 | * Performant mode tables. | ||
142 | */ | ||
143 | u32 trans_support; | ||
144 | u32 trans_offset; | ||
145 | struct TransTable_struct *transtable; | ||
146 | unsigned long transMethod; | ||
147 | |||
148 | /* | ||
149 | * Performant mode completion buffer | ||
150 | */ | ||
151 | u64 *reply_pool; | ||
152 | dma_addr_t reply_pool_dhandle; | ||
153 | u64 *reply_pool_head; | ||
154 | size_t reply_pool_size; | ||
155 | unsigned char reply_pool_wraparound; | ||
156 | u32 *blockFetchTable; | ||
140 | }; | 157 | }; |
141 | 158 | ||
142 | /* Defining the diffent access_menthods */ | 159 | /* Defining the diffent access_methods |
143 | /* | 160 | * |
144 | * Memory mapped FIFO interface (SMART 53xx cards) | 161 | * Memory mapped FIFO interface (SMART 53xx cards) |
145 | */ | 162 | */ |
146 | #define SA5_DOORBELL 0x20 | 163 | #define SA5_DOORBELL 0x20 |
@@ -159,19 +176,47 @@ struct ctlr_info | |||
159 | #define SA5B_INTR_PENDING 0x04 | 176 | #define SA5B_INTR_PENDING 0x04 |
160 | #define FIFO_EMPTY 0xffffffff | 177 | #define FIFO_EMPTY 0xffffffff |
161 | #define CCISS_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */ | 178 | #define CCISS_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */ |
179 | /* Perf. mode flags */ | ||
180 | #define SA5_PERF_INTR_PENDING 0x04 | ||
181 | #define SA5_PERF_INTR_OFF 0x05 | ||
182 | #define SA5_OUTDB_STATUS_PERF_BIT 0x01 | ||
183 | #define SA5_OUTDB_CLEAR_PERF_BIT 0x01 | ||
184 | #define SA5_OUTDB_CLEAR 0xA0 | ||
185 | #define SA5_OUTDB_CLEAR_PERF_BIT 0x01 | ||
186 | #define SA5_OUTDB_STATUS 0x9C | ||
187 | |||
162 | 188 | ||
163 | #define CISS_ERROR_BIT 0x02 | 189 | #define CISS_ERROR_BIT 0x02 |
164 | 190 | ||
165 | #define CCISS_INTR_ON 1 | 191 | #define CCISS_INTR_ON 1 |
166 | #define CCISS_INTR_OFF 0 | 192 | #define CCISS_INTR_OFF 0 |
193 | |||
194 | |||
195 | /* CCISS_BOARD_READY_WAIT_SECS is how long to wait for a board | ||
196 | * to become ready, in seconds, before giving up on it. | ||
197 | * CCISS_BOARD_READY_POLL_INTERVAL_MSECS * is how long to wait | ||
198 | * between polling the board to see if it is ready, in | ||
199 | * milliseconds. CCISS_BOARD_READY_ITERATIONS is derived | ||
200 | * the above. | ||
201 | */ | ||
202 | #define CCISS_BOARD_READY_WAIT_SECS (120) | ||
203 | #define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100) | ||
204 | #define CCISS_BOARD_READY_ITERATIONS \ | ||
205 | ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ | ||
206 | CCISS_BOARD_READY_POLL_INTERVAL_MSECS) | ||
207 | #define CCISS_POST_RESET_PAUSE_MSECS (3000) | ||
208 | #define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000) | ||
209 | #define CCISS_POST_RESET_NOOP_RETRIES (12) | ||
210 | |||
167 | /* | 211 | /* |
168 | Send the command to the hardware | 212 | Send the command to the hardware |
169 | */ | 213 | */ |
170 | static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) | 214 | static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) |
171 | { | 215 | { |
172 | #ifdef CCISS_DEBUG | 216 | #ifdef CCISS_DEBUG |
173 | printk("Sending %x - down to controller\n", c->busaddr ); | 217 | printk(KERN_WARNING "cciss%d: Sending %08x - down to controller\n", |
174 | #endif /* CCISS_DEBUG */ | 218 | h->ctlr, c->busaddr); |
219 | #endif /* CCISS_DEBUG */ | ||
175 | writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); | 220 | writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); |
176 | h->commands_outstanding++; | 221 | h->commands_outstanding++; |
177 | if ( h->commands_outstanding > h->max_outstanding) | 222 | if ( h->commands_outstanding > h->max_outstanding) |
@@ -214,6 +259,20 @@ static void SA5B_intr_mask(ctlr_info_t *h, unsigned long val) | |||
214 | h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); | 259 | h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); |
215 | } | 260 | } |
216 | } | 261 | } |
262 | |||
263 | /* Performant mode intr_mask */ | ||
264 | static void SA5_performant_intr_mask(ctlr_info_t *h, unsigned long val) | ||
265 | { | ||
266 | if (val) { /* turn on interrupts */ | ||
267 | h->interrupts_enabled = 1; | ||
268 | writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); | ||
269 | } else { | ||
270 | h->interrupts_enabled = 0; | ||
271 | writel(SA5_PERF_INTR_OFF, | ||
272 | h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); | ||
273 | } | ||
274 | } | ||
275 | |||
217 | /* | 276 | /* |
218 | * Returns true if fifo is full. | 277 | * Returns true if fifo is full. |
219 | * | 278 | * |
@@ -250,10 +309,44 @@ static unsigned long SA5_completed(ctlr_info_t *h) | |||
250 | return ( register_value); | 309 | return ( register_value); |
251 | 310 | ||
252 | } | 311 | } |
312 | |||
313 | /* Performant mode command completed */ | ||
314 | static unsigned long SA5_performant_completed(ctlr_info_t *h) | ||
315 | { | ||
316 | unsigned long register_value = FIFO_EMPTY; | ||
317 | |||
318 | /* flush the controller write of the reply queue by reading | ||
319 | * outbound doorbell status register. | ||
320 | */ | ||
321 | register_value = readl(h->vaddr + SA5_OUTDB_STATUS); | ||
322 | /* msi auto clears the interrupt pending bit. */ | ||
323 | if (!(h->msi_vector || h->msix_vector)) { | ||
324 | writel(SA5_OUTDB_CLEAR_PERF_BIT, h->vaddr + SA5_OUTDB_CLEAR); | ||
325 | /* Do a read in order to flush the write to the controller | ||
326 | * (as per spec.) | ||
327 | */ | ||
328 | register_value = readl(h->vaddr + SA5_OUTDB_STATUS); | ||
329 | } | ||
330 | |||
331 | if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { | ||
332 | register_value = *(h->reply_pool_head); | ||
333 | (h->reply_pool_head)++; | ||
334 | h->commands_outstanding--; | ||
335 | } else { | ||
336 | register_value = FIFO_EMPTY; | ||
337 | } | ||
338 | /* Check for wraparound */ | ||
339 | if (h->reply_pool_head == (h->reply_pool + h->max_commands)) { | ||
340 | h->reply_pool_head = h->reply_pool; | ||
341 | h->reply_pool_wraparound ^= 1; | ||
342 | } | ||
343 | |||
344 | return register_value; | ||
345 | } | ||
253 | /* | 346 | /* |
254 | * Returns true if an interrupt is pending.. | 347 | * Returns true if an interrupt is pending.. |
255 | */ | 348 | */ |
256 | static unsigned long SA5_intr_pending(ctlr_info_t *h) | 349 | static bool SA5_intr_pending(ctlr_info_t *h) |
257 | { | 350 | { |
258 | unsigned long register_value = | 351 | unsigned long register_value = |
259 | readl(h->vaddr + SA5_INTR_STATUS); | 352 | readl(h->vaddr + SA5_INTR_STATUS); |
@@ -268,7 +361,7 @@ static unsigned long SA5_intr_pending(ctlr_info_t *h) | |||
268 | /* | 361 | /* |
269 | * Returns true if an interrupt is pending.. | 362 | * Returns true if an interrupt is pending.. |
270 | */ | 363 | */ |
271 | static unsigned long SA5B_intr_pending(ctlr_info_t *h) | 364 | static bool SA5B_intr_pending(ctlr_info_t *h) |
272 | { | 365 | { |
273 | unsigned long register_value = | 366 | unsigned long register_value = |
274 | readl(h->vaddr + SA5_INTR_STATUS); | 367 | readl(h->vaddr + SA5_INTR_STATUS); |
@@ -280,6 +373,20 @@ static unsigned long SA5B_intr_pending(ctlr_info_t *h) | |||
280 | return 0 ; | 373 | return 0 ; |
281 | } | 374 | } |
282 | 375 | ||
376 | static bool SA5_performant_intr_pending(ctlr_info_t *h) | ||
377 | { | ||
378 | unsigned long register_value = readl(h->vaddr + SA5_INTR_STATUS); | ||
379 | |||
380 | if (!register_value) | ||
381 | return false; | ||
382 | |||
383 | if (h->msi_vector || h->msix_vector) | ||
384 | return true; | ||
385 | |||
386 | /* Read outbound doorbell to flush */ | ||
387 | register_value = readl(h->vaddr + SA5_OUTDB_STATUS); | ||
388 | return register_value & SA5_OUTDB_STATUS_PERF_BIT; | ||
389 | } | ||
283 | 390 | ||
284 | static struct access_method SA5_access = { | 391 | static struct access_method SA5_access = { |
285 | SA5_submit_command, | 392 | SA5_submit_command, |
@@ -297,6 +404,14 @@ static struct access_method SA5B_access = { | |||
297 | SA5_completed, | 404 | SA5_completed, |
298 | }; | 405 | }; |
299 | 406 | ||
407 | static struct access_method SA5_performant_access = { | ||
408 | SA5_submit_command, | ||
409 | SA5_performant_intr_mask, | ||
410 | SA5_fifo_full, | ||
411 | SA5_performant_intr_pending, | ||
412 | SA5_performant_completed, | ||
413 | }; | ||
414 | |||
300 | struct board_type { | 415 | struct board_type { |
301 | __u32 board_id; | 416 | __u32 board_id; |
302 | char *product_name; | 417 | char *product_name; |
@@ -304,6 +419,4 @@ struct board_type { | |||
304 | int nr_cmds; /* Max cmds this kind of ctlr can handle. */ | 419 | int nr_cmds; /* Max cmds this kind of ctlr can handle. */ |
305 | }; | 420 | }; |
306 | 421 | ||
307 | #define CCISS_LOCK(i) (&hba[i]->lock) | ||
308 | |||
309 | #endif /* CCISS_H */ | 422 | #endif /* CCISS_H */ |
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index e624ff959cb6..eb060f1b00b6 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h | |||
@@ -52,8 +52,10 @@ | |||
52 | /* Configuration Table */ | 52 | /* Configuration Table */ |
53 | #define CFGTBL_ChangeReq 0x00000001l | 53 | #define CFGTBL_ChangeReq 0x00000001l |
54 | #define CFGTBL_AccCmds 0x00000001l | 54 | #define CFGTBL_AccCmds 0x00000001l |
55 | #define DOORBELL_CTLR_RESET 0x00000004l | ||
55 | 56 | ||
56 | #define CFGTBL_Trans_Simple 0x00000002l | 57 | #define CFGTBL_Trans_Simple 0x00000002l |
58 | #define CFGTBL_Trans_Performant 0x00000004l | ||
57 | 59 | ||
58 | #define CFGTBL_BusType_Ultra2 0x00000001l | 60 | #define CFGTBL_BusType_Ultra2 0x00000001l |
59 | #define CFGTBL_BusType_Ultra3 0x00000002l | 61 | #define CFGTBL_BusType_Ultra3 0x00000002l |
@@ -173,12 +175,15 @@ typedef struct _SGDescriptor_struct { | |||
173 | * PAD_64 can be adjusted independently as needed for 32-bit | 175 | * PAD_64 can be adjusted independently as needed for 32-bit |
174 | * and 64-bits systems. | 176 | * and 64-bits systems. |
175 | */ | 177 | */ |
176 | #define COMMANDLIST_ALIGNMENT (8) | 178 | #define COMMANDLIST_ALIGNMENT (32) |
177 | #define IS_64_BIT ((sizeof(long) - 4)/4) | 179 | #define IS_64_BIT ((sizeof(long) - 4)/4) |
178 | #define IS_32_BIT (!IS_64_BIT) | 180 | #define IS_32_BIT (!IS_64_BIT) |
179 | #define PAD_32 (0) | 181 | #define PAD_32 (0) |
180 | #define PAD_64 (4) | 182 | #define PAD_64 (4) |
181 | #define PADSIZE (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64) | 183 | #define PADSIZE (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64) |
184 | #define DIRECT_LOOKUP_BIT 0x10 | ||
185 | #define DIRECT_LOOKUP_SHIFT 5 | ||
186 | |||
182 | typedef struct _CommandList_struct { | 187 | typedef struct _CommandList_struct { |
183 | CommandListHeader_struct Header; | 188 | CommandListHeader_struct Header; |
184 | RequestBlock_struct Request; | 189 | RequestBlock_struct Request; |
@@ -195,7 +200,7 @@ typedef struct _CommandList_struct { | |||
195 | struct completion *waiting; | 200 | struct completion *waiting; |
196 | int retry_count; | 201 | int retry_count; |
197 | void * scsi_cmd; | 202 | void * scsi_cmd; |
198 | char pad[PADSIZE]; | 203 | char pad[PADSIZE]; |
199 | } CommandList_struct; | 204 | } CommandList_struct; |
200 | 205 | ||
201 | /* Configuration Table Structure */ | 206 | /* Configuration Table Structure */ |
@@ -209,12 +214,15 @@ typedef struct _HostWrite_struct { | |||
209 | typedef struct _CfgTable_struct { | 214 | typedef struct _CfgTable_struct { |
210 | BYTE Signature[4]; | 215 | BYTE Signature[4]; |
211 | DWORD SpecValence; | 216 | DWORD SpecValence; |
217 | #define SIMPLE_MODE 0x02 | ||
218 | #define PERFORMANT_MODE 0x04 | ||
219 | #define MEMQ_MODE 0x08 | ||
212 | DWORD TransportSupport; | 220 | DWORD TransportSupport; |
213 | DWORD TransportActive; | 221 | DWORD TransportActive; |
214 | HostWrite_struct HostWrite; | 222 | HostWrite_struct HostWrite; |
215 | DWORD CmdsOutMax; | 223 | DWORD CmdsOutMax; |
216 | DWORD BusTypes; | 224 | DWORD BusTypes; |
217 | DWORD Reserved; | 225 | DWORD TransMethodOffset; |
218 | BYTE ServerName[16]; | 226 | BYTE ServerName[16]; |
219 | DWORD HeartBeat; | 227 | DWORD HeartBeat; |
220 | DWORD SCSI_Prefetch; | 228 | DWORD SCSI_Prefetch; |
@@ -222,6 +230,28 @@ typedef struct _CfgTable_struct { | |||
222 | DWORD MaxLogicalUnits; | 230 | DWORD MaxLogicalUnits; |
223 | DWORD MaxPhysicalDrives; | 231 | DWORD MaxPhysicalDrives; |
224 | DWORD MaxPhysicalDrivesPerLogicalUnit; | 232 | DWORD MaxPhysicalDrivesPerLogicalUnit; |
233 | DWORD MaxPerformantModeCommands; | ||
234 | u8 reserved[0x78 - 0x58]; | ||
235 | u32 misc_fw_support; /* offset 0x78 */ | ||
236 | #define MISC_FW_DOORBELL_RESET (0x02) | ||
225 | } CfgTable_struct; | 237 | } CfgTable_struct; |
238 | |||
239 | struct TransTable_struct { | ||
240 | u32 BlockFetch0; | ||
241 | u32 BlockFetch1; | ||
242 | u32 BlockFetch2; | ||
243 | u32 BlockFetch3; | ||
244 | u32 BlockFetch4; | ||
245 | u32 BlockFetch5; | ||
246 | u32 BlockFetch6; | ||
247 | u32 BlockFetch7; | ||
248 | u32 RepQSize; | ||
249 | u32 RepQCount; | ||
250 | u32 RepQCtrAddrLow32; | ||
251 | u32 RepQCtrAddrHigh32; | ||
252 | u32 RepQAddr0Low32; | ||
253 | u32 RepQAddr0High32; | ||
254 | }; | ||
255 | |||
226 | #pragma pack() | 256 | #pragma pack() |
227 | #endif /* CCISS_CMD_H */ | 257 | #endif /* CCISS_CMD_H */ |
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 72dae92f3cab..575495f3c4b8 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
@@ -44,13 +44,15 @@ | |||
44 | #define CCISS_ABORT_MSG 0x00 | 44 | #define CCISS_ABORT_MSG 0x00 |
45 | #define CCISS_RESET_MSG 0x01 | 45 | #define CCISS_RESET_MSG 0x01 |
46 | 46 | ||
47 | static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, | 47 | static int fill_cmd(ctlr_info_t *h, CommandList_struct *c, __u8 cmd, void *buff, |
48 | size_t size, | 48 | size_t size, |
49 | __u8 page_code, unsigned char *scsi3addr, | 49 | __u8 page_code, unsigned char *scsi3addr, |
50 | int cmd_type); | 50 | int cmd_type); |
51 | 51 | ||
52 | static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool); | 52 | static CommandList_struct *cmd_alloc(ctlr_info_t *h); |
53 | static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool); | 53 | static CommandList_struct *cmd_special_alloc(ctlr_info_t *h); |
54 | static void cmd_free(ctlr_info_t *h, CommandList_struct *c); | ||
55 | static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c); | ||
54 | 56 | ||
55 | static int cciss_scsi_proc_info( | 57 | static int cciss_scsi_proc_info( |
56 | struct Scsi_Host *sh, | 58 | struct Scsi_Host *sh, |
@@ -93,8 +95,8 @@ static struct scsi_host_template cciss_driver_template = { | |||
93 | 95 | ||
94 | #pragma pack(1) | 96 | #pragma pack(1) |
95 | 97 | ||
96 | #define SCSI_PAD_32 0 | 98 | #define SCSI_PAD_32 8 |
97 | #define SCSI_PAD_64 0 | 99 | #define SCSI_PAD_64 8 |
98 | 100 | ||
99 | struct cciss_scsi_cmd_stack_elem_t { | 101 | struct cciss_scsi_cmd_stack_elem_t { |
100 | CommandList_struct cmd; | 102 | CommandList_struct cmd; |
@@ -127,16 +129,16 @@ struct cciss_scsi_adapter_data_t { | |||
127 | spinlock_t lock; // to protect ccissscsi[ctlr]; | 129 | spinlock_t lock; // to protect ccissscsi[ctlr]; |
128 | }; | 130 | }; |
129 | 131 | ||
130 | #define CPQ_TAPE_LOCK(ctlr, flags) spin_lock_irqsave( \ | 132 | #define CPQ_TAPE_LOCK(h, flags) spin_lock_irqsave( \ |
131 | &hba[ctlr]->scsi_ctlr->lock, flags); | 133 | &h->scsi_ctlr->lock, flags); |
132 | #define CPQ_TAPE_UNLOCK(ctlr, flags) spin_unlock_irqrestore( \ | 134 | #define CPQ_TAPE_UNLOCK(h, flags) spin_unlock_irqrestore( \ |
133 | &hba[ctlr]->scsi_ctlr->lock, flags); | 135 | &h->scsi_ctlr->lock, flags); |
134 | 136 | ||
135 | static CommandList_struct * | 137 | static CommandList_struct * |
136 | scsi_cmd_alloc(ctlr_info_t *h) | 138 | scsi_cmd_alloc(ctlr_info_t *h) |
137 | { | 139 | { |
138 | /* assume only one process in here at a time, locking done by caller. */ | 140 | /* assume only one process in here at a time, locking done by caller. */ |
139 | /* use CCISS_LOCK(ctlr) */ | 141 | /* use h->lock */ |
140 | /* might be better to rewrite how we allocate scsi commands in a way that */ | 142 | /* might be better to rewrite how we allocate scsi commands in a way that */ |
141 | /* needs no locking at all. */ | 143 | /* needs no locking at all. */ |
142 | 144 | ||
@@ -177,10 +179,10 @@ scsi_cmd_alloc(ctlr_info_t *h) | |||
177 | } | 179 | } |
178 | 180 | ||
179 | static void | 181 | static void |
180 | scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd) | 182 | scsi_cmd_free(ctlr_info_t *h, CommandList_struct *c) |
181 | { | 183 | { |
182 | /* assume only one process in here at a time, locking done by caller. */ | 184 | /* assume only one process in here at a time, locking done by caller. */ |
183 | /* use CCISS_LOCK(ctlr) */ | 185 | /* use h->lock */ |
184 | /* drop the free memory chunk on top of the stack. */ | 186 | /* drop the free memory chunk on top of the stack. */ |
185 | 187 | ||
186 | struct cciss_scsi_adapter_data_t *sa; | 188 | struct cciss_scsi_adapter_data_t *sa; |
@@ -190,22 +192,23 @@ scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd) | |||
190 | stk = &sa->cmd_stack; | 192 | stk = &sa->cmd_stack; |
191 | stk->top++; | 193 | stk->top++; |
192 | if (stk->top >= CMD_STACK_SIZE) { | 194 | if (stk->top >= CMD_STACK_SIZE) { |
193 | printk("cciss: scsi_cmd_free called too many times.\n"); | 195 | dev_err(&h->pdev->dev, |
196 | "scsi_cmd_free called too many times.\n"); | ||
194 | BUG(); | 197 | BUG(); |
195 | } | 198 | } |
196 | stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) cmd; | 199 | stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) c; |
197 | } | 200 | } |
198 | 201 | ||
199 | static int | 202 | static int |
200 | scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa) | 203 | scsi_cmd_stack_setup(ctlr_info_t *h, struct cciss_scsi_adapter_data_t *sa) |
201 | { | 204 | { |
202 | int i; | 205 | int i; |
203 | struct cciss_scsi_cmd_stack_t *stk; | 206 | struct cciss_scsi_cmd_stack_t *stk; |
204 | size_t size; | 207 | size_t size; |
205 | 208 | ||
206 | sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[ctlr], | 209 | sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(h, |
207 | hba[ctlr]->chainsize, CMD_STACK_SIZE); | 210 | h->chainsize, CMD_STACK_SIZE); |
208 | if (!sa->cmd_sg_list && hba[ctlr]->chainsize > 0) | 211 | if (!sa->cmd_sg_list && h->chainsize > 0) |
209 | return -ENOMEM; | 212 | return -ENOMEM; |
210 | 213 | ||
211 | stk = &sa->cmd_stack; | 214 | stk = &sa->cmd_stack; |
@@ -215,7 +218,7 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa) | |||
215 | BUILD_BUG_ON((sizeof(*stk->pool) % COMMANDLIST_ALIGNMENT) != 0); | 218 | BUILD_BUG_ON((sizeof(*stk->pool) % COMMANDLIST_ALIGNMENT) != 0); |
216 | /* pci_alloc_consistent guarantees 32-bit DMA address will be used */ | 219 | /* pci_alloc_consistent guarantees 32-bit DMA address will be used */ |
217 | stk->pool = (struct cciss_scsi_cmd_stack_elem_t *) | 220 | stk->pool = (struct cciss_scsi_cmd_stack_elem_t *) |
218 | pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle); | 221 | pci_alloc_consistent(h->pdev, size, &stk->cmd_pool_handle); |
219 | 222 | ||
220 | if (stk->pool == NULL) { | 223 | if (stk->pool == NULL) { |
221 | cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE); | 224 | cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE); |
@@ -234,23 +237,22 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa) | |||
234 | } | 237 | } |
235 | 238 | ||
236 | static void | 239 | static void |
237 | scsi_cmd_stack_free(int ctlr) | 240 | scsi_cmd_stack_free(ctlr_info_t *h) |
238 | { | 241 | { |
239 | struct cciss_scsi_adapter_data_t *sa; | 242 | struct cciss_scsi_adapter_data_t *sa; |
240 | struct cciss_scsi_cmd_stack_t *stk; | 243 | struct cciss_scsi_cmd_stack_t *stk; |
241 | size_t size; | 244 | size_t size; |
242 | 245 | ||
243 | sa = hba[ctlr]->scsi_ctlr; | 246 | sa = h->scsi_ctlr; |
244 | stk = &sa->cmd_stack; | 247 | stk = &sa->cmd_stack; |
245 | if (stk->top != CMD_STACK_SIZE-1) { | 248 | if (stk->top != CMD_STACK_SIZE-1) { |
246 | printk( "cciss: %d scsi commands are still outstanding.\n", | 249 | dev_warn(&h->pdev->dev, |
250 | "bug: %d scsi commands are still outstanding.\n", | ||
247 | CMD_STACK_SIZE - stk->top); | 251 | CMD_STACK_SIZE - stk->top); |
248 | // BUG(); | ||
249 | printk("WE HAVE A BUG HERE!!! stk=0x%p\n", stk); | ||
250 | } | 252 | } |
251 | size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE; | 253 | size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE; |
252 | 254 | ||
253 | pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle); | 255 | pci_free_consistent(h->pdev, size, stk->pool, stk->cmd_pool_handle); |
254 | stk->pool = NULL; | 256 | stk->pool = NULL; |
255 | cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE); | 257 | cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE); |
256 | } | 258 | } |
@@ -342,20 +344,20 @@ print_cmd(CommandList_struct *cp) | |||
342 | #endif | 344 | #endif |
343 | 345 | ||
344 | static int | 346 | static int |
345 | find_bus_target_lun(int ctlr, int *bus, int *target, int *lun) | 347 | find_bus_target_lun(ctlr_info_t *h, int *bus, int *target, int *lun) |
346 | { | 348 | { |
347 | /* finds an unused bus, target, lun for a new device */ | 349 | /* finds an unused bus, target, lun for a new device */ |
348 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ | 350 | /* assumes h->scsi_ctlr->lock is held */ |
349 | int i, found=0; | 351 | int i, found=0; |
350 | unsigned char target_taken[CCISS_MAX_SCSI_DEVS_PER_HBA]; | 352 | unsigned char target_taken[CCISS_MAX_SCSI_DEVS_PER_HBA]; |
351 | 353 | ||
352 | memset(&target_taken[0], 0, CCISS_MAX_SCSI_DEVS_PER_HBA); | 354 | memset(&target_taken[0], 0, CCISS_MAX_SCSI_DEVS_PER_HBA); |
353 | 355 | ||
354 | target_taken[SELF_SCSI_ID] = 1; | 356 | target_taken[SELF_SCSI_ID] = 1; |
355 | for (i=0;i<ccissscsi[ctlr].ndevices;i++) | 357 | for (i = 0; i < ccissscsi[h->ctlr].ndevices; i++) |
356 | target_taken[ccissscsi[ctlr].dev[i].target] = 1; | 358 | target_taken[ccissscsi[h->ctlr].dev[i].target] = 1; |
357 | 359 | ||
358 | for (i=0;i<CCISS_MAX_SCSI_DEVS_PER_HBA;i++) { | 360 | for (i = 0; i < CCISS_MAX_SCSI_DEVS_PER_HBA; i++) { |
359 | if (!target_taken[i]) { | 361 | if (!target_taken[i]) { |
360 | *bus = 0; *target=i; *lun = 0; found=1; | 362 | *bus = 0; *target=i; *lun = 0; found=1; |
361 | break; | 363 | break; |
@@ -369,19 +371,19 @@ struct scsi2map { | |||
369 | }; | 371 | }; |
370 | 372 | ||
371 | static int | 373 | static int |
372 | cciss_scsi_add_entry(int ctlr, int hostno, | 374 | cciss_scsi_add_entry(ctlr_info_t *h, int hostno, |
373 | struct cciss_scsi_dev_t *device, | 375 | struct cciss_scsi_dev_t *device, |
374 | struct scsi2map *added, int *nadded) | 376 | struct scsi2map *added, int *nadded) |
375 | { | 377 | { |
376 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ | 378 | /* assumes h->scsi_ctlr->lock is held */ |
377 | int n = ccissscsi[ctlr].ndevices; | 379 | int n = ccissscsi[h->ctlr].ndevices; |
378 | struct cciss_scsi_dev_t *sd; | 380 | struct cciss_scsi_dev_t *sd; |
379 | int i, bus, target, lun; | 381 | int i, bus, target, lun; |
380 | unsigned char addr1[8], addr2[8]; | 382 | unsigned char addr1[8], addr2[8]; |
381 | 383 | ||
382 | if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { | 384 | if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { |
383 | printk("cciss%d: Too many devices, " | 385 | dev_warn(&h->pdev->dev, "Too many devices, " |
384 | "some will be inaccessible.\n", ctlr); | 386 | "some will be inaccessible.\n"); |
385 | return -1; | 387 | return -1; |
386 | } | 388 | } |
387 | 389 | ||
@@ -397,7 +399,7 @@ cciss_scsi_add_entry(int ctlr, int hostno, | |||
397 | memcpy(addr1, device->scsi3addr, 8); | 399 | memcpy(addr1, device->scsi3addr, 8); |
398 | addr1[4] = 0; | 400 | addr1[4] = 0; |
399 | for (i = 0; i < n; i++) { | 401 | for (i = 0; i < n; i++) { |
400 | sd = &ccissscsi[ctlr].dev[i]; | 402 | sd = &ccissscsi[h->ctlr].dev[i]; |
401 | memcpy(addr2, sd->scsi3addr, 8); | 403 | memcpy(addr2, sd->scsi3addr, 8); |
402 | addr2[4] = 0; | 404 | addr2[4] = 0; |
403 | /* differ only in byte 4? */ | 405 | /* differ only in byte 4? */ |
@@ -410,9 +412,9 @@ cciss_scsi_add_entry(int ctlr, int hostno, | |||
410 | } | 412 | } |
411 | } | 413 | } |
412 | 414 | ||
413 | sd = &ccissscsi[ctlr].dev[n]; | 415 | sd = &ccissscsi[h->ctlr].dev[n]; |
414 | if (lun == 0) { | 416 | if (lun == 0) { |
415 | if (find_bus_target_lun(ctlr, | 417 | if (find_bus_target_lun(h, |
416 | &sd->bus, &sd->target, &sd->lun) != 0) | 418 | &sd->bus, &sd->target, &sd->lun) != 0) |
417 | return -1; | 419 | return -1; |
418 | } else { | 420 | } else { |
@@ -431,37 +433,37 @@ cciss_scsi_add_entry(int ctlr, int hostno, | |||
431 | memcpy(sd->device_id, device->device_id, sizeof(sd->device_id)); | 433 | memcpy(sd->device_id, device->device_id, sizeof(sd->device_id)); |
432 | sd->devtype = device->devtype; | 434 | sd->devtype = device->devtype; |
433 | 435 | ||
434 | ccissscsi[ctlr].ndevices++; | 436 | ccissscsi[h->ctlr].ndevices++; |
435 | 437 | ||
436 | /* initially, (before registering with scsi layer) we don't | 438 | /* initially, (before registering with scsi layer) we don't |
437 | know our hostno and we don't want to print anything first | 439 | know our hostno and we don't want to print anything first |
438 | time anyway (the scsi layer's inquiries will show that info) */ | 440 | time anyway (the scsi layer's inquiries will show that info) */ |
439 | if (hostno != -1) | 441 | if (hostno != -1) |
440 | printk("cciss%d: %s device c%db%dt%dl%d added.\n", | 442 | dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d added.\n", |
441 | ctlr, scsi_device_type(sd->devtype), hostno, | 443 | scsi_device_type(sd->devtype), hostno, |
442 | sd->bus, sd->target, sd->lun); | 444 | sd->bus, sd->target, sd->lun); |
443 | return 0; | 445 | return 0; |
444 | } | 446 | } |
445 | 447 | ||
446 | static void | 448 | static void |
447 | cciss_scsi_remove_entry(int ctlr, int hostno, int entry, | 449 | cciss_scsi_remove_entry(ctlr_info_t *h, int hostno, int entry, |
448 | struct scsi2map *removed, int *nremoved) | 450 | struct scsi2map *removed, int *nremoved) |
449 | { | 451 | { |
450 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ | 452 | /* assumes h->ctlr]->scsi_ctlr->lock is held */ |
451 | int i; | 453 | int i; |
452 | struct cciss_scsi_dev_t sd; | 454 | struct cciss_scsi_dev_t sd; |
453 | 455 | ||
454 | if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return; | 456 | if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return; |
455 | sd = ccissscsi[ctlr].dev[entry]; | 457 | sd = ccissscsi[h->ctlr].dev[entry]; |
456 | removed[*nremoved].bus = sd.bus; | 458 | removed[*nremoved].bus = sd.bus; |
457 | removed[*nremoved].target = sd.target; | 459 | removed[*nremoved].target = sd.target; |
458 | removed[*nremoved].lun = sd.lun; | 460 | removed[*nremoved].lun = sd.lun; |
459 | (*nremoved)++; | 461 | (*nremoved)++; |
460 | for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++) | 462 | for (i = entry; i < ccissscsi[h->ctlr].ndevices-1; i++) |
461 | ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1]; | 463 | ccissscsi[h->ctlr].dev[i] = ccissscsi[h->ctlr].dev[i+1]; |
462 | ccissscsi[ctlr].ndevices--; | 464 | ccissscsi[h->ctlr].ndevices--; |
463 | printk("cciss%d: %s device c%db%dt%dl%d removed.\n", | 465 | dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d removed.\n", |
464 | ctlr, scsi_device_type(sd.devtype), hostno, | 466 | scsi_device_type(sd.devtype), hostno, |
465 | sd.bus, sd.target, sd.lun); | 467 | sd.bus, sd.target, sd.lun); |
466 | } | 468 | } |
467 | 469 | ||
@@ -476,24 +478,24 @@ cciss_scsi_remove_entry(int ctlr, int hostno, int entry, | |||
476 | (a)[1] == (b)[1] && \ | 478 | (a)[1] == (b)[1] && \ |
477 | (a)[0] == (b)[0]) | 479 | (a)[0] == (b)[0]) |
478 | 480 | ||
479 | static void fixup_botched_add(int ctlr, char *scsi3addr) | 481 | static void fixup_botched_add(ctlr_info_t *h, char *scsi3addr) |
480 | { | 482 | { |
481 | /* called when scsi_add_device fails in order to re-adjust */ | 483 | /* called when scsi_add_device fails in order to re-adjust */ |
482 | /* ccissscsi[] to match the mid layer's view. */ | 484 | /* ccissscsi[] to match the mid layer's view. */ |
483 | unsigned long flags; | 485 | unsigned long flags; |
484 | int i, j; | 486 | int i, j; |
485 | CPQ_TAPE_LOCK(ctlr, flags); | 487 | CPQ_TAPE_LOCK(h, flags); |
486 | for (i = 0; i < ccissscsi[ctlr].ndevices; i++) { | 488 | for (i = 0; i < ccissscsi[h->ctlr].ndevices; i++) { |
487 | if (memcmp(scsi3addr, | 489 | if (memcmp(scsi3addr, |
488 | ccissscsi[ctlr].dev[i].scsi3addr, 8) == 0) { | 490 | ccissscsi[h->ctlr].dev[i].scsi3addr, 8) == 0) { |
489 | for (j = i; j < ccissscsi[ctlr].ndevices-1; j++) | 491 | for (j = i; j < ccissscsi[h->ctlr].ndevices-1; j++) |
490 | ccissscsi[ctlr].dev[j] = | 492 | ccissscsi[h->ctlr].dev[j] = |
491 | ccissscsi[ctlr].dev[j+1]; | 493 | ccissscsi[h->ctlr].dev[j+1]; |
492 | ccissscsi[ctlr].ndevices--; | 494 | ccissscsi[h->ctlr].ndevices--; |
493 | break; | 495 | break; |
494 | } | 496 | } |
495 | } | 497 | } |
496 | CPQ_TAPE_UNLOCK(ctlr, flags); | 498 | CPQ_TAPE_UNLOCK(h, flags); |
497 | } | 499 | } |
498 | 500 | ||
499 | static int device_is_the_same(struct cciss_scsi_dev_t *dev1, | 501 | static int device_is_the_same(struct cciss_scsi_dev_t *dev1, |
@@ -513,7 +515,7 @@ static int device_is_the_same(struct cciss_scsi_dev_t *dev1, | |||
513 | } | 515 | } |
514 | 516 | ||
515 | static int | 517 | static int |
516 | adjust_cciss_scsi_table(int ctlr, int hostno, | 518 | adjust_cciss_scsi_table(ctlr_info_t *h, int hostno, |
517 | struct cciss_scsi_dev_t sd[], int nsds) | 519 | struct cciss_scsi_dev_t sd[], int nsds) |
518 | { | 520 | { |
519 | /* sd contains scsi3 addresses and devtypes, but | 521 | /* sd contains scsi3 addresses and devtypes, but |
@@ -534,15 +536,15 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
534 | GFP_KERNEL); | 536 | GFP_KERNEL); |
535 | 537 | ||
536 | if (!added || !removed) { | 538 | if (!added || !removed) { |
537 | printk(KERN_WARNING "cciss%d: Out of memory in " | 539 | dev_warn(&h->pdev->dev, |
538 | "adjust_cciss_scsi_table\n", ctlr); | 540 | "Out of memory in adjust_cciss_scsi_table\n"); |
539 | goto free_and_out; | 541 | goto free_and_out; |
540 | } | 542 | } |
541 | 543 | ||
542 | CPQ_TAPE_LOCK(ctlr, flags); | 544 | CPQ_TAPE_LOCK(h, flags); |
543 | 545 | ||
544 | if (hostno != -1) /* if it's not the first time... */ | 546 | if (hostno != -1) /* if it's not the first time... */ |
545 | sh = hba[ctlr]->scsi_ctlr->scsi_host; | 547 | sh = h->scsi_ctlr->scsi_host; |
546 | 548 | ||
547 | /* find any devices in ccissscsi[] that are not in | 549 | /* find any devices in ccissscsi[] that are not in |
548 | sd[] and remove them from ccissscsi[] */ | 550 | sd[] and remove them from ccissscsi[] */ |
@@ -550,8 +552,8 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
550 | i = 0; | 552 | i = 0; |
551 | nremoved = 0; | 553 | nremoved = 0; |
552 | nadded = 0; | 554 | nadded = 0; |
553 | while(i<ccissscsi[ctlr].ndevices) { | 555 | while (i < ccissscsi[h->ctlr].ndevices) { |
554 | csd = &ccissscsi[ctlr].dev[i]; | 556 | csd = &ccissscsi[h->ctlr].dev[i]; |
555 | found=0; | 557 | found=0; |
556 | for (j=0;j<nsds;j++) { | 558 | for (j=0;j<nsds;j++) { |
557 | if (SCSI3ADDR_EQ(sd[j].scsi3addr, | 559 | if (SCSI3ADDR_EQ(sd[j].scsi3addr, |
@@ -566,20 +568,18 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
566 | 568 | ||
567 | if (found == 0) { /* device no longer present. */ | 569 | if (found == 0) { /* device no longer present. */ |
568 | changes++; | 570 | changes++; |
569 | /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n", | 571 | cciss_scsi_remove_entry(h, hostno, i, |
570 | ctlr, scsi_device_type(csd->devtype), hostno, | ||
571 | csd->bus, csd->target, csd->lun); */ | ||
572 | cciss_scsi_remove_entry(ctlr, hostno, i, | ||
573 | removed, &nremoved); | 572 | removed, &nremoved); |
574 | /* remove ^^^, hence i not incremented */ | 573 | /* remove ^^^, hence i not incremented */ |
575 | } else if (found == 1) { /* device is different in some way */ | 574 | } else if (found == 1) { /* device is different in some way */ |
576 | changes++; | 575 | changes++; |
577 | printk("cciss%d: device c%db%dt%dl%d has changed.\n", | 576 | dev_info(&h->pdev->dev, |
578 | ctlr, hostno, csd->bus, csd->target, csd->lun); | 577 | "device c%db%dt%dl%d has changed.\n", |
579 | cciss_scsi_remove_entry(ctlr, hostno, i, | 578 | hostno, csd->bus, csd->target, csd->lun); |
579 | cciss_scsi_remove_entry(h, hostno, i, | ||
580 | removed, &nremoved); | 580 | removed, &nremoved); |
581 | /* remove ^^^, hence i not incremented */ | 581 | /* remove ^^^, hence i not incremented */ |
582 | if (cciss_scsi_add_entry(ctlr, hostno, &sd[j], | 582 | if (cciss_scsi_add_entry(h, hostno, &sd[j], |
583 | added, &nadded) != 0) | 583 | added, &nadded) != 0) |
584 | /* we just removed one, so add can't fail. */ | 584 | /* we just removed one, so add can't fail. */ |
585 | BUG(); | 585 | BUG(); |
@@ -601,8 +601,8 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
601 | 601 | ||
602 | for (i=0;i<nsds;i++) { | 602 | for (i=0;i<nsds;i++) { |
603 | found=0; | 603 | found=0; |
604 | for (j=0;j<ccissscsi[ctlr].ndevices;j++) { | 604 | for (j = 0; j < ccissscsi[h->ctlr].ndevices; j++) { |
605 | csd = &ccissscsi[ctlr].dev[j]; | 605 | csd = &ccissscsi[h->ctlr].dev[j]; |
606 | if (SCSI3ADDR_EQ(sd[i].scsi3addr, | 606 | if (SCSI3ADDR_EQ(sd[i].scsi3addr, |
607 | csd->scsi3addr)) { | 607 | csd->scsi3addr)) { |
608 | if (device_is_the_same(&sd[i], csd)) | 608 | if (device_is_the_same(&sd[i], csd)) |
@@ -614,18 +614,18 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
614 | } | 614 | } |
615 | if (!found) { | 615 | if (!found) { |
616 | changes++; | 616 | changes++; |
617 | if (cciss_scsi_add_entry(ctlr, hostno, &sd[i], | 617 | if (cciss_scsi_add_entry(h, hostno, &sd[i], |
618 | added, &nadded) != 0) | 618 | added, &nadded) != 0) |
619 | break; | 619 | break; |
620 | } else if (found == 1) { | 620 | } else if (found == 1) { |
621 | /* should never happen... */ | 621 | /* should never happen... */ |
622 | changes++; | 622 | changes++; |
623 | printk(KERN_WARNING "cciss%d: device " | 623 | dev_warn(&h->pdev->dev, |
624 | "unexpectedly changed\n", ctlr); | 624 | "device unexpectedly changed\n"); |
625 | /* but if it does happen, we just ignore that device */ | 625 | /* but if it does happen, we just ignore that device */ |
626 | } | 626 | } |
627 | } | 627 | } |
628 | CPQ_TAPE_UNLOCK(ctlr, flags); | 628 | CPQ_TAPE_UNLOCK(h, flags); |
629 | 629 | ||
630 | /* Don't notify scsi mid layer of any changes the first time through */ | 630 | /* Don't notify scsi mid layer of any changes the first time through */ |
631 | /* (or if there are no changes) scsi_scan_host will do it later the */ | 631 | /* (or if there are no changes) scsi_scan_host will do it later the */ |
@@ -645,9 +645,9 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
645 | /* We don't expect to get here. */ | 645 | /* We don't expect to get here. */ |
646 | /* future cmds to this device will get selection */ | 646 | /* future cmds to this device will get selection */ |
647 | /* timeout as if the device was gone. */ | 647 | /* timeout as if the device was gone. */ |
648 | printk(KERN_WARNING "cciss%d: didn't find " | 648 | dev_warn(&h->pdev->dev, "didn't find " |
649 | "c%db%dt%dl%d\n for removal.", | 649 | "c%db%dt%dl%d\n for removal.", |
650 | ctlr, hostno, removed[i].bus, | 650 | hostno, removed[i].bus, |
651 | removed[i].target, removed[i].lun); | 651 | removed[i].target, removed[i].lun); |
652 | } | 652 | } |
653 | } | 653 | } |
@@ -659,13 +659,12 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
659 | added[i].target, added[i].lun); | 659 | added[i].target, added[i].lun); |
660 | if (rc == 0) | 660 | if (rc == 0) |
661 | continue; | 661 | continue; |
662 | printk(KERN_WARNING "cciss%d: scsi_add_device " | 662 | dev_warn(&h->pdev->dev, "scsi_add_device " |
663 | "c%db%dt%dl%d failed, device not added.\n", | 663 | "c%db%dt%dl%d failed, device not added.\n", |
664 | ctlr, hostno, | 664 | hostno, added[i].bus, added[i].target, added[i].lun); |
665 | added[i].bus, added[i].target, added[i].lun); | ||
666 | /* now we have to remove it from ccissscsi, */ | 665 | /* now we have to remove it from ccissscsi, */ |
667 | /* since it didn't get added to scsi mid layer */ | 666 | /* since it didn't get added to scsi mid layer */ |
668 | fixup_botched_add(ctlr, added[i].scsi3addr); | 667 | fixup_botched_add(h, added[i].scsi3addr); |
669 | } | 668 | } |
670 | 669 | ||
671 | free_and_out: | 670 | free_and_out: |
@@ -675,33 +674,33 @@ free_and_out: | |||
675 | } | 674 | } |
676 | 675 | ||
677 | static int | 676 | static int |
678 | lookup_scsi3addr(int ctlr, int bus, int target, int lun, char *scsi3addr) | 677 | lookup_scsi3addr(ctlr_info_t *h, int bus, int target, int lun, char *scsi3addr) |
679 | { | 678 | { |
680 | int i; | 679 | int i; |
681 | struct cciss_scsi_dev_t *sd; | 680 | struct cciss_scsi_dev_t *sd; |
682 | unsigned long flags; | 681 | unsigned long flags; |
683 | 682 | ||
684 | CPQ_TAPE_LOCK(ctlr, flags); | 683 | CPQ_TAPE_LOCK(h, flags); |
685 | for (i=0;i<ccissscsi[ctlr].ndevices;i++) { | 684 | for (i = 0; i < ccissscsi[h->ctlr].ndevices; i++) { |
686 | sd = &ccissscsi[ctlr].dev[i]; | 685 | sd = &ccissscsi[h->ctlr].dev[i]; |
687 | if (sd->bus == bus && | 686 | if (sd->bus == bus && |
688 | sd->target == target && | 687 | sd->target == target && |
689 | sd->lun == lun) { | 688 | sd->lun == lun) { |
690 | memcpy(scsi3addr, &sd->scsi3addr[0], 8); | 689 | memcpy(scsi3addr, &sd->scsi3addr[0], 8); |
691 | CPQ_TAPE_UNLOCK(ctlr, flags); | 690 | CPQ_TAPE_UNLOCK(h, flags); |
692 | return 0; | 691 | return 0; |
693 | } | 692 | } |
694 | } | 693 | } |
695 | CPQ_TAPE_UNLOCK(ctlr, flags); | 694 | CPQ_TAPE_UNLOCK(h, flags); |
696 | return -1; | 695 | return -1; |
697 | } | 696 | } |
698 | 697 | ||
699 | static void | 698 | static void |
700 | cciss_scsi_setup(int cntl_num) | 699 | cciss_scsi_setup(ctlr_info_t *h) |
701 | { | 700 | { |
702 | struct cciss_scsi_adapter_data_t * shba; | 701 | struct cciss_scsi_adapter_data_t * shba; |
703 | 702 | ||
704 | ccissscsi[cntl_num].ndevices = 0; | 703 | ccissscsi[h->ctlr].ndevices = 0; |
705 | shba = (struct cciss_scsi_adapter_data_t *) | 704 | shba = (struct cciss_scsi_adapter_data_t *) |
706 | kmalloc(sizeof(*shba), GFP_KERNEL); | 705 | kmalloc(sizeof(*shba), GFP_KERNEL); |
707 | if (shba == NULL) | 706 | if (shba == NULL) |
@@ -709,35 +708,35 @@ cciss_scsi_setup(int cntl_num) | |||
709 | shba->scsi_host = NULL; | 708 | shba->scsi_host = NULL; |
710 | spin_lock_init(&shba->lock); | 709 | spin_lock_init(&shba->lock); |
711 | shba->registered = 0; | 710 | shba->registered = 0; |
712 | if (scsi_cmd_stack_setup(cntl_num, shba) != 0) { | 711 | if (scsi_cmd_stack_setup(h, shba) != 0) { |
713 | kfree(shba); | 712 | kfree(shba); |
714 | shba = NULL; | 713 | shba = NULL; |
715 | } | 714 | } |
716 | hba[cntl_num]->scsi_ctlr = shba; | 715 | h->scsi_ctlr = shba; |
717 | return; | 716 | return; |
718 | } | 717 | } |
719 | 718 | ||
720 | static void | 719 | static void complete_scsi_command(CommandList_struct *c, int timeout, |
721 | complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) | 720 | __u32 tag) |
722 | { | 721 | { |
723 | struct scsi_cmnd *cmd; | 722 | struct scsi_cmnd *cmd; |
724 | ctlr_info_t *ctlr; | 723 | ctlr_info_t *h; |
725 | ErrorInfo_struct *ei; | 724 | ErrorInfo_struct *ei; |
726 | 725 | ||
727 | ei = cp->err_info; | 726 | ei = c->err_info; |
728 | 727 | ||
729 | /* First, see if it was a message rather than a command */ | 728 | /* First, see if it was a message rather than a command */ |
730 | if (cp->Request.Type.Type == TYPE_MSG) { | 729 | if (c->Request.Type.Type == TYPE_MSG) { |
731 | cp->cmd_type = CMD_MSG_DONE; | 730 | c->cmd_type = CMD_MSG_DONE; |
732 | return; | 731 | return; |
733 | } | 732 | } |
734 | 733 | ||
735 | cmd = (struct scsi_cmnd *) cp->scsi_cmd; | 734 | cmd = (struct scsi_cmnd *) c->scsi_cmd; |
736 | ctlr = hba[cp->ctlr]; | 735 | h = hba[c->ctlr]; |
737 | 736 | ||
738 | scsi_dma_unmap(cmd); | 737 | scsi_dma_unmap(cmd); |
739 | if (cp->Header.SGTotal > ctlr->max_cmd_sgentries) | 738 | if (c->Header.SGTotal > h->max_cmd_sgentries) |
740 | cciss_unmap_sg_chain_block(ctlr, cp); | 739 | cciss_unmap_sg_chain_block(h, c); |
741 | 740 | ||
742 | cmd->result = (DID_OK << 16); /* host byte */ | 741 | cmd->result = (DID_OK << 16); /* host byte */ |
743 | cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ | 742 | cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ |
@@ -764,9 +763,8 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) | |||
764 | { | 763 | { |
765 | #if 0 | 764 | #if 0 |
766 | printk(KERN_WARNING "cciss: cmd %p " | 765 | printk(KERN_WARNING "cciss: cmd %p " |
767 | "has SCSI Status = %x\n", | 766 | "has SCSI Status = %x\n", |
768 | cp, | 767 | c, ei->ScsiStatus); |
769 | ei->ScsiStatus); | ||
770 | #endif | 768 | #endif |
771 | cmd->result |= (ei->ScsiStatus << 1); | 769 | cmd->result |= (ei->ScsiStatus << 1); |
772 | } | 770 | } |
@@ -786,13 +784,13 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) | |||
786 | case CMD_DATA_UNDERRUN: /* let mid layer handle it. */ | 784 | case CMD_DATA_UNDERRUN: /* let mid layer handle it. */ |
787 | break; | 785 | break; |
788 | case CMD_DATA_OVERRUN: | 786 | case CMD_DATA_OVERRUN: |
789 | printk(KERN_WARNING "cciss: cp %p has" | 787 | dev_warn(&h->pdev->dev, "%p has" |
790 | " completed with data overrun " | 788 | " completed with data overrun " |
791 | "reported\n", cp); | 789 | "reported\n", c); |
792 | break; | 790 | break; |
793 | case CMD_INVALID: { | 791 | case CMD_INVALID: { |
794 | /* print_bytes(cp, sizeof(*cp), 1, 0); | 792 | /* print_bytes(c, sizeof(*c), 1, 0); |
795 | print_cmd(cp); */ | 793 | print_cmd(c); */ |
796 | /* We get CMD_INVALID if you address a non-existent tape drive instead | 794 | /* We get CMD_INVALID if you address a non-existent tape drive instead |
797 | of a selection timeout (no response). You will see this if you yank | 795 | of a selection timeout (no response). You will see this if you yank |
798 | out a tape drive, then try to access it. This is kind of a shame | 796 | out a tape drive, then try to access it. This is kind of a shame |
@@ -802,54 +800,50 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) | |||
802 | } | 800 | } |
803 | break; | 801 | break; |
804 | case CMD_PROTOCOL_ERR: | 802 | case CMD_PROTOCOL_ERR: |
805 | printk(KERN_WARNING "cciss: cp %p has " | 803 | dev_warn(&h->pdev->dev, |
806 | "protocol error \n", cp); | 804 | "%p has protocol error\n", c); |
807 | break; | 805 | break; |
808 | case CMD_HARDWARE_ERR: | 806 | case CMD_HARDWARE_ERR: |
809 | cmd->result = DID_ERROR << 16; | 807 | cmd->result = DID_ERROR << 16; |
810 | printk(KERN_WARNING "cciss: cp %p had " | 808 | dev_warn(&h->pdev->dev, |
811 | " hardware error\n", cp); | 809 | "%p had hardware error\n", c); |
812 | break; | 810 | break; |
813 | case CMD_CONNECTION_LOST: | 811 | case CMD_CONNECTION_LOST: |
814 | cmd->result = DID_ERROR << 16; | 812 | cmd->result = DID_ERROR << 16; |
815 | printk(KERN_WARNING "cciss: cp %p had " | 813 | dev_warn(&h->pdev->dev, |
816 | "connection lost\n", cp); | 814 | "%p had connection lost\n", c); |
817 | break; | 815 | break; |
818 | case CMD_ABORTED: | 816 | case CMD_ABORTED: |
819 | cmd->result = DID_ABORT << 16; | 817 | cmd->result = DID_ABORT << 16; |
820 | printk(KERN_WARNING "cciss: cp %p was " | 818 | dev_warn(&h->pdev->dev, "%p was aborted\n", c); |
821 | "aborted\n", cp); | ||
822 | break; | 819 | break; |
823 | case CMD_ABORT_FAILED: | 820 | case CMD_ABORT_FAILED: |
824 | cmd->result = DID_ERROR << 16; | 821 | cmd->result = DID_ERROR << 16; |
825 | printk(KERN_WARNING "cciss: cp %p reports " | 822 | dev_warn(&h->pdev->dev, |
826 | "abort failed\n", cp); | 823 | "%p reports abort failed\n", c); |
827 | break; | 824 | break; |
828 | case CMD_UNSOLICITED_ABORT: | 825 | case CMD_UNSOLICITED_ABORT: |
829 | cmd->result = DID_ABORT << 16; | 826 | cmd->result = DID_ABORT << 16; |
830 | printk(KERN_WARNING "cciss: cp %p aborted " | 827 | dev_warn(&h->pdev->dev, "%p aborted do to an " |
831 | "do to an unsolicited abort\n", cp); | 828 | "unsolicited abort\n", c); |
832 | break; | 829 | break; |
833 | case CMD_TIMEOUT: | 830 | case CMD_TIMEOUT: |
834 | cmd->result = DID_TIME_OUT << 16; | 831 | cmd->result = DID_TIME_OUT << 16; |
835 | printk(KERN_WARNING "cciss: cp %p timedout\n", | 832 | dev_warn(&h->pdev->dev, "%p timedout\n", c); |
836 | cp); | ||
837 | break; | 833 | break; |
838 | default: | 834 | default: |
839 | cmd->result = DID_ERROR << 16; | 835 | cmd->result = DID_ERROR << 16; |
840 | printk(KERN_WARNING "cciss: cp %p returned " | 836 | dev_warn(&h->pdev->dev, |
841 | "unknown status %x\n", cp, | 837 | "%p returned unknown status %x\n", c, |
842 | ei->CommandStatus); | 838 | ei->CommandStatus); |
843 | } | 839 | } |
844 | } | 840 | } |
845 | // printk("c:%p:c%db%dt%dl%d ", cmd, ctlr->ctlr, cmd->channel, | ||
846 | // cmd->target, cmd->lun); | ||
847 | cmd->scsi_done(cmd); | 841 | cmd->scsi_done(cmd); |
848 | scsi_cmd_free(ctlr, cp); | 842 | scsi_cmd_free(h, c); |
849 | } | 843 | } |
850 | 844 | ||
851 | static int | 845 | static int |
852 | cciss_scsi_detect(int ctlr) | 846 | cciss_scsi_detect(ctlr_info_t *h) |
853 | { | 847 | { |
854 | struct Scsi_Host *sh; | 848 | struct Scsi_Host *sh; |
855 | int error; | 849 | int error; |
@@ -860,15 +854,15 @@ cciss_scsi_detect(int ctlr) | |||
860 | sh->io_port = 0; // good enough? FIXME, | 854 | sh->io_port = 0; // good enough? FIXME, |
861 | sh->n_io_port = 0; // I don't think we use these two... | 855 | sh->n_io_port = 0; // I don't think we use these two... |
862 | sh->this_id = SELF_SCSI_ID; | 856 | sh->this_id = SELF_SCSI_ID; |
863 | sh->sg_tablesize = hba[ctlr]->maxsgentries; | 857 | sh->sg_tablesize = h->maxsgentries; |
864 | sh->max_cmd_len = MAX_COMMAND_SIZE; | 858 | sh->max_cmd_len = MAX_COMMAND_SIZE; |
865 | 859 | ||
866 | ((struct cciss_scsi_adapter_data_t *) | 860 | ((struct cciss_scsi_adapter_data_t *) |
867 | hba[ctlr]->scsi_ctlr)->scsi_host = sh; | 861 | h->scsi_ctlr)->scsi_host = sh; |
868 | sh->hostdata[0] = (unsigned long) hba[ctlr]; | 862 | sh->hostdata[0] = (unsigned long) h; |
869 | sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT]; | 863 | sh->irq = h->intr[SIMPLE_MODE_INT]; |
870 | sh->unique_id = sh->irq; | 864 | sh->unique_id = sh->irq; |
871 | error = scsi_add_host(sh, &hba[ctlr]->pdev->dev); | 865 | error = scsi_add_host(sh, &h->pdev->dev); |
872 | if (error) | 866 | if (error) |
873 | goto fail_host_put; | 867 | goto fail_host_put; |
874 | scsi_scan_host(sh); | 868 | scsi_scan_host(sh); |
@@ -882,20 +876,20 @@ cciss_scsi_detect(int ctlr) | |||
882 | 876 | ||
883 | static void | 877 | static void |
884 | cciss_unmap_one(struct pci_dev *pdev, | 878 | cciss_unmap_one(struct pci_dev *pdev, |
885 | CommandList_struct *cp, | 879 | CommandList_struct *c, |
886 | size_t buflen, | 880 | size_t buflen, |
887 | int data_direction) | 881 | int data_direction) |
888 | { | 882 | { |
889 | u64bit addr64; | 883 | u64bit addr64; |
890 | 884 | ||
891 | addr64.val32.lower = cp->SG[0].Addr.lower; | 885 | addr64.val32.lower = c->SG[0].Addr.lower; |
892 | addr64.val32.upper = cp->SG[0].Addr.upper; | 886 | addr64.val32.upper = c->SG[0].Addr.upper; |
893 | pci_unmap_single(pdev, (dma_addr_t) addr64.val, buflen, data_direction); | 887 | pci_unmap_single(pdev, (dma_addr_t) addr64.val, buflen, data_direction); |
894 | } | 888 | } |
895 | 889 | ||
896 | static void | 890 | static void |
897 | cciss_map_one(struct pci_dev *pdev, | 891 | cciss_map_one(struct pci_dev *pdev, |
898 | CommandList_struct *cp, | 892 | CommandList_struct *c, |
899 | unsigned char *buf, | 893 | unsigned char *buf, |
900 | size_t buflen, | 894 | size_t buflen, |
901 | int data_direction) | 895 | int data_direction) |
@@ -903,164 +897,149 @@ cciss_map_one(struct pci_dev *pdev, | |||
903 | __u64 addr64; | 897 | __u64 addr64; |
904 | 898 | ||
905 | addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction); | 899 | addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction); |
906 | cp->SG[0].Addr.lower = | 900 | c->SG[0].Addr.lower = |
907 | (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); | 901 | (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); |
908 | cp->SG[0].Addr.upper = | 902 | c->SG[0].Addr.upper = |
909 | (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); | 903 | (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); |
910 | cp->SG[0].Len = buflen; | 904 | c->SG[0].Len = buflen; |
911 | cp->Header.SGList = (__u8) 1; /* no. SGs contig in this cmd */ | 905 | c->Header.SGList = (__u8) 1; /* no. SGs contig in this cmd */ |
912 | cp->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */ | 906 | c->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */ |
913 | } | 907 | } |
914 | 908 | ||
915 | static int | 909 | static int |
916 | cciss_scsi_do_simple_cmd(ctlr_info_t *c, | 910 | cciss_scsi_do_simple_cmd(ctlr_info_t *h, |
917 | CommandList_struct *cp, | 911 | CommandList_struct *c, |
918 | unsigned char *scsi3addr, | 912 | unsigned char *scsi3addr, |
919 | unsigned char *cdb, | 913 | unsigned char *cdb, |
920 | unsigned char cdblen, | 914 | unsigned char cdblen, |
921 | unsigned char *buf, int bufsize, | 915 | unsigned char *buf, int bufsize, |
922 | int direction) | 916 | int direction) |
923 | { | 917 | { |
924 | unsigned long flags; | ||
925 | DECLARE_COMPLETION_ONSTACK(wait); | 918 | DECLARE_COMPLETION_ONSTACK(wait); |
926 | 919 | ||
927 | cp->cmd_type = CMD_IOCTL_PEND; // treat this like an ioctl | 920 | c->cmd_type = CMD_IOCTL_PEND; /* treat this like an ioctl */ |
928 | cp->scsi_cmd = NULL; | 921 | c->scsi_cmd = NULL; |
929 | cp->Header.ReplyQueue = 0; // unused in simple mode | 922 | c->Header.ReplyQueue = 0; /* unused in simple mode */ |
930 | memcpy(&cp->Header.LUN, scsi3addr, sizeof(cp->Header.LUN)); | 923 | memcpy(&c->Header.LUN, scsi3addr, sizeof(c->Header.LUN)); |
931 | cp->Header.Tag.lower = cp->busaddr; // Use k. address of cmd as tag | 924 | c->Header.Tag.lower = c->busaddr; /* Use k. address of cmd as tag */ |
932 | // Fill in the request block... | 925 | // Fill in the request block... |
933 | 926 | ||
934 | /* printk("Using scsi3addr 0x%02x%0x2%0x2%0x2%0x2%0x2%0x2%0x2\n", | 927 | /* printk("Using scsi3addr 0x%02x%0x2%0x2%0x2%0x2%0x2%0x2%0x2\n", |
935 | scsi3addr[0], scsi3addr[1], scsi3addr[2], scsi3addr[3], | 928 | scsi3addr[0], scsi3addr[1], scsi3addr[2], scsi3addr[3], |
936 | scsi3addr[4], scsi3addr[5], scsi3addr[6], scsi3addr[7]); */ | 929 | scsi3addr[4], scsi3addr[5], scsi3addr[6], scsi3addr[7]); */ |
937 | 930 | ||
938 | memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB)); | 931 | memset(c->Request.CDB, 0, sizeof(c->Request.CDB)); |
939 | memcpy(cp->Request.CDB, cdb, cdblen); | 932 | memcpy(c->Request.CDB, cdb, cdblen); |
940 | cp->Request.Timeout = 0; | 933 | c->Request.Timeout = 0; |
941 | cp->Request.CDBLen = cdblen; | 934 | c->Request.CDBLen = cdblen; |
942 | cp->Request.Type.Type = TYPE_CMD; | 935 | c->Request.Type.Type = TYPE_CMD; |
943 | cp->Request.Type.Attribute = ATTR_SIMPLE; | 936 | c->Request.Type.Attribute = ATTR_SIMPLE; |
944 | cp->Request.Type.Direction = direction; | 937 | c->Request.Type.Direction = direction; |
945 | 938 | ||
946 | /* Fill in the SG list and do dma mapping */ | 939 | /* Fill in the SG list and do dma mapping */ |
947 | cciss_map_one(c->pdev, cp, (unsigned char *) buf, | 940 | cciss_map_one(h->pdev, c, (unsigned char *) buf, |
948 | bufsize, DMA_FROM_DEVICE); | 941 | bufsize, DMA_FROM_DEVICE); |
949 | 942 | ||
950 | cp->waiting = &wait; | 943 | c->waiting = &wait; |
951 | 944 | enqueue_cmd_and_start_io(h, c); | |
952 | /* Put the request on the tail of the request queue */ | ||
953 | spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags); | ||
954 | addQ(&c->reqQ, cp); | ||
955 | c->Qdepth++; | ||
956 | start_io(c); | ||
957 | spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags); | ||
958 | |||
959 | wait_for_completion(&wait); | 945 | wait_for_completion(&wait); |
960 | 946 | ||
961 | /* undo the dma mapping */ | 947 | /* undo the dma mapping */ |
962 | cciss_unmap_one(c->pdev, cp, bufsize, DMA_FROM_DEVICE); | 948 | cciss_unmap_one(h->pdev, c, bufsize, DMA_FROM_DEVICE); |
963 | return(0); | 949 | return(0); |
964 | } | 950 | } |
965 | 951 | ||
966 | static void | 952 | static void |
967 | cciss_scsi_interpret_error(CommandList_struct *cp) | 953 | cciss_scsi_interpret_error(ctlr_info_t *h, CommandList_struct *c) |
968 | { | 954 | { |
969 | ErrorInfo_struct *ei; | 955 | ErrorInfo_struct *ei; |
970 | 956 | ||
971 | ei = cp->err_info; | 957 | ei = c->err_info; |
972 | switch(ei->CommandStatus) | 958 | switch(ei->CommandStatus) |
973 | { | 959 | { |
974 | case CMD_TARGET_STATUS: | 960 | case CMD_TARGET_STATUS: |
975 | printk(KERN_WARNING "cciss: cmd %p has " | 961 | dev_warn(&h->pdev->dev, |
976 | "completed with errors\n", cp); | 962 | "cmd %p has completed with errors\n", c); |
977 | printk(KERN_WARNING "cciss: cmd %p " | 963 | dev_warn(&h->pdev->dev, |
978 | "has SCSI Status = %x\n", | 964 | "cmd %p has SCSI Status = %x\n", |
979 | cp, | 965 | c, ei->ScsiStatus); |
980 | ei->ScsiStatus); | ||
981 | if (ei->ScsiStatus == 0) | 966 | if (ei->ScsiStatus == 0) |
982 | printk(KERN_WARNING | 967 | dev_warn(&h->pdev->dev, |
983 | "cciss:SCSI status is abnormally zero. " | 968 | "SCSI status is abnormally zero. " |
984 | "(probably indicates selection timeout " | 969 | "(probably indicates selection timeout " |
985 | "reported incorrectly due to a known " | 970 | "reported incorrectly due to a known " |
986 | "firmware bug, circa July, 2001.)\n"); | 971 | "firmware bug, circa July, 2001.)\n"); |
987 | break; | 972 | break; |
988 | case CMD_DATA_UNDERRUN: /* let mid layer handle it. */ | 973 | case CMD_DATA_UNDERRUN: /* let mid layer handle it. */ |
989 | printk("UNDERRUN\n"); | 974 | dev_info(&h->pdev->dev, "UNDERRUN\n"); |
990 | break; | 975 | break; |
991 | case CMD_DATA_OVERRUN: | 976 | case CMD_DATA_OVERRUN: |
992 | printk(KERN_WARNING "cciss: cp %p has" | 977 | dev_warn(&h->pdev->dev, "%p has" |
993 | " completed with data overrun " | 978 | " completed with data overrun " |
994 | "reported\n", cp); | 979 | "reported\n", c); |
995 | break; | 980 | break; |
996 | case CMD_INVALID: { | 981 | case CMD_INVALID: { |
997 | /* controller unfortunately reports SCSI passthru's */ | 982 | /* controller unfortunately reports SCSI passthru's */ |
998 | /* to non-existent targets as invalid commands. */ | 983 | /* to non-existent targets as invalid commands. */ |
999 | printk(KERN_WARNING "cciss: cp %p is " | 984 | dev_warn(&h->pdev->dev, |
1000 | "reported invalid (probably means " | 985 | "%p is reported invalid (probably means " |
1001 | "target device no longer present)\n", | 986 | "target device no longer present)\n", c); |
1002 | cp); | 987 | /* print_bytes((unsigned char *) c, sizeof(*c), 1, 0); |
1003 | /* print_bytes((unsigned char *) cp, sizeof(*cp), 1, 0); | 988 | print_cmd(c); */ |
1004 | print_cmd(cp); */ | ||
1005 | } | 989 | } |
1006 | break; | 990 | break; |
1007 | case CMD_PROTOCOL_ERR: | 991 | case CMD_PROTOCOL_ERR: |
1008 | printk(KERN_WARNING "cciss: cp %p has " | 992 | dev_warn(&h->pdev->dev, "%p has protocol error\n", c); |
1009 | "protocol error \n", cp); | ||
1010 | break; | 993 | break; |
1011 | case CMD_HARDWARE_ERR: | 994 | case CMD_HARDWARE_ERR: |
1012 | /* cmd->result = DID_ERROR << 16; */ | 995 | /* cmd->result = DID_ERROR << 16; */ |
1013 | printk(KERN_WARNING "cciss: cp %p had " | 996 | dev_warn(&h->pdev->dev, "%p had hardware error\n", c); |
1014 | " hardware error\n", cp); | ||
1015 | break; | 997 | break; |
1016 | case CMD_CONNECTION_LOST: | 998 | case CMD_CONNECTION_LOST: |
1017 | printk(KERN_WARNING "cciss: cp %p had " | 999 | dev_warn(&h->pdev->dev, "%p had connection lost\n", c); |
1018 | "connection lost\n", cp); | ||
1019 | break; | 1000 | break; |
1020 | case CMD_ABORTED: | 1001 | case CMD_ABORTED: |
1021 | printk(KERN_WARNING "cciss: cp %p was " | 1002 | dev_warn(&h->pdev->dev, "%p was aborted\n", c); |
1022 | "aborted\n", cp); | ||
1023 | break; | 1003 | break; |
1024 | case CMD_ABORT_FAILED: | 1004 | case CMD_ABORT_FAILED: |
1025 | printk(KERN_WARNING "cciss: cp %p reports " | 1005 | dev_warn(&h->pdev->dev, |
1026 | "abort failed\n", cp); | 1006 | "%p reports abort failed\n", c); |
1027 | break; | 1007 | break; |
1028 | case CMD_UNSOLICITED_ABORT: | 1008 | case CMD_UNSOLICITED_ABORT: |
1029 | printk(KERN_WARNING "cciss: cp %p aborted " | 1009 | dev_warn(&h->pdev->dev, |
1030 | "do to an unsolicited abort\n", cp); | 1010 | "%p aborted do to an unsolicited abort\n", c); |
1031 | break; | 1011 | break; |
1032 | case CMD_TIMEOUT: | 1012 | case CMD_TIMEOUT: |
1033 | printk(KERN_WARNING "cciss: cp %p timedout\n", | 1013 | dev_warn(&h->pdev->dev, "%p timedout\n", c); |
1034 | cp); | ||
1035 | break; | 1014 | break; |
1036 | default: | 1015 | default: |
1037 | printk(KERN_WARNING "cciss: cp %p returned " | 1016 | dev_warn(&h->pdev->dev, |
1038 | "unknown status %x\n", cp, | 1017 | "%p returned unknown status %x\n", |
1039 | ei->CommandStatus); | 1018 | c, ei->CommandStatus); |
1040 | } | 1019 | } |
1041 | } | 1020 | } |
1042 | 1021 | ||
1043 | static int | 1022 | static int |
1044 | cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, | 1023 | cciss_scsi_do_inquiry(ctlr_info_t *h, unsigned char *scsi3addr, |
1045 | unsigned char page, unsigned char *buf, | 1024 | unsigned char page, unsigned char *buf, |
1046 | unsigned char bufsize) | 1025 | unsigned char bufsize) |
1047 | { | 1026 | { |
1048 | int rc; | 1027 | int rc; |
1049 | CommandList_struct *cp; | 1028 | CommandList_struct *c; |
1050 | char cdb[6]; | 1029 | char cdb[6]; |
1051 | ErrorInfo_struct *ei; | 1030 | ErrorInfo_struct *ei; |
1052 | unsigned long flags; | 1031 | unsigned long flags; |
1053 | 1032 | ||
1054 | spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags); | 1033 | spin_lock_irqsave(&h->lock, flags); |
1055 | cp = scsi_cmd_alloc(c); | 1034 | c = scsi_cmd_alloc(h); |
1056 | spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags); | 1035 | spin_unlock_irqrestore(&h->lock, flags); |
1057 | 1036 | ||
1058 | if (cp == NULL) { /* trouble... */ | 1037 | if (c == NULL) { /* trouble... */ |
1059 | printk("cmd_alloc returned NULL!\n"); | 1038 | printk("cmd_alloc returned NULL!\n"); |
1060 | return -1; | 1039 | return -1; |
1061 | } | 1040 | } |
1062 | 1041 | ||
1063 | ei = cp->err_info; | 1042 | ei = c->err_info; |
1064 | 1043 | ||
1065 | cdb[0] = CISS_INQUIRY; | 1044 | cdb[0] = CISS_INQUIRY; |
1066 | cdb[1] = (page != 0); | 1045 | cdb[1] = (page != 0); |
@@ -1068,24 +1047,24 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, | |||
1068 | cdb[3] = 0; | 1047 | cdb[3] = 0; |
1069 | cdb[4] = bufsize; | 1048 | cdb[4] = bufsize; |
1070 | cdb[5] = 0; | 1049 | cdb[5] = 0; |
1071 | rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb, | 1050 | rc = cciss_scsi_do_simple_cmd(h, c, scsi3addr, cdb, |
1072 | 6, buf, bufsize, XFER_READ); | 1051 | 6, buf, bufsize, XFER_READ); |
1073 | 1052 | ||
1074 | if (rc != 0) return rc; /* something went wrong */ | 1053 | if (rc != 0) return rc; /* something went wrong */ |
1075 | 1054 | ||
1076 | if (ei->CommandStatus != 0 && | 1055 | if (ei->CommandStatus != 0 && |
1077 | ei->CommandStatus != CMD_DATA_UNDERRUN) { | 1056 | ei->CommandStatus != CMD_DATA_UNDERRUN) { |
1078 | cciss_scsi_interpret_error(cp); | 1057 | cciss_scsi_interpret_error(h, c); |
1079 | rc = -1; | 1058 | rc = -1; |
1080 | } | 1059 | } |
1081 | spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags); | 1060 | spin_lock_irqsave(&h->lock, flags); |
1082 | scsi_cmd_free(c, cp); | 1061 | scsi_cmd_free(h, c); |
1083 | spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags); | 1062 | spin_unlock_irqrestore(&h->lock, flags); |
1084 | return rc; | 1063 | return rc; |
1085 | } | 1064 | } |
1086 | 1065 | ||
1087 | /* Get the device id from inquiry page 0x83 */ | 1066 | /* Get the device id from inquiry page 0x83 */ |
1088 | static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr, | 1067 | static int cciss_scsi_get_device_id(ctlr_info_t *h, unsigned char *scsi3addr, |
1089 | unsigned char *device_id, int buflen) | 1068 | unsigned char *device_id, int buflen) |
1090 | { | 1069 | { |
1091 | int rc; | 1070 | int rc; |
@@ -1096,7 +1075,7 @@ static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr, | |||
1096 | buf = kzalloc(64, GFP_KERNEL); | 1075 | buf = kzalloc(64, GFP_KERNEL); |
1097 | if (!buf) | 1076 | if (!buf) |
1098 | return -1; | 1077 | return -1; |
1099 | rc = cciss_scsi_do_inquiry(c, scsi3addr, 0x83, buf, 64); | 1078 | rc = cciss_scsi_do_inquiry(h, scsi3addr, 0x83, buf, 64); |
1100 | if (rc == 0) | 1079 | if (rc == 0) |
1101 | memcpy(device_id, &buf[8], buflen); | 1080 | memcpy(device_id, &buf[8], buflen); |
1102 | kfree(buf); | 1081 | kfree(buf); |
@@ -1104,20 +1083,20 @@ static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr, | |||
1104 | } | 1083 | } |
1105 | 1084 | ||
1106 | static int | 1085 | static int |
1107 | cciss_scsi_do_report_phys_luns(ctlr_info_t *c, | 1086 | cciss_scsi_do_report_phys_luns(ctlr_info_t *h, |
1108 | ReportLunData_struct *buf, int bufsize) | 1087 | ReportLunData_struct *buf, int bufsize) |
1109 | { | 1088 | { |
1110 | int rc; | 1089 | int rc; |
1111 | CommandList_struct *cp; | 1090 | CommandList_struct *c; |
1112 | unsigned char cdb[12]; | 1091 | unsigned char cdb[12]; |
1113 | unsigned char scsi3addr[8]; | 1092 | unsigned char scsi3addr[8]; |
1114 | ErrorInfo_struct *ei; | 1093 | ErrorInfo_struct *ei; |
1115 | unsigned long flags; | 1094 | unsigned long flags; |
1116 | 1095 | ||
1117 | spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags); | 1096 | spin_lock_irqsave(&h->lock, flags); |
1118 | cp = scsi_cmd_alloc(c); | 1097 | c = scsi_cmd_alloc(h); |
1119 | spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags); | 1098 | spin_unlock_irqrestore(&h->lock, flags); |
1120 | if (cp == NULL) { /* trouble... */ | 1099 | if (c == NULL) { /* trouble... */ |
1121 | printk("cmd_alloc returned NULL!\n"); | 1100 | printk("cmd_alloc returned NULL!\n"); |
1122 | return -1; | 1101 | return -1; |
1123 | } | 1102 | } |
@@ -1136,27 +1115,27 @@ cciss_scsi_do_report_phys_luns(ctlr_info_t *c, | |||
1136 | cdb[10] = 0; | 1115 | cdb[10] = 0; |
1137 | cdb[11] = 0; | 1116 | cdb[11] = 0; |
1138 | 1117 | ||
1139 | rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, | 1118 | rc = cciss_scsi_do_simple_cmd(h, c, scsi3addr, |
1140 | cdb, 12, | 1119 | cdb, 12, |
1141 | (unsigned char *) buf, | 1120 | (unsigned char *) buf, |
1142 | bufsize, XFER_READ); | 1121 | bufsize, XFER_READ); |
1143 | 1122 | ||
1144 | if (rc != 0) return rc; /* something went wrong */ | 1123 | if (rc != 0) return rc; /* something went wrong */ |
1145 | 1124 | ||
1146 | ei = cp->err_info; | 1125 | ei = c->err_info; |
1147 | if (ei->CommandStatus != 0 && | 1126 | if (ei->CommandStatus != 0 && |
1148 | ei->CommandStatus != CMD_DATA_UNDERRUN) { | 1127 | ei->CommandStatus != CMD_DATA_UNDERRUN) { |
1149 | cciss_scsi_interpret_error(cp); | 1128 | cciss_scsi_interpret_error(h, c); |
1150 | rc = -1; | 1129 | rc = -1; |
1151 | } | 1130 | } |
1152 | spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags); | 1131 | spin_lock_irqsave(&h->lock, flags); |
1153 | scsi_cmd_free(c, cp); | 1132 | scsi_cmd_free(h, c); |
1154 | spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags); | 1133 | spin_unlock_irqrestore(&h->lock, flags); |
1155 | return rc; | 1134 | return rc; |
1156 | } | 1135 | } |
1157 | 1136 | ||
1158 | static void | 1137 | static void |
1159 | cciss_update_non_disk_devices(int cntl_num, int hostno) | 1138 | cciss_update_non_disk_devices(ctlr_info_t *h, int hostno) |
1160 | { | 1139 | { |
1161 | /* the idea here is we could get notified from /proc | 1140 | /* the idea here is we could get notified from /proc |
1162 | that some devices have changed, so we do a report | 1141 | that some devices have changed, so we do a report |
@@ -1189,7 +1168,6 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1189 | ReportLunData_struct *ld_buff; | 1168 | ReportLunData_struct *ld_buff; |
1190 | unsigned char *inq_buff; | 1169 | unsigned char *inq_buff; |
1191 | unsigned char scsi3addr[8]; | 1170 | unsigned char scsi3addr[8]; |
1192 | ctlr_info_t *c; | ||
1193 | __u32 num_luns=0; | 1171 | __u32 num_luns=0; |
1194 | unsigned char *ch; | 1172 | unsigned char *ch; |
1195 | struct cciss_scsi_dev_t *currentsd, *this_device; | 1173 | struct cciss_scsi_dev_t *currentsd, *this_device; |
@@ -1197,7 +1175,6 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1197 | int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8; | 1175 | int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8; |
1198 | int i; | 1176 | int i; |
1199 | 1177 | ||
1200 | c = (ctlr_info_t *) hba[cntl_num]; | ||
1201 | ld_buff = kzalloc(reportlunsize, GFP_KERNEL); | 1178 | ld_buff = kzalloc(reportlunsize, GFP_KERNEL); |
1202 | inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); | 1179 | inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); |
1203 | currentsd = kzalloc(sizeof(*currentsd) * | 1180 | currentsd = kzalloc(sizeof(*currentsd) * |
@@ -1207,7 +1184,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1207 | goto out; | 1184 | goto out; |
1208 | } | 1185 | } |
1209 | this_device = ¤tsd[CCISS_MAX_SCSI_DEVS_PER_HBA]; | 1186 | this_device = ¤tsd[CCISS_MAX_SCSI_DEVS_PER_HBA]; |
1210 | if (cciss_scsi_do_report_phys_luns(c, ld_buff, reportlunsize) == 0) { | 1187 | if (cciss_scsi_do_report_phys_luns(h, ld_buff, reportlunsize) == 0) { |
1211 | ch = &ld_buff->LUNListLength[0]; | 1188 | ch = &ld_buff->LUNListLength[0]; |
1212 | num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8; | 1189 | num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8; |
1213 | if (num_luns > CISS_MAX_PHYS_LUN) { | 1190 | if (num_luns > CISS_MAX_PHYS_LUN) { |
@@ -1231,7 +1208,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1231 | memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE); | 1208 | memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE); |
1232 | memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8); | 1209 | memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8); |
1233 | 1210 | ||
1234 | if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, 0, inq_buff, | 1211 | if (cciss_scsi_do_inquiry(h, scsi3addr, 0, inq_buff, |
1235 | (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) | 1212 | (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) |
1236 | /* Inquiry failed (msg printed already) */ | 1213 | /* Inquiry failed (msg printed already) */ |
1237 | continue; /* so we will skip this device. */ | 1214 | continue; /* so we will skip this device. */ |
@@ -1249,7 +1226,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1249 | sizeof(this_device->revision)); | 1226 | sizeof(this_device->revision)); |
1250 | memset(this_device->device_id, 0, | 1227 | memset(this_device->device_id, 0, |
1251 | sizeof(this_device->device_id)); | 1228 | sizeof(this_device->device_id)); |
1252 | cciss_scsi_get_device_id(hba[cntl_num], scsi3addr, | 1229 | cciss_scsi_get_device_id(h, scsi3addr, |
1253 | this_device->device_id, sizeof(this_device->device_id)); | 1230 | this_device->device_id, sizeof(this_device->device_id)); |
1254 | 1231 | ||
1255 | switch (this_device->devtype) | 1232 | switch (this_device->devtype) |
@@ -1276,7 +1253,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1276 | case 0x08: /* medium changer */ | 1253 | case 0x08: /* medium changer */ |
1277 | if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) { | 1254 | if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) { |
1278 | printk(KERN_INFO "cciss%d: %s ignored, " | 1255 | printk(KERN_INFO "cciss%d: %s ignored, " |
1279 | "too many devices.\n", cntl_num, | 1256 | "too many devices.\n", h->ctlr, |
1280 | scsi_device_type(this_device->devtype)); | 1257 | scsi_device_type(this_device->devtype)); |
1281 | break; | 1258 | break; |
1282 | } | 1259 | } |
@@ -1288,7 +1265,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1288 | } | 1265 | } |
1289 | } | 1266 | } |
1290 | 1267 | ||
1291 | adjust_cciss_scsi_table(cntl_num, hostno, currentsd, ncurrent); | 1268 | adjust_cciss_scsi_table(h, hostno, currentsd, ncurrent); |
1292 | out: | 1269 | out: |
1293 | kfree(inq_buff); | 1270 | kfree(inq_buff); |
1294 | kfree(ld_buff); | 1271 | kfree(ld_buff); |
@@ -1307,12 +1284,12 @@ is_keyword(char *ptr, int len, char *verb) // Thanks to ncr53c8xx.c | |||
1307 | } | 1284 | } |
1308 | 1285 | ||
1309 | static int | 1286 | static int |
1310 | cciss_scsi_user_command(int ctlr, int hostno, char *buffer, int length) | 1287 | cciss_scsi_user_command(ctlr_info_t *h, int hostno, char *buffer, int length) |
1311 | { | 1288 | { |
1312 | int arg_len; | 1289 | int arg_len; |
1313 | 1290 | ||
1314 | if ((arg_len = is_keyword(buffer, length, "rescan")) != 0) | 1291 | if ((arg_len = is_keyword(buffer, length, "rescan")) != 0) |
1315 | cciss_update_non_disk_devices(ctlr, hostno); | 1292 | cciss_update_non_disk_devices(h, hostno); |
1316 | else | 1293 | else |
1317 | return -EINVAL; | 1294 | return -EINVAL; |
1318 | return length; | 1295 | return length; |
@@ -1329,20 +1306,16 @@ cciss_scsi_proc_info(struct Scsi_Host *sh, | |||
1329 | { | 1306 | { |
1330 | 1307 | ||
1331 | int buflen, datalen; | 1308 | int buflen, datalen; |
1332 | ctlr_info_t *ci; | 1309 | ctlr_info_t *h; |
1333 | int i; | 1310 | int i; |
1334 | int cntl_num; | ||
1335 | |||
1336 | 1311 | ||
1337 | ci = (ctlr_info_t *) sh->hostdata[0]; | 1312 | h = (ctlr_info_t *) sh->hostdata[0]; |
1338 | if (ci == NULL) /* This really shouldn't ever happen. */ | 1313 | if (h == NULL) /* This really shouldn't ever happen. */ |
1339 | return -EINVAL; | 1314 | return -EINVAL; |
1340 | 1315 | ||
1341 | cntl_num = ci->ctlr; /* Get our index into the hba[] array */ | ||
1342 | |||
1343 | if (func == 0) { /* User is reading from /proc/scsi/ciss*?/?* */ | 1316 | if (func == 0) { /* User is reading from /proc/scsi/ciss*?/?* */ |
1344 | buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n", | 1317 | buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n", |
1345 | cntl_num, sh->host_no); | 1318 | h->ctlr, sh->host_no); |
1346 | 1319 | ||
1347 | /* this information is needed by apps to know which cciss | 1320 | /* this information is needed by apps to know which cciss |
1348 | device corresponds to which scsi host number without | 1321 | device corresponds to which scsi host number without |
@@ -1352,8 +1325,9 @@ cciss_scsi_proc_info(struct Scsi_Host *sh, | |||
1352 | this info is for an app to be able to use to know how to | 1325 | this info is for an app to be able to use to know how to |
1353 | get them back in sync. */ | 1326 | get them back in sync. */ |
1354 | 1327 | ||
1355 | for (i=0;i<ccissscsi[cntl_num].ndevices;i++) { | 1328 | for (i = 0; i < ccissscsi[h->ctlr].ndevices; i++) { |
1356 | struct cciss_scsi_dev_t *sd = &ccissscsi[cntl_num].dev[i]; | 1329 | struct cciss_scsi_dev_t *sd = |
1330 | &ccissscsi[h->ctlr].dev[i]; | ||
1357 | buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d " | 1331 | buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d " |
1358 | "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", | 1332 | "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", |
1359 | sh->host_no, sd->bus, sd->target, sd->lun, | 1333 | sh->host_no, sd->bus, sd->target, sd->lun, |
@@ -1371,15 +1345,15 @@ cciss_scsi_proc_info(struct Scsi_Host *sh, | |||
1371 | *start = buffer + offset; | 1345 | *start = buffer + offset; |
1372 | return(datalen); | 1346 | return(datalen); |
1373 | } else /* User is writing to /proc/scsi/cciss*?/?* ... */ | 1347 | } else /* User is writing to /proc/scsi/cciss*?/?* ... */ |
1374 | return cciss_scsi_user_command(cntl_num, sh->host_no, | 1348 | return cciss_scsi_user_command(h, sh->host_no, |
1375 | buffer, length); | 1349 | buffer, length); |
1376 | } | 1350 | } |
1377 | 1351 | ||
1378 | /* cciss_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci | 1352 | /* cciss_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci |
1379 | dma mapping and fills in the scatter gather entries of the | 1353 | dma mapping and fills in the scatter gather entries of the |
1380 | cciss command, cp. */ | 1354 | cciss command, c. */ |
1381 | 1355 | ||
1382 | static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp, | 1356 | static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c, |
1383 | struct scsi_cmnd *cmd) | 1357 | struct scsi_cmnd *cmd) |
1384 | { | 1358 | { |
1385 | unsigned int len; | 1359 | unsigned int len; |
@@ -1393,7 +1367,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp, | |||
1393 | 1367 | ||
1394 | chained = 0; | 1368 | chained = 0; |
1395 | sg_index = 0; | 1369 | sg_index = 0; |
1396 | curr_sg = cp->SG; | 1370 | curr_sg = c->SG; |
1397 | request_nsgs = scsi_dma_map(cmd); | 1371 | request_nsgs = scsi_dma_map(cmd); |
1398 | if (request_nsgs) { | 1372 | if (request_nsgs) { |
1399 | scsi_for_each_sg(cmd, sg, request_nsgs, i) { | 1373 | scsi_for_each_sg(cmd, sg, request_nsgs, i) { |
@@ -1401,7 +1375,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp, | |||
1401 | !chained && request_nsgs - i > 1) { | 1375 | !chained && request_nsgs - i > 1) { |
1402 | chained = 1; | 1376 | chained = 1; |
1403 | sg_index = 0; | 1377 | sg_index = 0; |
1404 | curr_sg = sa->cmd_sg_list[cp->cmdindex]; | 1378 | curr_sg = sa->cmd_sg_list[c->cmdindex]; |
1405 | } | 1379 | } |
1406 | addr64 = (__u64) sg_dma_address(sg); | 1380 | addr64 = (__u64) sg_dma_address(sg); |
1407 | len = sg_dma_len(sg); | 1381 | len = sg_dma_len(sg); |
@@ -1414,19 +1388,19 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp, | |||
1414 | ++sg_index; | 1388 | ++sg_index; |
1415 | } | 1389 | } |
1416 | if (chained) | 1390 | if (chained) |
1417 | cciss_map_sg_chain_block(h, cp, | 1391 | cciss_map_sg_chain_block(h, c, |
1418 | sa->cmd_sg_list[cp->cmdindex], | 1392 | sa->cmd_sg_list[c->cmdindex], |
1419 | (request_nsgs - (h->max_cmd_sgentries - 1)) * | 1393 | (request_nsgs - (h->max_cmd_sgentries - 1)) * |
1420 | sizeof(SGDescriptor_struct)); | 1394 | sizeof(SGDescriptor_struct)); |
1421 | } | 1395 | } |
1422 | /* track how many SG entries we are using */ | 1396 | /* track how many SG entries we are using */ |
1423 | if (request_nsgs > h->maxSG) | 1397 | if (request_nsgs > h->maxSG) |
1424 | h->maxSG = request_nsgs; | 1398 | h->maxSG = request_nsgs; |
1425 | cp->Header.SGTotal = (__u8) request_nsgs + chained; | 1399 | c->Header.SGTotal = (__u8) request_nsgs + chained; |
1426 | if (request_nsgs > h->max_cmd_sgentries) | 1400 | if (request_nsgs > h->max_cmd_sgentries) |
1427 | cp->Header.SGList = h->max_cmd_sgentries; | 1401 | c->Header.SGList = h->max_cmd_sgentries; |
1428 | else | 1402 | else |
1429 | cp->Header.SGList = cp->Header.SGTotal; | 1403 | c->Header.SGList = c->Header.SGTotal; |
1430 | return; | 1404 | return; |
1431 | } | 1405 | } |
1432 | 1406 | ||
@@ -1434,18 +1408,17 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp, | |||
1434 | static int | 1408 | static int |
1435 | cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | 1409 | cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) |
1436 | { | 1410 | { |
1437 | ctlr_info_t *c; | 1411 | ctlr_info_t *h; |
1438 | int ctlr, rc; | 1412 | int rc; |
1439 | unsigned char scsi3addr[8]; | 1413 | unsigned char scsi3addr[8]; |
1440 | CommandList_struct *cp; | 1414 | CommandList_struct *c; |
1441 | unsigned long flags; | 1415 | unsigned long flags; |
1442 | 1416 | ||
1443 | // Get the ptr to our adapter structure (hba[i]) out of cmd->host. | 1417 | // Get the ptr to our adapter structure (hba[i]) out of cmd->host. |
1444 | // We violate cmd->host privacy here. (Is there another way?) | 1418 | // We violate cmd->host privacy here. (Is there another way?) |
1445 | c = (ctlr_info_t *) cmd->device->host->hostdata[0]; | 1419 | h = (ctlr_info_t *) cmd->device->host->hostdata[0]; |
1446 | ctlr = c->ctlr; | ||
1447 | 1420 | ||
1448 | rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id, | 1421 | rc = lookup_scsi3addr(h, cmd->device->channel, cmd->device->id, |
1449 | cmd->device->lun, scsi3addr); | 1422 | cmd->device->lun, scsi3addr); |
1450 | if (rc != 0) { | 1423 | if (rc != 0) { |
1451 | /* the scsi nexus does not match any that we presented... */ | 1424 | /* the scsi nexus does not match any that we presented... */ |
@@ -1457,19 +1430,14 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd | |||
1457 | return 0; | 1430 | return 0; |
1458 | } | 1431 | } |
1459 | 1432 | ||
1460 | /* printk("cciss_queue_command, p=%p, cmd=0x%02x, c%db%dt%dl%d\n", | ||
1461 | cmd, cmd->cmnd[0], ctlr, cmd->channel, cmd->target, cmd->lun);*/ | ||
1462 | // printk("q:%p:c%db%dt%dl%d ", cmd, ctlr, cmd->channel, | ||
1463 | // cmd->target, cmd->lun); | ||
1464 | |||
1465 | /* Ok, we have a reasonable scsi nexus, so send the cmd down, and | 1433 | /* Ok, we have a reasonable scsi nexus, so send the cmd down, and |
1466 | see what the device thinks of it. */ | 1434 | see what the device thinks of it. */ |
1467 | 1435 | ||
1468 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | 1436 | spin_lock_irqsave(&h->lock, flags); |
1469 | cp = scsi_cmd_alloc(c); | 1437 | c = scsi_cmd_alloc(h); |
1470 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1438 | spin_unlock_irqrestore(&h->lock, flags); |
1471 | if (cp == NULL) { /* trouble... */ | 1439 | if (c == NULL) { /* trouble... */ |
1472 | printk("scsi_cmd_alloc returned NULL!\n"); | 1440 | dev_warn(&h->pdev->dev, "scsi_cmd_alloc returned NULL!\n"); |
1473 | /* FIXME: next 3 lines are -> BAD! <- */ | 1441 | /* FIXME: next 3 lines are -> BAD! <- */ |
1474 | cmd->result = DID_NO_CONNECT << 16; | 1442 | cmd->result = DID_NO_CONNECT << 16; |
1475 | done(cmd); | 1443 | done(cmd); |
@@ -1480,35 +1448,41 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd | |||
1480 | 1448 | ||
1481 | cmd->scsi_done = done; // save this for use by completion code | 1449 | cmd->scsi_done = done; // save this for use by completion code |
1482 | 1450 | ||
1483 | // save cp in case we have to abort it | 1451 | /* save c in case we have to abort it */ |
1484 | cmd->host_scribble = (unsigned char *) cp; | 1452 | cmd->host_scribble = (unsigned char *) c; |
1485 | 1453 | ||
1486 | cp->cmd_type = CMD_SCSI; | 1454 | c->cmd_type = CMD_SCSI; |
1487 | cp->scsi_cmd = cmd; | 1455 | c->scsi_cmd = cmd; |
1488 | cp->Header.ReplyQueue = 0; // unused in simple mode | 1456 | c->Header.ReplyQueue = 0; /* unused in simple mode */ |
1489 | memcpy(&cp->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8); | 1457 | memcpy(&c->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8); |
1490 | cp->Header.Tag.lower = cp->busaddr; // Use k. address of cmd as tag | 1458 | c->Header.Tag.lower = c->busaddr; /* Use k. address of cmd as tag */ |
1491 | 1459 | ||
1492 | // Fill in the request block... | 1460 | // Fill in the request block... |
1493 | 1461 | ||
1494 | cp->Request.Timeout = 0; | 1462 | c->Request.Timeout = 0; |
1495 | memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB)); | 1463 | memset(c->Request.CDB, 0, sizeof(c->Request.CDB)); |
1496 | BUG_ON(cmd->cmd_len > sizeof(cp->Request.CDB)); | 1464 | BUG_ON(cmd->cmd_len > sizeof(c->Request.CDB)); |
1497 | cp->Request.CDBLen = cmd->cmd_len; | 1465 | c->Request.CDBLen = cmd->cmd_len; |
1498 | memcpy(cp->Request.CDB, cmd->cmnd, cmd->cmd_len); | 1466 | memcpy(c->Request.CDB, cmd->cmnd, cmd->cmd_len); |
1499 | cp->Request.Type.Type = TYPE_CMD; | 1467 | c->Request.Type.Type = TYPE_CMD; |
1500 | cp->Request.Type.Attribute = ATTR_SIMPLE; | 1468 | c->Request.Type.Attribute = ATTR_SIMPLE; |
1501 | switch(cmd->sc_data_direction) | 1469 | switch(cmd->sc_data_direction) |
1502 | { | 1470 | { |
1503 | case DMA_TO_DEVICE: cp->Request.Type.Direction = XFER_WRITE; break; | 1471 | case DMA_TO_DEVICE: |
1504 | case DMA_FROM_DEVICE: cp->Request.Type.Direction = XFER_READ; break; | 1472 | c->Request.Type.Direction = XFER_WRITE; |
1505 | case DMA_NONE: cp->Request.Type.Direction = XFER_NONE; break; | 1473 | break; |
1474 | case DMA_FROM_DEVICE: | ||
1475 | c->Request.Type.Direction = XFER_READ; | ||
1476 | break; | ||
1477 | case DMA_NONE: | ||
1478 | c->Request.Type.Direction = XFER_NONE; | ||
1479 | break; | ||
1506 | case DMA_BIDIRECTIONAL: | 1480 | case DMA_BIDIRECTIONAL: |
1507 | // This can happen if a buggy application does a scsi passthru | 1481 | // This can happen if a buggy application does a scsi passthru |
1508 | // and sets both inlen and outlen to non-zero. ( see | 1482 | // and sets both inlen and outlen to non-zero. ( see |
1509 | // ../scsi/scsi_ioctl.c:scsi_ioctl_send_command() ) | 1483 | // ../scsi/scsi_ioctl.c:scsi_ioctl_send_command() ) |
1510 | 1484 | ||
1511 | cp->Request.Type.Direction = XFER_RSVD; | 1485 | c->Request.Type.Direction = XFER_RSVD; |
1512 | // This is technically wrong, and cciss controllers should | 1486 | // This is technically wrong, and cciss controllers should |
1513 | // reject it with CMD_INVALID, which is the most correct | 1487 | // reject it with CMD_INVALID, which is the most correct |
1514 | // response, but non-fibre backends appear to let it | 1488 | // response, but non-fibre backends appear to let it |
@@ -1519,27 +1493,18 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd | |||
1519 | break; | 1493 | break; |
1520 | 1494 | ||
1521 | default: | 1495 | default: |
1522 | printk("cciss: unknown data direction: %d\n", | 1496 | dev_warn(&h->pdev->dev, "unknown data direction: %d\n", |
1523 | cmd->sc_data_direction); | 1497 | cmd->sc_data_direction); |
1524 | BUG(); | 1498 | BUG(); |
1525 | break; | 1499 | break; |
1526 | } | 1500 | } |
1527 | cciss_scatter_gather(c, cp, cmd); | 1501 | cciss_scatter_gather(h, c, cmd); |
1528 | 1502 | enqueue_cmd_and_start_io(h, c); | |
1529 | /* Put the request on the tail of the request queue */ | ||
1530 | |||
1531 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | ||
1532 | addQ(&c->reqQ, cp); | ||
1533 | c->Qdepth++; | ||
1534 | start_io(c); | ||
1535 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | ||
1536 | |||
1537 | /* the cmd'll come back via intr handler in complete_scsi_command() */ | 1503 | /* the cmd'll come back via intr handler in complete_scsi_command() */ |
1538 | return 0; | 1504 | return 0; |
1539 | } | 1505 | } |
1540 | 1506 | ||
1541 | static void | 1507 | static void cciss_unregister_scsi(ctlr_info_t *h) |
1542 | cciss_unregister_scsi(int ctlr) | ||
1543 | { | 1508 | { |
1544 | struct cciss_scsi_adapter_data_t *sa; | 1509 | struct cciss_scsi_adapter_data_t *sa; |
1545 | struct cciss_scsi_cmd_stack_t *stk; | 1510 | struct cciss_scsi_cmd_stack_t *stk; |
@@ -1547,59 +1512,58 @@ cciss_unregister_scsi(int ctlr) | |||
1547 | 1512 | ||
1548 | /* we are being forcibly unloaded, and may not refuse. */ | 1513 | /* we are being forcibly unloaded, and may not refuse. */ |
1549 | 1514 | ||
1550 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | 1515 | spin_lock_irqsave(&h->lock, flags); |
1551 | sa = hba[ctlr]->scsi_ctlr; | 1516 | sa = h->scsi_ctlr; |
1552 | stk = &sa->cmd_stack; | 1517 | stk = &sa->cmd_stack; |
1553 | 1518 | ||
1554 | /* if we weren't ever actually registered, don't unregister */ | 1519 | /* if we weren't ever actually registered, don't unregister */ |
1555 | if (sa->registered) { | 1520 | if (sa->registered) { |
1556 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1521 | spin_unlock_irqrestore(&h->lock, flags); |
1557 | scsi_remove_host(sa->scsi_host); | 1522 | scsi_remove_host(sa->scsi_host); |
1558 | scsi_host_put(sa->scsi_host); | 1523 | scsi_host_put(sa->scsi_host); |
1559 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | 1524 | spin_lock_irqsave(&h->lock, flags); |
1560 | } | 1525 | } |
1561 | 1526 | ||
1562 | /* set scsi_host to NULL so our detect routine will | 1527 | /* set scsi_host to NULL so our detect routine will |
1563 | find us on register */ | 1528 | find us on register */ |
1564 | sa->scsi_host = NULL; | 1529 | sa->scsi_host = NULL; |
1565 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1530 | spin_unlock_irqrestore(&h->lock, flags); |
1566 | scsi_cmd_stack_free(ctlr); | 1531 | scsi_cmd_stack_free(h); |
1567 | kfree(sa); | 1532 | kfree(sa); |
1568 | } | 1533 | } |
1569 | 1534 | ||
1570 | static int | 1535 | static int cciss_engage_scsi(ctlr_info_t *h) |
1571 | cciss_engage_scsi(int ctlr) | ||
1572 | { | 1536 | { |
1573 | struct cciss_scsi_adapter_data_t *sa; | 1537 | struct cciss_scsi_adapter_data_t *sa; |
1574 | struct cciss_scsi_cmd_stack_t *stk; | 1538 | struct cciss_scsi_cmd_stack_t *stk; |
1575 | unsigned long flags; | 1539 | unsigned long flags; |
1576 | 1540 | ||
1577 | spin_lock_irqsave(CCISS_LOCK(ctlr), flags); | 1541 | spin_lock_irqsave(&h->lock, flags); |
1578 | sa = hba[ctlr]->scsi_ctlr; | 1542 | sa = h->scsi_ctlr; |
1579 | stk = &sa->cmd_stack; | 1543 | stk = &sa->cmd_stack; |
1580 | 1544 | ||
1581 | if (sa->registered) { | 1545 | if (sa->registered) { |
1582 | printk("cciss%d: SCSI subsystem already engaged.\n", ctlr); | 1546 | dev_info(&h->pdev->dev, "SCSI subsystem already engaged.\n"); |
1583 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1547 | spin_unlock_irqrestore(&h->lock, flags); |
1584 | return -ENXIO; | 1548 | return -ENXIO; |
1585 | } | 1549 | } |
1586 | sa->registered = 1; | 1550 | sa->registered = 1; |
1587 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1551 | spin_unlock_irqrestore(&h->lock, flags); |
1588 | cciss_update_non_disk_devices(ctlr, -1); | 1552 | cciss_update_non_disk_devices(h, -1); |
1589 | cciss_scsi_detect(ctlr); | 1553 | cciss_scsi_detect(h); |
1590 | return 0; | 1554 | return 0; |
1591 | } | 1555 | } |
1592 | 1556 | ||
1593 | static void | 1557 | static void |
1594 | cciss_seq_tape_report(struct seq_file *seq, int ctlr) | 1558 | cciss_seq_tape_report(struct seq_file *seq, ctlr_info_t *h) |
1595 | { | 1559 | { |
1596 | unsigned long flags; | 1560 | unsigned long flags; |
1597 | 1561 | ||
1598 | CPQ_TAPE_LOCK(ctlr, flags); | 1562 | CPQ_TAPE_LOCK(h, flags); |
1599 | seq_printf(seq, | 1563 | seq_printf(seq, |
1600 | "Sequential access devices: %d\n\n", | 1564 | "Sequential access devices: %d\n\n", |
1601 | ccissscsi[ctlr].ndevices); | 1565 | ccissscsi[h->ctlr].ndevices); |
1602 | CPQ_TAPE_UNLOCK(ctlr, flags); | 1566 | CPQ_TAPE_UNLOCK(h, flags); |
1603 | } | 1567 | } |
1604 | 1568 | ||
1605 | static int wait_for_device_to_become_ready(ctlr_info_t *h, | 1569 | static int wait_for_device_to_become_ready(ctlr_info_t *h, |
@@ -1610,10 +1574,10 @@ static int wait_for_device_to_become_ready(ctlr_info_t *h, | |||
1610 | int waittime = HZ; | 1574 | int waittime = HZ; |
1611 | CommandList_struct *c; | 1575 | CommandList_struct *c; |
1612 | 1576 | ||
1613 | c = cmd_alloc(h, 1); | 1577 | c = cmd_alloc(h); |
1614 | if (!c) { | 1578 | if (!c) { |
1615 | printk(KERN_WARNING "cciss%d: out of memory in " | 1579 | dev_warn(&h->pdev->dev, "out of memory in " |
1616 | "wait_for_device_to_become_ready.\n", h->ctlr); | 1580 | "wait_for_device_to_become_ready.\n"); |
1617 | return IO_ERROR; | 1581 | return IO_ERROR; |
1618 | } | 1582 | } |
1619 | 1583 | ||
@@ -1631,7 +1595,7 @@ static int wait_for_device_to_become_ready(ctlr_info_t *h, | |||
1631 | waittime = waittime * 2; | 1595 | waittime = waittime * 2; |
1632 | 1596 | ||
1633 | /* Send the Test Unit Ready */ | 1597 | /* Send the Test Unit Ready */ |
1634 | rc = fill_cmd(c, TEST_UNIT_READY, h->ctlr, NULL, 0, 0, | 1598 | rc = fill_cmd(h, c, TEST_UNIT_READY, NULL, 0, 0, |
1635 | lunaddr, TYPE_CMD); | 1599 | lunaddr, TYPE_CMD); |
1636 | if (rc == 0) | 1600 | if (rc == 0) |
1637 | rc = sendcmd_withirq_core(h, c, 0); | 1601 | rc = sendcmd_withirq_core(h, c, 0); |
@@ -1657,18 +1621,18 @@ static int wait_for_device_to_become_ready(ctlr_info_t *h, | |||
1657 | } | 1621 | } |
1658 | } | 1622 | } |
1659 | retry_tur: | 1623 | retry_tur: |
1660 | printk(KERN_WARNING "cciss%d: Waiting %d secs " | 1624 | dev_warn(&h->pdev->dev, "Waiting %d secs " |
1661 | "for device to become ready.\n", | 1625 | "for device to become ready.\n", |
1662 | h->ctlr, waittime / HZ); | 1626 | waittime / HZ); |
1663 | rc = 1; /* device not ready. */ | 1627 | rc = 1; /* device not ready. */ |
1664 | } | 1628 | } |
1665 | 1629 | ||
1666 | if (rc) | 1630 | if (rc) |
1667 | printk("cciss%d: giving up on device.\n", h->ctlr); | 1631 | dev_warn(&h->pdev->dev, "giving up on device.\n"); |
1668 | else | 1632 | else |
1669 | printk(KERN_WARNING "cciss%d: device is ready.\n", h->ctlr); | 1633 | dev_warn(&h->pdev->dev, "device is ready.\n"); |
1670 | 1634 | ||
1671 | cmd_free(h, c, 1); | 1635 | cmd_free(h, c); |
1672 | return rc; | 1636 | return rc; |
1673 | } | 1637 | } |
1674 | 1638 | ||
@@ -1688,26 +1652,24 @@ static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd) | |||
1688 | int rc; | 1652 | int rc; |
1689 | CommandList_struct *cmd_in_trouble; | 1653 | CommandList_struct *cmd_in_trouble; |
1690 | unsigned char lunaddr[8]; | 1654 | unsigned char lunaddr[8]; |
1691 | ctlr_info_t *c; | 1655 | ctlr_info_t *h; |
1692 | int ctlr; | ||
1693 | 1656 | ||
1694 | /* find the controller to which the command to be aborted was sent */ | 1657 | /* find the controller to which the command to be aborted was sent */ |
1695 | c = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; | 1658 | h = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; |
1696 | if (c == NULL) /* paranoia */ | 1659 | if (h == NULL) /* paranoia */ |
1697 | return FAILED; | 1660 | return FAILED; |
1698 | ctlr = c->ctlr; | 1661 | dev_warn(&h->pdev->dev, "resetting tape drive or medium changer.\n"); |
1699 | printk(KERN_WARNING "cciss%d: resetting tape drive or medium changer.\n", ctlr); | ||
1700 | /* find the command that's giving us trouble */ | 1662 | /* find the command that's giving us trouble */ |
1701 | cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble; | 1663 | cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble; |
1702 | if (cmd_in_trouble == NULL) /* paranoia */ | 1664 | if (cmd_in_trouble == NULL) /* paranoia */ |
1703 | return FAILED; | 1665 | return FAILED; |
1704 | memcpy(lunaddr, &cmd_in_trouble->Header.LUN.LunAddrBytes[0], 8); | 1666 | memcpy(lunaddr, &cmd_in_trouble->Header.LUN.LunAddrBytes[0], 8); |
1705 | /* send a reset to the SCSI LUN which the command was sent to */ | 1667 | /* send a reset to the SCSI LUN which the command was sent to */ |
1706 | rc = sendcmd_withirq(CCISS_RESET_MSG, ctlr, NULL, 0, 0, lunaddr, | 1668 | rc = sendcmd_withirq(h, CCISS_RESET_MSG, NULL, 0, 0, lunaddr, |
1707 | TYPE_MSG); | 1669 | TYPE_MSG); |
1708 | if (rc == 0 && wait_for_device_to_become_ready(c, lunaddr) == 0) | 1670 | if (rc == 0 && wait_for_device_to_become_ready(h, lunaddr) == 0) |
1709 | return SUCCESS; | 1671 | return SUCCESS; |
1710 | printk(KERN_WARNING "cciss%d: resetting device failed.\n", ctlr); | 1672 | dev_warn(&h->pdev->dev, "resetting device failed.\n"); |
1711 | return FAILED; | 1673 | return FAILED; |
1712 | } | 1674 | } |
1713 | 1675 | ||
@@ -1716,22 +1678,20 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd) | |||
1716 | int rc; | 1678 | int rc; |
1717 | CommandList_struct *cmd_to_abort; | 1679 | CommandList_struct *cmd_to_abort; |
1718 | unsigned char lunaddr[8]; | 1680 | unsigned char lunaddr[8]; |
1719 | ctlr_info_t *c; | 1681 | ctlr_info_t *h; |
1720 | int ctlr; | ||
1721 | 1682 | ||
1722 | /* find the controller to which the command to be aborted was sent */ | 1683 | /* find the controller to which the command to be aborted was sent */ |
1723 | c = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; | 1684 | h = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; |
1724 | if (c == NULL) /* paranoia */ | 1685 | if (h == NULL) /* paranoia */ |
1725 | return FAILED; | 1686 | return FAILED; |
1726 | ctlr = c->ctlr; | 1687 | dev_warn(&h->pdev->dev, "aborting tardy SCSI cmd\n"); |
1727 | printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", ctlr); | ||
1728 | 1688 | ||
1729 | /* find the command to be aborted */ | 1689 | /* find the command to be aborted */ |
1730 | cmd_to_abort = (CommandList_struct *) scsicmd->host_scribble; | 1690 | cmd_to_abort = (CommandList_struct *) scsicmd->host_scribble; |
1731 | if (cmd_to_abort == NULL) /* paranoia */ | 1691 | if (cmd_to_abort == NULL) /* paranoia */ |
1732 | return FAILED; | 1692 | return FAILED; |
1733 | memcpy(lunaddr, &cmd_to_abort->Header.LUN.LunAddrBytes[0], 8); | 1693 | memcpy(lunaddr, &cmd_to_abort->Header.LUN.LunAddrBytes[0], 8); |
1734 | rc = sendcmd_withirq(CCISS_ABORT_MSG, ctlr, &cmd_to_abort->Header.Tag, | 1694 | rc = sendcmd_withirq(h, CCISS_ABORT_MSG, &cmd_to_abort->Header.Tag, |
1735 | 0, 0, lunaddr, TYPE_MSG); | 1695 | 0, 0, lunaddr, TYPE_MSG); |
1736 | if (rc == 0) | 1696 | if (rc == 0) |
1737 | return SUCCESS; | 1697 | return SUCCESS; |
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index abb4ec6690fc..d53b0291c44b 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/seq_file.h> | 35 | #include <linux/seq_file.h> |
36 | #include <linux/init.h> | 36 | #include <linux/init.h> |
37 | #include <linux/hdreg.h> | 37 | #include <linux/hdreg.h> |
38 | #include <linux/smp_lock.h> | ||
38 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
39 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
40 | #include <linux/genhd.h> | 41 | #include <linux/genhd.h> |
@@ -157,7 +158,7 @@ static int sendcmd( | |||
157 | unsigned int blkcnt, | 158 | unsigned int blkcnt, |
158 | unsigned int log_unit ); | 159 | unsigned int log_unit ); |
159 | 160 | ||
160 | static int ida_open(struct block_device *bdev, fmode_t mode); | 161 | static int ida_unlocked_open(struct block_device *bdev, fmode_t mode); |
161 | static int ida_release(struct gendisk *disk, fmode_t mode); | 162 | static int ida_release(struct gendisk *disk, fmode_t mode); |
162 | static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); | 163 | static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); |
163 | static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo); | 164 | static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo); |
@@ -195,9 +196,9 @@ static inline ctlr_info_t *get_host(struct gendisk *disk) | |||
195 | 196 | ||
196 | static const struct block_device_operations ida_fops = { | 197 | static const struct block_device_operations ida_fops = { |
197 | .owner = THIS_MODULE, | 198 | .owner = THIS_MODULE, |
198 | .open = ida_open, | 199 | .open = ida_unlocked_open, |
199 | .release = ida_release, | 200 | .release = ida_release, |
200 | .locked_ioctl = ida_ioctl, | 201 | .ioctl = ida_ioctl, |
201 | .getgeo = ida_getgeo, | 202 | .getgeo = ida_getgeo, |
202 | .revalidate_disk= ida_revalidate, | 203 | .revalidate_disk= ida_revalidate, |
203 | }; | 204 | }; |
@@ -840,13 +841,29 @@ static int ida_open(struct block_device *bdev, fmode_t mode) | |||
840 | return 0; | 841 | return 0; |
841 | } | 842 | } |
842 | 843 | ||
844 | static int ida_unlocked_open(struct block_device *bdev, fmode_t mode) | ||
845 | { | ||
846 | int ret; | ||
847 | |||
848 | lock_kernel(); | ||
849 | ret = ida_open(bdev, mode); | ||
850 | unlock_kernel(); | ||
851 | |||
852 | return ret; | ||
853 | } | ||
854 | |||
843 | /* | 855 | /* |
844 | * Close. Sync first. | 856 | * Close. Sync first. |
845 | */ | 857 | */ |
846 | static int ida_release(struct gendisk *disk, fmode_t mode) | 858 | static int ida_release(struct gendisk *disk, fmode_t mode) |
847 | { | 859 | { |
848 | ctlr_info_t *host = get_host(disk); | 860 | ctlr_info_t *host; |
861 | |||
862 | lock_kernel(); | ||
863 | host = get_host(disk); | ||
849 | host->usage_count--; | 864 | host->usage_count--; |
865 | unlock_kernel(); | ||
866 | |||
850 | return 0; | 867 | return 0; |
851 | } | 868 | } |
852 | 869 | ||
@@ -1128,7 +1145,7 @@ static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
1128 | * ida_ioctl does some miscellaneous stuff like reporting drive geometry, | 1145 | * ida_ioctl does some miscellaneous stuff like reporting drive geometry, |
1129 | * setting readahead and submitting commands from userspace to the controller. | 1146 | * setting readahead and submitting commands from userspace to the controller. |
1130 | */ | 1147 | */ |
1131 | static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) | 1148 | static int ida_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) |
1132 | { | 1149 | { |
1133 | drv_info_t *drv = get_drv(bdev->bd_disk); | 1150 | drv_info_t *drv = get_drv(bdev->bd_disk); |
1134 | ctlr_info_t *host = get_host(bdev->bd_disk); | 1151 | ctlr_info_t *host = get_host(bdev->bd_disk); |
@@ -1162,7 +1179,8 @@ out_passthru: | |||
1162 | return error; | 1179 | return error; |
1163 | case IDAGETCTLRSIG: | 1180 | case IDAGETCTLRSIG: |
1164 | if (!arg) return -EINVAL; | 1181 | if (!arg) return -EINVAL; |
1165 | put_user(host->ctlr_sig, (int __user *)arg); | 1182 | if (put_user(host->ctlr_sig, (int __user *)arg)) |
1183 | return -EFAULT; | ||
1166 | return 0; | 1184 | return 0; |
1167 | case IDAREVALIDATEVOLS: | 1185 | case IDAREVALIDATEVOLS: |
1168 | if (MINOR(bdev->bd_dev) != 0) | 1186 | if (MINOR(bdev->bd_dev) != 0) |
@@ -1170,7 +1188,8 @@ out_passthru: | |||
1170 | return revalidate_allvol(host); | 1188 | return revalidate_allvol(host); |
1171 | case IDADRIVERVERSION: | 1189 | case IDADRIVERVERSION: |
1172 | if (!arg) return -EINVAL; | 1190 | if (!arg) return -EINVAL; |
1173 | put_user(DRIVER_VERSION, (unsigned long __user *)arg); | 1191 | if (put_user(DRIVER_VERSION, (unsigned long __user *)arg)) |
1192 | return -EFAULT; | ||
1174 | return 0; | 1193 | return 0; |
1175 | case IDAGETPCIINFO: | 1194 | case IDAGETPCIINFO: |
1176 | { | 1195 | { |
@@ -1192,6 +1211,19 @@ out_passthru: | |||
1192 | } | 1211 | } |
1193 | 1212 | ||
1194 | } | 1213 | } |
1214 | |||
1215 | static int ida_ioctl(struct block_device *bdev, fmode_t mode, | ||
1216 | unsigned int cmd, unsigned long param) | ||
1217 | { | ||
1218 | int ret; | ||
1219 | |||
1220 | lock_kernel(); | ||
1221 | ret = ida_locked_ioctl(bdev, mode, cmd, param); | ||
1222 | unlock_kernel(); | ||
1223 | |||
1224 | return ret; | ||
1225 | } | ||
1226 | |||
1195 | /* | 1227 | /* |
1196 | * ida_ctlr_ioctl is for passing commands to the controller from userspace. | 1228 | * ida_ctlr_ioctl is for passing commands to the controller from userspace. |
1197 | * The command block (io) has already been copied to kernel space for us, | 1229 | * The command block (io) has already been copied to kernel space for us, |
@@ -1225,17 +1257,11 @@ static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io) | |||
1225 | /* Pre submit processing */ | 1257 | /* Pre submit processing */ |
1226 | switch(io->cmd) { | 1258 | switch(io->cmd) { |
1227 | case PASSTHRU_A: | 1259 | case PASSTHRU_A: |
1228 | p = kmalloc(io->sg[0].size, GFP_KERNEL); | 1260 | p = memdup_user(io->sg[0].addr, io->sg[0].size); |
1229 | if (!p) | 1261 | if (IS_ERR(p)) { |
1230 | { | 1262 | error = PTR_ERR(p); |
1231 | error = -ENOMEM; | 1263 | cmd_free(h, c, 0); |
1232 | cmd_free(h, c, 0); | 1264 | return error; |
1233 | return(error); | ||
1234 | } | ||
1235 | if (copy_from_user(p, io->sg[0].addr, io->sg[0].size)) { | ||
1236 | kfree(p); | ||
1237 | cmd_free(h, c, 0); | ||
1238 | return -EFAULT; | ||
1239 | } | 1265 | } |
1240 | c->req.hdr.blk = pci_map_single(h->pci_dev, &(io->c), | 1266 | c->req.hdr.blk = pci_map_single(h->pci_dev, &(io->c), |
1241 | sizeof(ida_ioctl_t), | 1267 | sizeof(ida_ioctl_t), |
@@ -1266,18 +1292,12 @@ static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io) | |||
1266 | case DIAG_PASS_THRU: | 1292 | case DIAG_PASS_THRU: |
1267 | case COLLECT_BUFFER: | 1293 | case COLLECT_BUFFER: |
1268 | case WRITE_FLASH_ROM: | 1294 | case WRITE_FLASH_ROM: |
1269 | p = kmalloc(io->sg[0].size, GFP_KERNEL); | 1295 | p = memdup_user(io->sg[0].addr, io->sg[0].size); |
1270 | if (!p) | 1296 | if (IS_ERR(p)) { |
1271 | { | 1297 | error = PTR_ERR(p); |
1272 | error = -ENOMEM; | 1298 | cmd_free(h, c, 0); |
1273 | cmd_free(h, c, 0); | 1299 | return error; |
1274 | return(error); | ||
1275 | } | 1300 | } |
1276 | if (copy_from_user(p, io->sg[0].addr, io->sg[0].size)) { | ||
1277 | kfree(p); | ||
1278 | cmd_free(h, c, 0); | ||
1279 | return -EFAULT; | ||
1280 | } | ||
1281 | c->req.sg[0].size = io->sg[0].size; | 1301 | c->req.sg[0].size = io->sg[0].size; |
1282 | c->req.sg[0].addr = pci_map_single(h->pci_dev, p, | 1302 | c->req.sg[0].addr = pci_map_single(h->pci_dev, p, |
1283 | c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); | 1303 | c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); |
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index df018990c422..9400845d602e 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c | |||
@@ -79,8 +79,8 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, | |||
79 | md_io.error = 0; | 79 | md_io.error = 0; |
80 | 80 | ||
81 | if ((rw & WRITE) && !test_bit(MD_NO_BARRIER, &mdev->flags)) | 81 | if ((rw & WRITE) && !test_bit(MD_NO_BARRIER, &mdev->flags)) |
82 | rw |= (1 << BIO_RW_BARRIER); | 82 | rw |= REQ_HARDBARRIER; |
83 | rw |= ((1<<BIO_RW_UNPLUG) | (1<<BIO_RW_SYNCIO)); | 83 | rw |= REQ_UNPLUG | REQ_SYNC; |
84 | 84 | ||
85 | retry: | 85 | retry: |
86 | bio = bio_alloc(GFP_NOIO, 1); | 86 | bio = bio_alloc(GFP_NOIO, 1); |
@@ -103,11 +103,11 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, | |||
103 | /* check for unsupported barrier op. | 103 | /* check for unsupported barrier op. |
104 | * would rather check on EOPNOTSUPP, but that is not reliable. | 104 | * would rather check on EOPNOTSUPP, but that is not reliable. |
105 | * don't try again for ANY return value != 0 */ | 105 | * don't try again for ANY return value != 0 */ |
106 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER) && !ok)) { | 106 | if (unlikely((bio->bi_rw & REQ_HARDBARRIER) && !ok)) { |
107 | /* Try again with no barrier */ | 107 | /* Try again with no barrier */ |
108 | dev_warn(DEV, "Barriers not supported on meta data device - disabling\n"); | 108 | dev_warn(DEV, "Barriers not supported on meta data device - disabling\n"); |
109 | set_bit(MD_NO_BARRIER, &mdev->flags); | 109 | set_bit(MD_NO_BARRIER, &mdev->flags); |
110 | rw &= ~(1 << BIO_RW_BARRIER); | 110 | rw &= ~REQ_HARDBARRIER; |
111 | bio_put(bio); | 111 | bio_put(bio); |
112 | goto retry; | 112 | goto retry; |
113 | } | 113 | } |
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 485ed8c7d623..352441b0f92f 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h | |||
@@ -550,12 +550,6 @@ struct p_delay_probe { | |||
550 | u32 offset; /* usecs the probe got sent after the reference time point */ | 550 | u32 offset; /* usecs the probe got sent after the reference time point */ |
551 | } __packed; | 551 | } __packed; |
552 | 552 | ||
553 | struct delay_probe { | ||
554 | struct list_head list; | ||
555 | unsigned int seq_num; | ||
556 | struct timeval time; | ||
557 | }; | ||
558 | |||
559 | /* DCBP: Drbd Compressed Bitmap Packet ... */ | 553 | /* DCBP: Drbd Compressed Bitmap Packet ... */ |
560 | static inline enum drbd_bitmap_code | 554 | static inline enum drbd_bitmap_code |
561 | DCBP_get_code(struct p_compressed_bm *p) | 555 | DCBP_get_code(struct p_compressed_bm *p) |
@@ -942,11 +936,9 @@ struct drbd_conf { | |||
942 | unsigned int ko_count; | 936 | unsigned int ko_count; |
943 | struct drbd_work resync_work, | 937 | struct drbd_work resync_work, |
944 | unplug_work, | 938 | unplug_work, |
945 | md_sync_work, | 939 | md_sync_work; |
946 | delay_probe_work; | ||
947 | struct timer_list resync_timer; | 940 | struct timer_list resync_timer; |
948 | struct timer_list md_sync_timer; | 941 | struct timer_list md_sync_timer; |
949 | struct timer_list delay_probe_timer; | ||
950 | 942 | ||
951 | /* Used after attach while negotiating new disk state. */ | 943 | /* Used after attach while negotiating new disk state. */ |
952 | union drbd_state new_state_tmp; | 944 | union drbd_state new_state_tmp; |
@@ -1062,12 +1054,6 @@ struct drbd_conf { | |||
1062 | u64 ed_uuid; /* UUID of the exposed data */ | 1054 | u64 ed_uuid; /* UUID of the exposed data */ |
1063 | struct mutex state_mutex; | 1055 | struct mutex state_mutex; |
1064 | char congestion_reason; /* Why we where congested... */ | 1056 | char congestion_reason; /* Why we where congested... */ |
1065 | struct list_head delay_probes; /* protected by peer_seq_lock */ | ||
1066 | int data_delay; /* Delay of packets on the data-sock behind meta-sock */ | ||
1067 | unsigned int delay_seq; /* To generate sequence numbers of delay probes */ | ||
1068 | struct timeval dps_time; /* delay-probes-start-time */ | ||
1069 | unsigned int dp_volume_last; /* send_cnt of last delay probe */ | ||
1070 | int c_sync_rate; /* current resync rate after delay_probe magic */ | ||
1071 | }; | 1057 | }; |
1072 | 1058 | ||
1073 | static inline struct drbd_conf *minor_to_mdev(unsigned int minor) | 1059 | static inline struct drbd_conf *minor_to_mdev(unsigned int minor) |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 7258c95e895e..fa650dd85b90 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -2184,43 +2184,6 @@ int drbd_send_ov_request(struct drbd_conf *mdev, sector_t sector, int size) | |||
2184 | return ok; | 2184 | return ok; |
2185 | } | 2185 | } |
2186 | 2186 | ||
2187 | static int drbd_send_delay_probe(struct drbd_conf *mdev, struct drbd_socket *ds) | ||
2188 | { | ||
2189 | struct p_delay_probe dp; | ||
2190 | int offset, ok = 0; | ||
2191 | struct timeval now; | ||
2192 | |||
2193 | mutex_lock(&ds->mutex); | ||
2194 | if (likely(ds->socket)) { | ||
2195 | do_gettimeofday(&now); | ||
2196 | offset = now.tv_usec - mdev->dps_time.tv_usec + | ||
2197 | (now.tv_sec - mdev->dps_time.tv_sec) * 1000000; | ||
2198 | dp.seq_num = cpu_to_be32(mdev->delay_seq); | ||
2199 | dp.offset = cpu_to_be32(offset); | ||
2200 | |||
2201 | ok = _drbd_send_cmd(mdev, ds->socket, P_DELAY_PROBE, | ||
2202 | (struct p_header *)&dp, sizeof(dp), 0); | ||
2203 | } | ||
2204 | mutex_unlock(&ds->mutex); | ||
2205 | |||
2206 | return ok; | ||
2207 | } | ||
2208 | |||
2209 | static int drbd_send_delay_probes(struct drbd_conf *mdev) | ||
2210 | { | ||
2211 | int ok; | ||
2212 | |||
2213 | mdev->delay_seq++; | ||
2214 | do_gettimeofday(&mdev->dps_time); | ||
2215 | ok = drbd_send_delay_probe(mdev, &mdev->meta); | ||
2216 | ok = ok && drbd_send_delay_probe(mdev, &mdev->data); | ||
2217 | |||
2218 | mdev->dp_volume_last = mdev->send_cnt; | ||
2219 | mod_timer(&mdev->delay_probe_timer, jiffies + mdev->sync_conf.dp_interval * HZ / 10); | ||
2220 | |||
2221 | return ok; | ||
2222 | } | ||
2223 | |||
2224 | /* called on sndtimeo | 2187 | /* called on sndtimeo |
2225 | * returns FALSE if we should retry, | 2188 | * returns FALSE if we should retry, |
2226 | * TRUE if we think connection is dead | 2189 | * TRUE if we think connection is dead |
@@ -2369,31 +2332,6 @@ static int _drbd_send_zc_ee(struct drbd_conf *mdev, struct drbd_epoch_entry *e) | |||
2369 | return 1; | 2332 | return 1; |
2370 | } | 2333 | } |
2371 | 2334 | ||
2372 | static void consider_delay_probes(struct drbd_conf *mdev) | ||
2373 | { | ||
2374 | if (mdev->state.conn != C_SYNC_SOURCE || mdev->agreed_pro_version < 93) | ||
2375 | return; | ||
2376 | |||
2377 | if (mdev->dp_volume_last + mdev->sync_conf.dp_volume * 2 < mdev->send_cnt) | ||
2378 | drbd_send_delay_probes(mdev); | ||
2379 | } | ||
2380 | |||
2381 | static int w_delay_probes(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | ||
2382 | { | ||
2383 | if (!cancel && mdev->state.conn == C_SYNC_SOURCE) | ||
2384 | drbd_send_delay_probes(mdev); | ||
2385 | |||
2386 | return 1; | ||
2387 | } | ||
2388 | |||
2389 | static void delay_probe_timer_fn(unsigned long data) | ||
2390 | { | ||
2391 | struct drbd_conf *mdev = (struct drbd_conf *) data; | ||
2392 | |||
2393 | if (list_empty(&mdev->delay_probe_work.list)) | ||
2394 | drbd_queue_work(&mdev->data.work, &mdev->delay_probe_work); | ||
2395 | } | ||
2396 | |||
2397 | /* Used to send write requests | 2335 | /* Used to send write requests |
2398 | * R_PRIMARY -> Peer (P_DATA) | 2336 | * R_PRIMARY -> Peer (P_DATA) |
2399 | */ | 2337 | */ |
@@ -2425,15 +2363,15 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) | |||
2425 | /* NOTE: no need to check if barriers supported here as we would | 2363 | /* NOTE: no need to check if barriers supported here as we would |
2426 | * not pass the test in make_request_common in that case | 2364 | * not pass the test in make_request_common in that case |
2427 | */ | 2365 | */ |
2428 | if (bio_rw_flagged(req->master_bio, BIO_RW_BARRIER)) { | 2366 | if (req->master_bio->bi_rw & REQ_HARDBARRIER) { |
2429 | dev_err(DEV, "ASSERT FAILED would have set DP_HARDBARRIER\n"); | 2367 | dev_err(DEV, "ASSERT FAILED would have set DP_HARDBARRIER\n"); |
2430 | /* dp_flags |= DP_HARDBARRIER; */ | 2368 | /* dp_flags |= DP_HARDBARRIER; */ |
2431 | } | 2369 | } |
2432 | if (bio_rw_flagged(req->master_bio, BIO_RW_SYNCIO)) | 2370 | if (req->master_bio->bi_rw & REQ_SYNC) |
2433 | dp_flags |= DP_RW_SYNC; | 2371 | dp_flags |= DP_RW_SYNC; |
2434 | /* for now handle SYNCIO and UNPLUG | 2372 | /* for now handle SYNCIO and UNPLUG |
2435 | * as if they still were one and the same flag */ | 2373 | * as if they still were one and the same flag */ |
2436 | if (bio_rw_flagged(req->master_bio, BIO_RW_UNPLUG)) | 2374 | if (req->master_bio->bi_rw & REQ_UNPLUG) |
2437 | dp_flags |= DP_RW_SYNC; | 2375 | dp_flags |= DP_RW_SYNC; |
2438 | if (mdev->state.conn >= C_SYNC_SOURCE && | 2376 | if (mdev->state.conn >= C_SYNC_SOURCE && |
2439 | mdev->state.conn <= C_PAUSED_SYNC_T) | 2377 | mdev->state.conn <= C_PAUSED_SYNC_T) |
@@ -2457,9 +2395,6 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) | |||
2457 | 2395 | ||
2458 | drbd_put_data_sock(mdev); | 2396 | drbd_put_data_sock(mdev); |
2459 | 2397 | ||
2460 | if (ok) | ||
2461 | consider_delay_probes(mdev); | ||
2462 | |||
2463 | return ok; | 2398 | return ok; |
2464 | } | 2399 | } |
2465 | 2400 | ||
@@ -2506,9 +2441,6 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd, | |||
2506 | 2441 | ||
2507 | drbd_put_data_sock(mdev); | 2442 | drbd_put_data_sock(mdev); |
2508 | 2443 | ||
2509 | if (ok) | ||
2510 | consider_delay_probes(mdev); | ||
2511 | |||
2512 | return ok; | 2444 | return ok; |
2513 | } | 2445 | } |
2514 | 2446 | ||
@@ -2604,6 +2536,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) | |||
2604 | unsigned long flags; | 2536 | unsigned long flags; |
2605 | int rv = 0; | 2537 | int rv = 0; |
2606 | 2538 | ||
2539 | lock_kernel(); | ||
2607 | spin_lock_irqsave(&mdev->req_lock, flags); | 2540 | spin_lock_irqsave(&mdev->req_lock, flags); |
2608 | /* to have a stable mdev->state.role | 2541 | /* to have a stable mdev->state.role |
2609 | * and no race with updating open_cnt */ | 2542 | * and no race with updating open_cnt */ |
@@ -2618,6 +2551,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) | |||
2618 | if (!rv) | 2551 | if (!rv) |
2619 | mdev->open_cnt++; | 2552 | mdev->open_cnt++; |
2620 | spin_unlock_irqrestore(&mdev->req_lock, flags); | 2553 | spin_unlock_irqrestore(&mdev->req_lock, flags); |
2554 | unlock_kernel(); | ||
2621 | 2555 | ||
2622 | return rv; | 2556 | return rv; |
2623 | } | 2557 | } |
@@ -2625,7 +2559,9 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) | |||
2625 | static int drbd_release(struct gendisk *gd, fmode_t mode) | 2559 | static int drbd_release(struct gendisk *gd, fmode_t mode) |
2626 | { | 2560 | { |
2627 | struct drbd_conf *mdev = gd->private_data; | 2561 | struct drbd_conf *mdev = gd->private_data; |
2562 | lock_kernel(); | ||
2628 | mdev->open_cnt--; | 2563 | mdev->open_cnt--; |
2564 | unlock_kernel(); | ||
2629 | return 0; | 2565 | return 0; |
2630 | } | 2566 | } |
2631 | 2567 | ||
@@ -2660,9 +2596,20 @@ static void drbd_unplug_fn(struct request_queue *q) | |||
2660 | 2596 | ||
2661 | static void drbd_set_defaults(struct drbd_conf *mdev) | 2597 | static void drbd_set_defaults(struct drbd_conf *mdev) |
2662 | { | 2598 | { |
2663 | mdev->sync_conf.after = DRBD_AFTER_DEF; | 2599 | /* This way we get a compile error when sync_conf grows, |
2664 | mdev->sync_conf.rate = DRBD_RATE_DEF; | 2600 | and we forgot to initialize it here */ |
2665 | mdev->sync_conf.al_extents = DRBD_AL_EXTENTS_DEF; | 2601 | mdev->sync_conf = (struct syncer_conf) { |
2602 | /* .rate = */ DRBD_RATE_DEF, | ||
2603 | /* .after = */ DRBD_AFTER_DEF, | ||
2604 | /* .al_extents = */ DRBD_AL_EXTENTS_DEF, | ||
2605 | /* .verify_alg = */ {}, 0, | ||
2606 | /* .cpu_mask = */ {}, 0, | ||
2607 | /* .csums_alg = */ {}, 0, | ||
2608 | /* .use_rle = */ 0 | ||
2609 | }; | ||
2610 | |||
2611 | /* Have to use that way, because the layout differs between | ||
2612 | big endian and little endian */ | ||
2666 | mdev->state = (union drbd_state) { | 2613 | mdev->state = (union drbd_state) { |
2667 | { .role = R_SECONDARY, | 2614 | { .role = R_SECONDARY, |
2668 | .peer = R_UNKNOWN, | 2615 | .peer = R_UNKNOWN, |
@@ -2721,24 +2668,17 @@ void drbd_init_set_defaults(struct drbd_conf *mdev) | |||
2721 | INIT_LIST_HEAD(&mdev->unplug_work.list); | 2668 | INIT_LIST_HEAD(&mdev->unplug_work.list); |
2722 | INIT_LIST_HEAD(&mdev->md_sync_work.list); | 2669 | INIT_LIST_HEAD(&mdev->md_sync_work.list); |
2723 | INIT_LIST_HEAD(&mdev->bm_io_work.w.list); | 2670 | INIT_LIST_HEAD(&mdev->bm_io_work.w.list); |
2724 | INIT_LIST_HEAD(&mdev->delay_probes); | ||
2725 | INIT_LIST_HEAD(&mdev->delay_probe_work.list); | ||
2726 | 2671 | ||
2727 | mdev->resync_work.cb = w_resync_inactive; | 2672 | mdev->resync_work.cb = w_resync_inactive; |
2728 | mdev->unplug_work.cb = w_send_write_hint; | 2673 | mdev->unplug_work.cb = w_send_write_hint; |
2729 | mdev->md_sync_work.cb = w_md_sync; | 2674 | mdev->md_sync_work.cb = w_md_sync; |
2730 | mdev->bm_io_work.w.cb = w_bitmap_io; | 2675 | mdev->bm_io_work.w.cb = w_bitmap_io; |
2731 | mdev->delay_probe_work.cb = w_delay_probes; | ||
2732 | init_timer(&mdev->resync_timer); | 2676 | init_timer(&mdev->resync_timer); |
2733 | init_timer(&mdev->md_sync_timer); | 2677 | init_timer(&mdev->md_sync_timer); |
2734 | init_timer(&mdev->delay_probe_timer); | ||
2735 | mdev->resync_timer.function = resync_timer_fn; | 2678 | mdev->resync_timer.function = resync_timer_fn; |
2736 | mdev->resync_timer.data = (unsigned long) mdev; | 2679 | mdev->resync_timer.data = (unsigned long) mdev; |
2737 | mdev->md_sync_timer.function = md_sync_timer_fn; | 2680 | mdev->md_sync_timer.function = md_sync_timer_fn; |
2738 | mdev->md_sync_timer.data = (unsigned long) mdev; | 2681 | mdev->md_sync_timer.data = (unsigned long) mdev; |
2739 | mdev->delay_probe_timer.function = delay_probe_timer_fn; | ||
2740 | mdev->delay_probe_timer.data = (unsigned long) mdev; | ||
2741 | |||
2742 | 2682 | ||
2743 | init_waitqueue_head(&mdev->misc_wait); | 2683 | init_waitqueue_head(&mdev->misc_wait); |
2744 | init_waitqueue_head(&mdev->state_wait); | 2684 | init_waitqueue_head(&mdev->state_wait); |
diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 2151f18b21de..73131c5ae339 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c | |||
@@ -1557,10 +1557,6 @@ static int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *n | |||
1557 | sc.rate = DRBD_RATE_DEF; | 1557 | sc.rate = DRBD_RATE_DEF; |
1558 | sc.after = DRBD_AFTER_DEF; | 1558 | sc.after = DRBD_AFTER_DEF; |
1559 | sc.al_extents = DRBD_AL_EXTENTS_DEF; | 1559 | sc.al_extents = DRBD_AL_EXTENTS_DEF; |
1560 | sc.dp_volume = DRBD_DP_VOLUME_DEF; | ||
1561 | sc.dp_interval = DRBD_DP_INTERVAL_DEF; | ||
1562 | sc.throttle_th = DRBD_RS_THROTTLE_TH_DEF; | ||
1563 | sc.hold_off_th = DRBD_RS_HOLD_OFF_TH_DEF; | ||
1564 | } else | 1560 | } else |
1565 | memcpy(&sc, &mdev->sync_conf, sizeof(struct syncer_conf)); | 1561 | memcpy(&sc, &mdev->sync_conf, sizeof(struct syncer_conf)); |
1566 | 1562 | ||
diff --git a/drivers/block/drbd/drbd_proc.c b/drivers/block/drbd/drbd_proc.c index d0f1767ea4c3..be3374b68460 100644 --- a/drivers/block/drbd/drbd_proc.c +++ b/drivers/block/drbd/drbd_proc.c | |||
@@ -73,21 +73,14 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) | |||
73 | seq_printf(seq, "sync'ed:%3u.%u%% ", res / 10, res % 10); | 73 | seq_printf(seq, "sync'ed:%3u.%u%% ", res / 10, res % 10); |
74 | /* if more than 1 GB display in MB */ | 74 | /* if more than 1 GB display in MB */ |
75 | if (mdev->rs_total > 0x100000L) | 75 | if (mdev->rs_total > 0x100000L) |
76 | seq_printf(seq, "(%lu/%lu)M", | 76 | seq_printf(seq, "(%lu/%lu)M\n\t", |
77 | (unsigned long) Bit2KB(rs_left >> 10), | 77 | (unsigned long) Bit2KB(rs_left >> 10), |
78 | (unsigned long) Bit2KB(mdev->rs_total >> 10)); | 78 | (unsigned long) Bit2KB(mdev->rs_total >> 10)); |
79 | else | 79 | else |
80 | seq_printf(seq, "(%lu/%lu)K", | 80 | seq_printf(seq, "(%lu/%lu)K\n\t", |
81 | (unsigned long) Bit2KB(rs_left), | 81 | (unsigned long) Bit2KB(rs_left), |
82 | (unsigned long) Bit2KB(mdev->rs_total)); | 82 | (unsigned long) Bit2KB(mdev->rs_total)); |
83 | 83 | ||
84 | if (mdev->state.conn == C_SYNC_TARGET) | ||
85 | seq_printf(seq, " queue_delay: %d.%d ms\n\t", | ||
86 | mdev->data_delay / 1000, | ||
87 | (mdev->data_delay % 1000) / 100); | ||
88 | else if (mdev->state.conn == C_SYNC_SOURCE) | ||
89 | seq_printf(seq, " delay_probe: %u\n\t", mdev->delay_seq); | ||
90 | |||
91 | /* see drivers/md/md.c | 84 | /* see drivers/md/md.c |
92 | * We do not want to overflow, so the order of operands and | 85 | * We do not want to overflow, so the order of operands and |
93 | * the * 100 / 100 trick are important. We do a +1 to be | 86 | * the * 100 / 100 trick are important. We do a +1 to be |
@@ -135,14 +128,6 @@ static void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) | |||
135 | else | 128 | else |
136 | seq_printf(seq, " (%ld)", dbdt); | 129 | seq_printf(seq, " (%ld)", dbdt); |
137 | 130 | ||
138 | if (mdev->state.conn == C_SYNC_TARGET) { | ||
139 | if (mdev->c_sync_rate > 1000) | ||
140 | seq_printf(seq, " want: %d,%03d", | ||
141 | mdev->c_sync_rate / 1000, mdev->c_sync_rate % 1000); | ||
142 | else | ||
143 | seq_printf(seq, " want: %d", mdev->c_sync_rate); | ||
144 | } | ||
145 | |||
146 | seq_printf(seq, " K/sec\n"); | 131 | seq_printf(seq, " K/sec\n"); |
147 | } | 132 | } |
148 | 133 | ||
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index ec1711f7c5c5..081522d3c742 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -1180,7 +1180,7 @@ next_bio: | |||
1180 | bio->bi_sector = sector; | 1180 | bio->bi_sector = sector; |
1181 | bio->bi_bdev = mdev->ldev->backing_bdev; | 1181 | bio->bi_bdev = mdev->ldev->backing_bdev; |
1182 | /* we special case some flags in the multi-bio case, see below | 1182 | /* we special case some flags in the multi-bio case, see below |
1183 | * (BIO_RW_UNPLUG, BIO_RW_BARRIER) */ | 1183 | * (REQ_UNPLUG, REQ_HARDBARRIER) */ |
1184 | bio->bi_rw = rw; | 1184 | bio->bi_rw = rw; |
1185 | bio->bi_private = e; | 1185 | bio->bi_private = e; |
1186 | bio->bi_end_io = drbd_endio_sec; | 1186 | bio->bi_end_io = drbd_endio_sec; |
@@ -1209,16 +1209,16 @@ next_bio: | |||
1209 | bios = bios->bi_next; | 1209 | bios = bios->bi_next; |
1210 | bio->bi_next = NULL; | 1210 | bio->bi_next = NULL; |
1211 | 1211 | ||
1212 | /* strip off BIO_RW_UNPLUG unless it is the last bio */ | 1212 | /* strip off REQ_UNPLUG unless it is the last bio */ |
1213 | if (bios) | 1213 | if (bios) |
1214 | bio->bi_rw &= ~(1<<BIO_RW_UNPLUG); | 1214 | bio->bi_rw &= ~REQ_UNPLUG; |
1215 | 1215 | ||
1216 | drbd_generic_make_request(mdev, fault_type, bio); | 1216 | drbd_generic_make_request(mdev, fault_type, bio); |
1217 | 1217 | ||
1218 | /* strip off BIO_RW_BARRIER, | 1218 | /* strip off REQ_HARDBARRIER, |
1219 | * unless it is the first or last bio */ | 1219 | * unless it is the first or last bio */ |
1220 | if (bios && bios->bi_next) | 1220 | if (bios && bios->bi_next) |
1221 | bios->bi_rw &= ~(1<<BIO_RW_BARRIER); | 1221 | bios->bi_rw &= ~REQ_HARDBARRIER; |
1222 | } while (bios); | 1222 | } while (bios); |
1223 | maybe_kick_lo(mdev); | 1223 | maybe_kick_lo(mdev); |
1224 | return 0; | 1224 | return 0; |
@@ -1233,7 +1233,7 @@ fail: | |||
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | /** | 1235 | /** |
1236 | * w_e_reissue() - Worker callback; Resubmit a bio, without BIO_RW_BARRIER set | 1236 | * w_e_reissue() - Worker callback; Resubmit a bio, without REQ_HARDBARRIER set |
1237 | * @mdev: DRBD device. | 1237 | * @mdev: DRBD device. |
1238 | * @w: work object. | 1238 | * @w: work object. |
1239 | * @cancel: The connection will be closed anyways (unused in this callback) | 1239 | * @cancel: The connection will be closed anyways (unused in this callback) |
@@ -1245,7 +1245,7 @@ int w_e_reissue(struct drbd_conf *mdev, struct drbd_work *w, int cancel) __relea | |||
1245 | (and DE_BARRIER_IN_NEXT_EPOCH_ISSUED in the previous Epoch) | 1245 | (and DE_BARRIER_IN_NEXT_EPOCH_ISSUED in the previous Epoch) |
1246 | so that we can finish that epoch in drbd_may_finish_epoch(). | 1246 | so that we can finish that epoch in drbd_may_finish_epoch(). |
1247 | That is necessary if we already have a long chain of Epochs, before | 1247 | That is necessary if we already have a long chain of Epochs, before |
1248 | we realize that BIO_RW_BARRIER is actually not supported */ | 1248 | we realize that REQ_HARDBARRIER is actually not supported */ |
1249 | 1249 | ||
1250 | /* As long as the -ENOTSUPP on the barrier is reported immediately | 1250 | /* As long as the -ENOTSUPP on the barrier is reported immediately |
1251 | that will never trigger. If it is reported late, we will just | 1251 | that will never trigger. If it is reported late, we will just |
@@ -1824,14 +1824,14 @@ static int receive_Data(struct drbd_conf *mdev, struct p_header *h) | |||
1824 | epoch = list_entry(e->epoch->list.prev, struct drbd_epoch, list); | 1824 | epoch = list_entry(e->epoch->list.prev, struct drbd_epoch, list); |
1825 | if (epoch == e->epoch) { | 1825 | if (epoch == e->epoch) { |
1826 | set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); | 1826 | set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); |
1827 | rw |= (1<<BIO_RW_BARRIER); | 1827 | rw |= REQ_HARDBARRIER; |
1828 | e->flags |= EE_IS_BARRIER; | 1828 | e->flags |= EE_IS_BARRIER; |
1829 | } else { | 1829 | } else { |
1830 | if (atomic_read(&epoch->epoch_size) > 1 || | 1830 | if (atomic_read(&epoch->epoch_size) > 1 || |
1831 | !test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) { | 1831 | !test_bit(DE_CONTAINS_A_BARRIER, &epoch->flags)) { |
1832 | set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags); | 1832 | set_bit(DE_BARRIER_IN_NEXT_EPOCH_ISSUED, &epoch->flags); |
1833 | set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); | 1833 | set_bit(DE_CONTAINS_A_BARRIER, &e->epoch->flags); |
1834 | rw |= (1<<BIO_RW_BARRIER); | 1834 | rw |= REQ_HARDBARRIER; |
1835 | e->flags |= EE_IS_BARRIER; | 1835 | e->flags |= EE_IS_BARRIER; |
1836 | } | 1836 | } |
1837 | } | 1837 | } |
@@ -1841,10 +1841,10 @@ static int receive_Data(struct drbd_conf *mdev, struct p_header *h) | |||
1841 | dp_flags = be32_to_cpu(p->dp_flags); | 1841 | dp_flags = be32_to_cpu(p->dp_flags); |
1842 | if (dp_flags & DP_HARDBARRIER) { | 1842 | if (dp_flags & DP_HARDBARRIER) { |
1843 | dev_err(DEV, "ASSERT FAILED would have submitted barrier request\n"); | 1843 | dev_err(DEV, "ASSERT FAILED would have submitted barrier request\n"); |
1844 | /* rw |= (1<<BIO_RW_BARRIER); */ | 1844 | /* rw |= REQ_HARDBARRIER; */ |
1845 | } | 1845 | } |
1846 | if (dp_flags & DP_RW_SYNC) | 1846 | if (dp_flags & DP_RW_SYNC) |
1847 | rw |= (1<<BIO_RW_SYNCIO) | (1<<BIO_RW_UNPLUG); | 1847 | rw |= REQ_SYNC | REQ_UNPLUG; |
1848 | if (dp_flags & DP_MAY_SET_IN_SYNC) | 1848 | if (dp_flags & DP_MAY_SET_IN_SYNC) |
1849 | e->flags |= EE_MAY_SET_IN_SYNC; | 1849 | e->flags |= EE_MAY_SET_IN_SYNC; |
1850 | 1850 | ||
@@ -3555,14 +3555,15 @@ static int receive_bitmap(struct drbd_conf *mdev, struct p_header *h) | |||
3555 | return ok; | 3555 | return ok; |
3556 | } | 3556 | } |
3557 | 3557 | ||
3558 | static int receive_skip(struct drbd_conf *mdev, struct p_header *h) | 3558 | static int receive_skip_(struct drbd_conf *mdev, struct p_header *h, int silent) |
3559 | { | 3559 | { |
3560 | /* TODO zero copy sink :) */ | 3560 | /* TODO zero copy sink :) */ |
3561 | static char sink[128]; | 3561 | static char sink[128]; |
3562 | int size, want, r; | 3562 | int size, want, r; |
3563 | 3563 | ||
3564 | dev_warn(DEV, "skipping unknown optional packet type %d, l: %d!\n", | 3564 | if (!silent) |
3565 | h->command, h->length); | 3565 | dev_warn(DEV, "skipping unknown optional packet type %d, l: %d!\n", |
3566 | h->command, h->length); | ||
3566 | 3567 | ||
3567 | size = h->length; | 3568 | size = h->length; |
3568 | while (size > 0) { | 3569 | while (size > 0) { |
@@ -3574,101 +3575,25 @@ static int receive_skip(struct drbd_conf *mdev, struct p_header *h) | |||
3574 | return size == 0; | 3575 | return size == 0; |
3575 | } | 3576 | } |
3576 | 3577 | ||
3577 | static int receive_UnplugRemote(struct drbd_conf *mdev, struct p_header *h) | 3578 | static int receive_skip(struct drbd_conf *mdev, struct p_header *h) |
3578 | { | ||
3579 | if (mdev->state.disk >= D_INCONSISTENT) | ||
3580 | drbd_kick_lo(mdev); | ||
3581 | |||
3582 | /* Make sure we've acked all the TCP data associated | ||
3583 | * with the data requests being unplugged */ | ||
3584 | drbd_tcp_quickack(mdev->data.socket); | ||
3585 | |||
3586 | return TRUE; | ||
3587 | } | ||
3588 | |||
3589 | static void timeval_sub_us(struct timeval* tv, unsigned int us) | ||
3590 | { | 3579 | { |
3591 | tv->tv_sec -= us / 1000000; | 3580 | return receive_skip_(mdev, h, 0); |
3592 | us = us % 1000000; | ||
3593 | if (tv->tv_usec > us) { | ||
3594 | tv->tv_usec += 1000000; | ||
3595 | tv->tv_sec--; | ||
3596 | } | ||
3597 | tv->tv_usec -= us; | ||
3598 | } | 3581 | } |
3599 | 3582 | ||
3600 | static void got_delay_probe(struct drbd_conf *mdev, int from, struct p_delay_probe *p) | 3583 | static int receive_skip_silent(struct drbd_conf *mdev, struct p_header *h) |
3601 | { | 3584 | { |
3602 | struct delay_probe *dp; | 3585 | return receive_skip_(mdev, h, 1); |
3603 | struct list_head *le; | ||
3604 | struct timeval now; | ||
3605 | int seq_num; | ||
3606 | int offset; | ||
3607 | int data_delay; | ||
3608 | |||
3609 | seq_num = be32_to_cpu(p->seq_num); | ||
3610 | offset = be32_to_cpu(p->offset); | ||
3611 | |||
3612 | spin_lock(&mdev->peer_seq_lock); | ||
3613 | if (!list_empty(&mdev->delay_probes)) { | ||
3614 | if (from == USE_DATA_SOCKET) | ||
3615 | le = mdev->delay_probes.next; | ||
3616 | else | ||
3617 | le = mdev->delay_probes.prev; | ||
3618 | |||
3619 | dp = list_entry(le, struct delay_probe, list); | ||
3620 | |||
3621 | if (dp->seq_num == seq_num) { | ||
3622 | list_del(le); | ||
3623 | spin_unlock(&mdev->peer_seq_lock); | ||
3624 | do_gettimeofday(&now); | ||
3625 | timeval_sub_us(&now, offset); | ||
3626 | data_delay = | ||
3627 | now.tv_usec - dp->time.tv_usec + | ||
3628 | (now.tv_sec - dp->time.tv_sec) * 1000000; | ||
3629 | |||
3630 | if (data_delay > 0) | ||
3631 | mdev->data_delay = data_delay; | ||
3632 | |||
3633 | kfree(dp); | ||
3634 | return; | ||
3635 | } | ||
3636 | |||
3637 | if (dp->seq_num > seq_num) { | ||
3638 | spin_unlock(&mdev->peer_seq_lock); | ||
3639 | dev_warn(DEV, "Previous allocation failure of struct delay_probe?\n"); | ||
3640 | return; /* Do not alloca a struct delay_probe.... */ | ||
3641 | } | ||
3642 | } | ||
3643 | spin_unlock(&mdev->peer_seq_lock); | ||
3644 | |||
3645 | dp = kmalloc(sizeof(struct delay_probe), GFP_NOIO); | ||
3646 | if (!dp) { | ||
3647 | dev_warn(DEV, "Failed to allocate a struct delay_probe, do not worry.\n"); | ||
3648 | return; | ||
3649 | } | ||
3650 | |||
3651 | dp->seq_num = seq_num; | ||
3652 | do_gettimeofday(&dp->time); | ||
3653 | timeval_sub_us(&dp->time, offset); | ||
3654 | |||
3655 | spin_lock(&mdev->peer_seq_lock); | ||
3656 | if (from == USE_DATA_SOCKET) | ||
3657 | list_add(&dp->list, &mdev->delay_probes); | ||
3658 | else | ||
3659 | list_add_tail(&dp->list, &mdev->delay_probes); | ||
3660 | spin_unlock(&mdev->peer_seq_lock); | ||
3661 | } | 3586 | } |
3662 | 3587 | ||
3663 | static int receive_delay_probe(struct drbd_conf *mdev, struct p_header *h) | 3588 | static int receive_UnplugRemote(struct drbd_conf *mdev, struct p_header *h) |
3664 | { | 3589 | { |
3665 | struct p_delay_probe *p = (struct p_delay_probe *)h; | 3590 | if (mdev->state.disk >= D_INCONSISTENT) |
3591 | drbd_kick_lo(mdev); | ||
3666 | 3592 | ||
3667 | ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; | 3593 | /* Make sure we've acked all the TCP data associated |
3668 | if (drbd_recv(mdev, h->payload, h->length) != h->length) | 3594 | * with the data requests being unplugged */ |
3669 | return FALSE; | 3595 | drbd_tcp_quickack(mdev->data.socket); |
3670 | 3596 | ||
3671 | got_delay_probe(mdev, USE_DATA_SOCKET, p); | ||
3672 | return TRUE; | 3597 | return TRUE; |
3673 | } | 3598 | } |
3674 | 3599 | ||
@@ -3695,7 +3620,7 @@ static drbd_cmd_handler_f drbd_default_handler[] = { | |||
3695 | [P_OV_REQUEST] = receive_DataRequest, | 3620 | [P_OV_REQUEST] = receive_DataRequest, |
3696 | [P_OV_REPLY] = receive_DataRequest, | 3621 | [P_OV_REPLY] = receive_DataRequest, |
3697 | [P_CSUM_RS_REQUEST] = receive_DataRequest, | 3622 | [P_CSUM_RS_REQUEST] = receive_DataRequest, |
3698 | [P_DELAY_PROBE] = receive_delay_probe, | 3623 | [P_DELAY_PROBE] = receive_skip_silent, |
3699 | /* anything missing from this table is in | 3624 | /* anything missing from this table is in |
3700 | * the asender_tbl, see get_asender_cmd */ | 3625 | * the asender_tbl, see get_asender_cmd */ |
3701 | [P_MAX_CMD] = NULL, | 3626 | [P_MAX_CMD] = NULL, |
@@ -4472,11 +4397,9 @@ static int got_OVResult(struct drbd_conf *mdev, struct p_header *h) | |||
4472 | return TRUE; | 4397 | return TRUE; |
4473 | } | 4398 | } |
4474 | 4399 | ||
4475 | static int got_delay_probe_m(struct drbd_conf *mdev, struct p_header *h) | 4400 | static int got_something_to_ignore_m(struct drbd_conf *mdev, struct p_header *h) |
4476 | { | 4401 | { |
4477 | struct p_delay_probe *p = (struct p_delay_probe *)h; | 4402 | /* IGNORE */ |
4478 | |||
4479 | got_delay_probe(mdev, USE_META_SOCKET, p); | ||
4480 | return TRUE; | 4403 | return TRUE; |
4481 | } | 4404 | } |
4482 | 4405 | ||
@@ -4504,7 +4427,7 @@ static struct asender_cmd *get_asender_cmd(int cmd) | |||
4504 | [P_BARRIER_ACK] = { sizeof(struct p_barrier_ack), got_BarrierAck }, | 4427 | [P_BARRIER_ACK] = { sizeof(struct p_barrier_ack), got_BarrierAck }, |
4505 | [P_STATE_CHG_REPLY] = { sizeof(struct p_req_state_reply), got_RqSReply }, | 4428 | [P_STATE_CHG_REPLY] = { sizeof(struct p_req_state_reply), got_RqSReply }, |
4506 | [P_RS_IS_IN_SYNC] = { sizeof(struct p_block_ack), got_IsInSync }, | 4429 | [P_RS_IS_IN_SYNC] = { sizeof(struct p_block_ack), got_IsInSync }, |
4507 | [P_DELAY_PROBE] = { sizeof(struct p_delay_probe), got_delay_probe_m }, | 4430 | [P_DELAY_PROBE] = { sizeof(struct p_delay_probe), got_something_to_ignore_m }, |
4508 | [P_MAX_CMD] = { 0, NULL }, | 4431 | [P_MAX_CMD] = { 0, NULL }, |
4509 | }; | 4432 | }; |
4510 | if (cmd > P_MAX_CMD || asender_tbl[cmd].process == NULL) | 4433 | if (cmd > P_MAX_CMD || asender_tbl[cmd].process == NULL) |
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 654f1ef5cbb0..f761d98a4e90 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -997,7 +997,7 @@ int drbd_make_request_26(struct request_queue *q, struct bio *bio) | |||
997 | * because of those XXX, this is not yet enabled, | 997 | * because of those XXX, this is not yet enabled, |
998 | * i.e. in drbd_init_set_defaults we set the NO_BARRIER_SUPP bit. | 998 | * i.e. in drbd_init_set_defaults we set the NO_BARRIER_SUPP bit. |
999 | */ | 999 | */ |
1000 | if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER) && test_bit(NO_BARRIER_SUPP, &mdev->flags))) { | 1000 | if (unlikely(bio->bi_rw & REQ_HARDBARRIER) && test_bit(NO_BARRIER_SUPP, &mdev->flags)) { |
1001 | /* dev_warn(DEV, "Rejecting barrier request as underlying device does not support\n"); */ | 1001 | /* dev_warn(DEV, "Rejecting barrier request as underlying device does not support\n"); */ |
1002 | bio_endio(bio, -EOPNOTSUPP); | 1002 | bio_endio(bio, -EOPNOTSUPP); |
1003 | return 0; | 1003 | return 0; |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index b623ceee2a4a..ca4a16cea2d8 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -424,18 +424,6 @@ void resync_timer_fn(unsigned long data) | |||
424 | drbd_queue_work(&mdev->data.work, &mdev->resync_work); | 424 | drbd_queue_work(&mdev->data.work, &mdev->resync_work); |
425 | } | 425 | } |
426 | 426 | ||
427 | static int calc_resync_rate(struct drbd_conf *mdev) | ||
428 | { | ||
429 | int d = mdev->data_delay / 1000; /* us -> ms */ | ||
430 | int td = mdev->sync_conf.throttle_th * 100; /* 0.1s -> ms */ | ||
431 | int hd = mdev->sync_conf.hold_off_th * 100; /* 0.1s -> ms */ | ||
432 | int cr = mdev->sync_conf.rate; | ||
433 | |||
434 | return d <= td ? cr : | ||
435 | d >= hd ? 0 : | ||
436 | cr + (cr * (td - d) / (hd - td)); | ||
437 | } | ||
438 | |||
439 | int w_make_resync_request(struct drbd_conf *mdev, | 427 | int w_make_resync_request(struct drbd_conf *mdev, |
440 | struct drbd_work *w, int cancel) | 428 | struct drbd_work *w, int cancel) |
441 | { | 429 | { |
@@ -473,8 +461,7 @@ int w_make_resync_request(struct drbd_conf *mdev, | |||
473 | max_segment_size = mdev->agreed_pro_version < 94 ? | 461 | max_segment_size = mdev->agreed_pro_version < 94 ? |
474 | queue_max_segment_size(mdev->rq_queue) : DRBD_MAX_SEGMENT_SIZE; | 462 | queue_max_segment_size(mdev->rq_queue) : DRBD_MAX_SEGMENT_SIZE; |
475 | 463 | ||
476 | mdev->c_sync_rate = calc_resync_rate(mdev); | 464 | number = SLEEP_TIME * mdev->sync_conf.rate / ((BM_BLOCK_SIZE / 1024) * HZ); |
477 | number = SLEEP_TIME * mdev->c_sync_rate / ((BM_BLOCK_SIZE / 1024) * HZ); | ||
478 | pe = atomic_read(&mdev->rs_pending_cnt); | 465 | pe = atomic_read(&mdev->rs_pending_cnt); |
479 | 466 | ||
480 | mutex_lock(&mdev->data.mutex); | 467 | mutex_lock(&mdev->data.mutex); |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 90c4038702da..cf04c1b234ed 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -178,6 +178,7 @@ static int print_unex = 1; | |||
178 | #include <linux/slab.h> | 178 | #include <linux/slab.h> |
179 | #include <linux/mm.h> | 179 | #include <linux/mm.h> |
180 | #include <linux/bio.h> | 180 | #include <linux/bio.h> |
181 | #include <linux/smp_lock.h> | ||
181 | #include <linux/string.h> | 182 | #include <linux/string.h> |
182 | #include <linux/jiffies.h> | 183 | #include <linux/jiffies.h> |
183 | #include <linux/fcntl.h> | 184 | #include <linux/fcntl.h> |
@@ -514,8 +515,6 @@ static unsigned long fdc_busy; | |||
514 | static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); | 515 | static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); |
515 | static DECLARE_WAIT_QUEUE_HEAD(command_done); | 516 | static DECLARE_WAIT_QUEUE_HEAD(command_done); |
516 | 517 | ||
517 | #define NO_SIGNAL (!interruptible || !signal_pending(current)) | ||
518 | |||
519 | /* Errors during formatting are counted here. */ | 518 | /* Errors during formatting are counted here. */ |
520 | static int format_errors; | 519 | static int format_errors; |
521 | 520 | ||
@@ -539,7 +538,7 @@ static int max_buffer_sectors; | |||
539 | 538 | ||
540 | static int *errors; | 539 | static int *errors; |
541 | typedef void (*done_f)(int); | 540 | typedef void (*done_f)(int); |
542 | static struct cont_t { | 541 | static const struct cont_t { |
543 | void (*interrupt)(void); | 542 | void (*interrupt)(void); |
544 | /* this is called after the interrupt of the | 543 | /* this is called after the interrupt of the |
545 | * main command */ | 544 | * main command */ |
@@ -578,7 +577,7 @@ static void reset_fdc(void); | |||
578 | #define NEED_1_RECAL -2 | 577 | #define NEED_1_RECAL -2 |
579 | #define NEED_2_RECAL -3 | 578 | #define NEED_2_RECAL -3 |
580 | 579 | ||
581 | static int usage_count; | 580 | static atomic_t usage_count = ATOMIC_INIT(0); |
582 | 581 | ||
583 | /* buffer related variables */ | 582 | /* buffer related variables */ |
584 | static int buffer_track = -1; | 583 | static int buffer_track = -1; |
@@ -858,36 +857,15 @@ static void set_fdc(int drive) | |||
858 | } | 857 | } |
859 | 858 | ||
860 | /* locks the driver */ | 859 | /* locks the driver */ |
861 | static int _lock_fdc(int drive, bool interruptible, int line) | 860 | static int lock_fdc(int drive, bool interruptible) |
862 | { | 861 | { |
863 | if (!usage_count) { | 862 | if (WARN(atomic_read(&usage_count) == 0, |
864 | pr_err("Trying to lock fdc while usage count=0 at line %d\n", | 863 | "Trying to lock fdc while usage count=0\n")) |
865 | line); | ||
866 | return -1; | 864 | return -1; |
867 | } | ||
868 | |||
869 | if (test_and_set_bit(0, &fdc_busy)) { | ||
870 | DECLARE_WAITQUEUE(wait, current); | ||
871 | add_wait_queue(&fdc_wait, &wait); | ||
872 | |||
873 | for (;;) { | ||
874 | set_current_state(TASK_INTERRUPTIBLE); | ||
875 | |||
876 | if (!test_and_set_bit(0, &fdc_busy)) | ||
877 | break; | ||
878 | 865 | ||
879 | schedule(); | 866 | if (wait_event_interruptible(fdc_wait, !test_and_set_bit(0, &fdc_busy))) |
880 | 867 | return -EINTR; | |
881 | if (!NO_SIGNAL) { | ||
882 | remove_wait_queue(&fdc_wait, &wait); | ||
883 | return -EINTR; | ||
884 | } | ||
885 | } | ||
886 | 868 | ||
887 | set_current_state(TASK_RUNNING); | ||
888 | remove_wait_queue(&fdc_wait, &wait); | ||
889 | flush_scheduled_work(); | ||
890 | } | ||
891 | command_status = FD_COMMAND_NONE; | 869 | command_status = FD_COMMAND_NONE; |
892 | 870 | ||
893 | __reschedule_timeout(drive, "lock fdc"); | 871 | __reschedule_timeout(drive, "lock fdc"); |
@@ -895,11 +873,8 @@ static int _lock_fdc(int drive, bool interruptible, int line) | |||
895 | return 0; | 873 | return 0; |
896 | } | 874 | } |
897 | 875 | ||
898 | #define lock_fdc(drive, interruptible) \ | ||
899 | _lock_fdc(drive, interruptible, __LINE__) | ||
900 | |||
901 | /* unlocks the driver */ | 876 | /* unlocks the driver */ |
902 | static inline void unlock_fdc(void) | 877 | static void unlock_fdc(void) |
903 | { | 878 | { |
904 | unsigned long flags; | 879 | unsigned long flags; |
905 | 880 | ||
@@ -1224,7 +1199,7 @@ static int need_more_output(void) | |||
1224 | /* Set perpendicular mode as required, based on data rate, if supported. | 1199 | /* Set perpendicular mode as required, based on data rate, if supported. |
1225 | * 82077 Now tested. 1Mbps data rate only possible with 82077-1. | 1200 | * 82077 Now tested. 1Mbps data rate only possible with 82077-1. |
1226 | */ | 1201 | */ |
1227 | static inline void perpendicular_mode(void) | 1202 | static void perpendicular_mode(void) |
1228 | { | 1203 | { |
1229 | unsigned char perp_mode; | 1204 | unsigned char perp_mode; |
1230 | 1205 | ||
@@ -1995,14 +1970,14 @@ static void do_wakeup(void) | |||
1995 | wake_up(&command_done); | 1970 | wake_up(&command_done); |
1996 | } | 1971 | } |
1997 | 1972 | ||
1998 | static struct cont_t wakeup_cont = { | 1973 | static const struct cont_t wakeup_cont = { |
1999 | .interrupt = empty, | 1974 | .interrupt = empty, |
2000 | .redo = do_wakeup, | 1975 | .redo = do_wakeup, |
2001 | .error = empty, | 1976 | .error = empty, |
2002 | .done = (done_f)empty | 1977 | .done = (done_f)empty |
2003 | }; | 1978 | }; |
2004 | 1979 | ||
2005 | static struct cont_t intr_cont = { | 1980 | static const struct cont_t intr_cont = { |
2006 | .interrupt = empty, | 1981 | .interrupt = empty, |
2007 | .redo = process_fd_request, | 1982 | .redo = process_fd_request, |
2008 | .error = empty, | 1983 | .error = empty, |
@@ -2015,25 +1990,10 @@ static int wait_til_done(void (*handler)(void), bool interruptible) | |||
2015 | 1990 | ||
2016 | schedule_bh(handler); | 1991 | schedule_bh(handler); |
2017 | 1992 | ||
2018 | if (command_status < 2 && NO_SIGNAL) { | 1993 | if (interruptible) |
2019 | DECLARE_WAITQUEUE(wait, current); | 1994 | wait_event_interruptible(command_done, command_status >= 2); |
2020 | 1995 | else | |
2021 | add_wait_queue(&command_done, &wait); | 1996 | wait_event(command_done, command_status >= 2); |
2022 | for (;;) { | ||
2023 | set_current_state(interruptible ? | ||
2024 | TASK_INTERRUPTIBLE : | ||
2025 | TASK_UNINTERRUPTIBLE); | ||
2026 | |||
2027 | if (command_status >= 2 || !NO_SIGNAL) | ||
2028 | break; | ||
2029 | |||
2030 | is_alive(__func__, ""); | ||
2031 | schedule(); | ||
2032 | } | ||
2033 | |||
2034 | set_current_state(TASK_RUNNING); | ||
2035 | remove_wait_queue(&command_done, &wait); | ||
2036 | } | ||
2037 | 1997 | ||
2038 | if (command_status < 2) { | 1998 | if (command_status < 2) { |
2039 | cancel_activity(); | 1999 | cancel_activity(); |
@@ -2223,7 +2183,7 @@ static void redo_format(void) | |||
2223 | debugt(__func__, "queue format request"); | 2183 | debugt(__func__, "queue format request"); |
2224 | } | 2184 | } |
2225 | 2185 | ||
2226 | static struct cont_t format_cont = { | 2186 | static const struct cont_t format_cont = { |
2227 | .interrupt = format_interrupt, | 2187 | .interrupt = format_interrupt, |
2228 | .redo = redo_format, | 2188 | .redo = redo_format, |
2229 | .error = bad_flp_intr, | 2189 | .error = bad_flp_intr, |
@@ -2583,10 +2543,8 @@ static int make_raw_rw_request(void) | |||
2583 | int tracksize; | 2543 | int tracksize; |
2584 | int ssize; | 2544 | int ssize; |
2585 | 2545 | ||
2586 | if (max_buffer_sectors == 0) { | 2546 | if (WARN(max_buffer_sectors == 0, "VFS: Block I/O scheduled on unopened device\n")) |
2587 | pr_info("VFS: Block I/O scheduled on unopened device\n"); | ||
2588 | return 0; | 2547 | return 0; |
2589 | } | ||
2590 | 2548 | ||
2591 | set_fdc((long)current_req->rq_disk->private_data); | 2549 | set_fdc((long)current_req->rq_disk->private_data); |
2592 | 2550 | ||
@@ -2921,7 +2879,7 @@ do_request: | |||
2921 | return; | 2879 | return; |
2922 | } | 2880 | } |
2923 | 2881 | ||
2924 | static struct cont_t rw_cont = { | 2882 | static const struct cont_t rw_cont = { |
2925 | .interrupt = rw_interrupt, | 2883 | .interrupt = rw_interrupt, |
2926 | .redo = redo_fd_request, | 2884 | .redo = redo_fd_request, |
2927 | .error = bad_flp_intr, | 2885 | .error = bad_flp_intr, |
@@ -2936,19 +2894,16 @@ static void process_fd_request(void) | |||
2936 | 2894 | ||
2937 | static void do_fd_request(struct request_queue *q) | 2895 | static void do_fd_request(struct request_queue *q) |
2938 | { | 2896 | { |
2939 | if (max_buffer_sectors == 0) { | 2897 | if (WARN(max_buffer_sectors == 0, |
2940 | pr_info("VFS: %s called on non-open device\n", __func__); | 2898 | "VFS: %s called on non-open device\n", __func__)) |
2941 | return; | 2899 | return; |
2942 | } | ||
2943 | 2900 | ||
2944 | if (usage_count == 0) { | 2901 | if (WARN(atomic_read(&usage_count) == 0, |
2945 | pr_info("warning: usage count=0, current_req=%p exiting\n", | 2902 | "warning: usage count=0, current_req=%p sect=%ld type=%x flags=%x\n", |
2946 | current_req); | 2903 | current_req, (long)blk_rq_pos(current_req), current_req->cmd_type, |
2947 | pr_info("sect=%ld type=%x flags=%x\n", | 2904 | current_req->cmd_flags)) |
2948 | (long)blk_rq_pos(current_req), current_req->cmd_type, | ||
2949 | current_req->cmd_flags); | ||
2950 | return; | 2905 | return; |
2951 | } | 2906 | |
2952 | if (test_bit(0, &fdc_busy)) { | 2907 | if (test_bit(0, &fdc_busy)) { |
2953 | /* fdc busy, this new request will be treated when the | 2908 | /* fdc busy, this new request will be treated when the |
2954 | current one is done */ | 2909 | current one is done */ |
@@ -2960,7 +2915,7 @@ static void do_fd_request(struct request_queue *q) | |||
2960 | is_alive(__func__, ""); | 2915 | is_alive(__func__, ""); |
2961 | } | 2916 | } |
2962 | 2917 | ||
2963 | static struct cont_t poll_cont = { | 2918 | static const struct cont_t poll_cont = { |
2964 | .interrupt = success_and_wakeup, | 2919 | .interrupt = success_and_wakeup, |
2965 | .redo = floppy_ready, | 2920 | .redo = floppy_ready, |
2966 | .error = generic_failure, | 2921 | .error = generic_failure, |
@@ -2991,7 +2946,7 @@ static void reset_intr(void) | |||
2991 | pr_info("weird, reset interrupt called\n"); | 2946 | pr_info("weird, reset interrupt called\n"); |
2992 | } | 2947 | } |
2993 | 2948 | ||
2994 | static struct cont_t reset_cont = { | 2949 | static const struct cont_t reset_cont = { |
2995 | .interrupt = reset_intr, | 2950 | .interrupt = reset_intr, |
2996 | .redo = success_and_wakeup, | 2951 | .redo = success_and_wakeup, |
2997 | .error = generic_failure, | 2952 | .error = generic_failure, |
@@ -3033,7 +2988,7 @@ static inline int fd_copyin(void __user *param, void *address, | |||
3033 | return copy_from_user(address, param, size) ? -EFAULT : 0; | 2988 | return copy_from_user(address, param, size) ? -EFAULT : 0; |
3034 | } | 2989 | } |
3035 | 2990 | ||
3036 | static inline const char *drive_name(int type, int drive) | 2991 | static const char *drive_name(int type, int drive) |
3037 | { | 2992 | { |
3038 | struct floppy_struct *floppy; | 2993 | struct floppy_struct *floppy; |
3039 | 2994 | ||
@@ -3096,14 +3051,14 @@ static void raw_cmd_done(int flag) | |||
3096 | generic_done(flag); | 3051 | generic_done(flag); |
3097 | } | 3052 | } |
3098 | 3053 | ||
3099 | static struct cont_t raw_cmd_cont = { | 3054 | static const struct cont_t raw_cmd_cont = { |
3100 | .interrupt = success_and_wakeup, | 3055 | .interrupt = success_and_wakeup, |
3101 | .redo = floppy_start, | 3056 | .redo = floppy_start, |
3102 | .error = generic_failure, | 3057 | .error = generic_failure, |
3103 | .done = raw_cmd_done | 3058 | .done = raw_cmd_done |
3104 | }; | 3059 | }; |
3105 | 3060 | ||
3106 | static inline int raw_cmd_copyout(int cmd, void __user *param, | 3061 | static int raw_cmd_copyout(int cmd, void __user *param, |
3107 | struct floppy_raw_cmd *ptr) | 3062 | struct floppy_raw_cmd *ptr) |
3108 | { | 3063 | { |
3109 | int ret; | 3064 | int ret; |
@@ -3148,7 +3103,7 @@ static void raw_cmd_free(struct floppy_raw_cmd **ptr) | |||
3148 | } | 3103 | } |
3149 | } | 3104 | } |
3150 | 3105 | ||
3151 | static inline int raw_cmd_copyin(int cmd, void __user *param, | 3106 | static int raw_cmd_copyin(int cmd, void __user *param, |
3152 | struct floppy_raw_cmd **rcmd) | 3107 | struct floppy_raw_cmd **rcmd) |
3153 | { | 3108 | { |
3154 | struct floppy_raw_cmd *ptr; | 3109 | struct floppy_raw_cmd *ptr; |
@@ -3266,7 +3221,7 @@ static int invalidate_drive(struct block_device *bdev) | |||
3266 | return 0; | 3221 | return 0; |
3267 | } | 3222 | } |
3268 | 3223 | ||
3269 | static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, | 3224 | static int set_geometry(unsigned int cmd, struct floppy_struct *g, |
3270 | int drive, int type, struct block_device *bdev) | 3225 | int drive, int type, struct block_device *bdev) |
3271 | { | 3226 | { |
3272 | int cnt; | 3227 | int cnt; |
@@ -3337,7 +3292,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, | |||
3337 | } | 3292 | } |
3338 | 3293 | ||
3339 | /* handle obsolete ioctl's */ | 3294 | /* handle obsolete ioctl's */ |
3340 | static int ioctl_table[] = { | 3295 | static unsigned int ioctl_table[] = { |
3341 | FDCLRPRM, | 3296 | FDCLRPRM, |
3342 | FDSETPRM, | 3297 | FDSETPRM, |
3343 | FDDEFPRM, | 3298 | FDDEFPRM, |
@@ -3365,7 +3320,7 @@ static int ioctl_table[] = { | |||
3365 | FDTWADDLE | 3320 | FDTWADDLE |
3366 | }; | 3321 | }; |
3367 | 3322 | ||
3368 | static inline int normalize_ioctl(int *cmd, int *size) | 3323 | static int normalize_ioctl(unsigned int *cmd, int *size) |
3369 | { | 3324 | { |
3370 | int i; | 3325 | int i; |
3371 | 3326 | ||
@@ -3417,7 +3372,7 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
3417 | return 0; | 3372 | return 0; |
3418 | } | 3373 | } |
3419 | 3374 | ||
3420 | static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | 3375 | static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, |
3421 | unsigned long param) | 3376 | unsigned long param) |
3422 | { | 3377 | { |
3423 | int drive = (long)bdev->bd_disk->private_data; | 3378 | int drive = (long)bdev->bd_disk->private_data; |
@@ -3593,6 +3548,18 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | |||
3593 | return 0; | 3548 | return 0; |
3594 | } | 3549 | } |
3595 | 3550 | ||
3551 | static int fd_ioctl(struct block_device *bdev, fmode_t mode, | ||
3552 | unsigned int cmd, unsigned long param) | ||
3553 | { | ||
3554 | int ret; | ||
3555 | |||
3556 | lock_kernel(); | ||
3557 | ret = fd_locked_ioctl(bdev, mode, cmd, param); | ||
3558 | unlock_kernel(); | ||
3559 | |||
3560 | return ret; | ||
3561 | } | ||
3562 | |||
3596 | static void __init config_types(void) | 3563 | static void __init config_types(void) |
3597 | { | 3564 | { |
3598 | bool has_drive = false; | 3565 | bool has_drive = false; |
@@ -3649,6 +3616,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) | |||
3649 | { | 3616 | { |
3650 | int drive = (long)disk->private_data; | 3617 | int drive = (long)disk->private_data; |
3651 | 3618 | ||
3619 | lock_kernel(); | ||
3652 | mutex_lock(&open_lock); | 3620 | mutex_lock(&open_lock); |
3653 | if (UDRS->fd_ref < 0) | 3621 | if (UDRS->fd_ref < 0) |
3654 | UDRS->fd_ref = 0; | 3622 | UDRS->fd_ref = 0; |
@@ -3659,6 +3627,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) | |||
3659 | if (!UDRS->fd_ref) | 3627 | if (!UDRS->fd_ref) |
3660 | opened_bdev[drive] = NULL; | 3628 | opened_bdev[drive] = NULL; |
3661 | mutex_unlock(&open_lock); | 3629 | mutex_unlock(&open_lock); |
3630 | unlock_kernel(); | ||
3662 | 3631 | ||
3663 | return 0; | 3632 | return 0; |
3664 | } | 3633 | } |
@@ -3676,6 +3645,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
3676 | int res = -EBUSY; | 3645 | int res = -EBUSY; |
3677 | char *tmp; | 3646 | char *tmp; |
3678 | 3647 | ||
3648 | lock_kernel(); | ||
3679 | mutex_lock(&open_lock); | 3649 | mutex_lock(&open_lock); |
3680 | old_dev = UDRS->fd_device; | 3650 | old_dev = UDRS->fd_device; |
3681 | if (opened_bdev[drive] && opened_bdev[drive] != bdev) | 3651 | if (opened_bdev[drive] && opened_bdev[drive] != bdev) |
@@ -3752,6 +3722,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
3752 | goto out; | 3722 | goto out; |
3753 | } | 3723 | } |
3754 | mutex_unlock(&open_lock); | 3724 | mutex_unlock(&open_lock); |
3725 | unlock_kernel(); | ||
3755 | return 0; | 3726 | return 0; |
3756 | out: | 3727 | out: |
3757 | if (UDRS->fd_ref < 0) | 3728 | if (UDRS->fd_ref < 0) |
@@ -3762,6 +3733,7 @@ out: | |||
3762 | opened_bdev[drive] = NULL; | 3733 | opened_bdev[drive] = NULL; |
3763 | out2: | 3734 | out2: |
3764 | mutex_unlock(&open_lock); | 3735 | mutex_unlock(&open_lock); |
3736 | unlock_kernel(); | ||
3765 | return res; | 3737 | return res; |
3766 | } | 3738 | } |
3767 | 3739 | ||
@@ -3829,6 +3801,7 @@ static int __floppy_read_block_0(struct block_device *bdev) | |||
3829 | bio.bi_size = size; | 3801 | bio.bi_size = size; |
3830 | bio.bi_bdev = bdev; | 3802 | bio.bi_bdev = bdev; |
3831 | bio.bi_sector = 0; | 3803 | bio.bi_sector = 0; |
3804 | bio.bi_flags = BIO_QUIET; | ||
3832 | init_completion(&complete); | 3805 | init_completion(&complete); |
3833 | bio.bi_private = &complete; | 3806 | bio.bi_private = &complete; |
3834 | bio.bi_end_io = floppy_rb0_complete; | 3807 | bio.bi_end_io = floppy_rb0_complete; |
@@ -3857,10 +3830,10 @@ static int floppy_revalidate(struct gendisk *disk) | |||
3857 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || | 3830 | if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || |
3858 | test_bit(FD_VERIFY_BIT, &UDRS->flags) || | 3831 | test_bit(FD_VERIFY_BIT, &UDRS->flags) || |
3859 | test_bit(drive, &fake_change) || NO_GEOM) { | 3832 | test_bit(drive, &fake_change) || NO_GEOM) { |
3860 | if (usage_count == 0) { | 3833 | if (WARN(atomic_read(&usage_count) == 0, |
3861 | pr_info("VFS: revalidate called on non-open device.\n"); | 3834 | "VFS: revalidate called on non-open device.\n")) |
3862 | return -EFAULT; | 3835 | return -EFAULT; |
3863 | } | 3836 | |
3864 | lock_fdc(drive, false); | 3837 | lock_fdc(drive, false); |
3865 | cf = (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || | 3838 | cf = (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || |
3866 | test_bit(FD_VERIFY_BIT, &UDRS->flags)); | 3839 | test_bit(FD_VERIFY_BIT, &UDRS->flags)); |
@@ -3893,7 +3866,7 @@ static const struct block_device_operations floppy_fops = { | |||
3893 | .owner = THIS_MODULE, | 3866 | .owner = THIS_MODULE, |
3894 | .open = floppy_open, | 3867 | .open = floppy_open, |
3895 | .release = floppy_release, | 3868 | .release = floppy_release, |
3896 | .locked_ioctl = fd_ioctl, | 3869 | .ioctl = fd_ioctl, |
3897 | .getgeo = fd_getgeo, | 3870 | .getgeo = fd_getgeo, |
3898 | .media_changed = check_floppy_change, | 3871 | .media_changed = check_floppy_change, |
3899 | .revalidate_disk = floppy_revalidate, | 3872 | .revalidate_disk = floppy_revalidate, |
@@ -4126,7 +4099,7 @@ static ssize_t floppy_cmos_show(struct device *dev, | |||
4126 | return sprintf(buf, "%X\n", UDP->cmos); | 4099 | return sprintf(buf, "%X\n", UDP->cmos); |
4127 | } | 4100 | } |
4128 | 4101 | ||
4129 | DEVICE_ATTR(cmos, S_IRUGO, floppy_cmos_show, NULL); | 4102 | static DEVICE_ATTR(cmos, S_IRUGO, floppy_cmos_show, NULL); |
4130 | 4103 | ||
4131 | static void floppy_device_release(struct device *dev) | 4104 | static void floppy_device_release(struct device *dev) |
4132 | { | 4105 | { |
@@ -4175,6 +4148,9 @@ static int __init floppy_init(void) | |||
4175 | int i, unit, drive; | 4148 | int i, unit, drive; |
4176 | int err, dr; | 4149 | int err, dr; |
4177 | 4150 | ||
4151 | set_debugt(); | ||
4152 | interruptjiffies = resultjiffies = jiffies; | ||
4153 | |||
4178 | #if defined(CONFIG_PPC) | 4154 | #if defined(CONFIG_PPC) |
4179 | if (check_legacy_ioport(FDC1)) | 4155 | if (check_legacy_ioport(FDC1)) |
4180 | return -ENODEV; | 4156 | return -ENODEV; |
@@ -4353,7 +4329,7 @@ out_unreg_platform_dev: | |||
4353 | platform_device_unregister(&floppy_device[drive]); | 4329 | platform_device_unregister(&floppy_device[drive]); |
4354 | out_flush_work: | 4330 | out_flush_work: |
4355 | flush_scheduled_work(); | 4331 | flush_scheduled_work(); |
4356 | if (usage_count) | 4332 | if (atomic_read(&usage_count)) |
4357 | floppy_release_irq_and_dma(); | 4333 | floppy_release_irq_and_dma(); |
4358 | out_unreg_region: | 4334 | out_unreg_region: |
4359 | blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); | 4335 | blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256); |
@@ -4370,8 +4346,6 @@ out_put_disk: | |||
4370 | return err; | 4346 | return err; |
4371 | } | 4347 | } |
4372 | 4348 | ||
4373 | static DEFINE_SPINLOCK(floppy_usage_lock); | ||
4374 | |||
4375 | static const struct io_region { | 4349 | static const struct io_region { |
4376 | int offset; | 4350 | int offset; |
4377 | int size; | 4351 | int size; |
@@ -4417,14 +4391,8 @@ static void floppy_release_regions(int fdc) | |||
4417 | 4391 | ||
4418 | static int floppy_grab_irq_and_dma(void) | 4392 | static int floppy_grab_irq_and_dma(void) |
4419 | { | 4393 | { |
4420 | unsigned long flags; | 4394 | if (atomic_inc_return(&usage_count) > 1) |
4421 | |||
4422 | spin_lock_irqsave(&floppy_usage_lock, flags); | ||
4423 | if (usage_count++) { | ||
4424 | spin_unlock_irqrestore(&floppy_usage_lock, flags); | ||
4425 | return 0; | 4395 | return 0; |
4426 | } | ||
4427 | spin_unlock_irqrestore(&floppy_usage_lock, flags); | ||
4428 | 4396 | ||
4429 | /* | 4397 | /* |
4430 | * We might have scheduled a free_irq(), wait it to | 4398 | * We might have scheduled a free_irq(), wait it to |
@@ -4435,9 +4403,7 @@ static int floppy_grab_irq_and_dma(void) | |||
4435 | if (fd_request_irq()) { | 4403 | if (fd_request_irq()) { |
4436 | DPRINT("Unable to grab IRQ%d for the floppy driver\n", | 4404 | DPRINT("Unable to grab IRQ%d for the floppy driver\n", |
4437 | FLOPPY_IRQ); | 4405 | FLOPPY_IRQ); |
4438 | spin_lock_irqsave(&floppy_usage_lock, flags); | 4406 | atomic_dec(&usage_count); |
4439 | usage_count--; | ||
4440 | spin_unlock_irqrestore(&floppy_usage_lock, flags); | ||
4441 | return -1; | 4407 | return -1; |
4442 | } | 4408 | } |
4443 | if (fd_request_dma()) { | 4409 | if (fd_request_dma()) { |
@@ -4447,9 +4413,7 @@ static int floppy_grab_irq_and_dma(void) | |||
4447 | use_virtual_dma = can_use_virtual_dma = 1; | 4413 | use_virtual_dma = can_use_virtual_dma = 1; |
4448 | if (!(can_use_virtual_dma & 1)) { | 4414 | if (!(can_use_virtual_dma & 1)) { |
4449 | fd_free_irq(); | 4415 | fd_free_irq(); |
4450 | spin_lock_irqsave(&floppy_usage_lock, flags); | 4416 | atomic_dec(&usage_count); |
4451 | usage_count--; | ||
4452 | spin_unlock_irqrestore(&floppy_usage_lock, flags); | ||
4453 | return -1; | 4417 | return -1; |
4454 | } | 4418 | } |
4455 | } | 4419 | } |
@@ -4484,9 +4448,7 @@ cleanup: | |||
4484 | fd_free_dma(); | 4448 | fd_free_dma(); |
4485 | while (--fdc >= 0) | 4449 | while (--fdc >= 0) |
4486 | floppy_release_regions(fdc); | 4450 | floppy_release_regions(fdc); |
4487 | spin_lock_irqsave(&floppy_usage_lock, flags); | 4451 | atomic_dec(&usage_count); |
4488 | usage_count--; | ||
4489 | spin_unlock_irqrestore(&floppy_usage_lock, flags); | ||
4490 | return -1; | 4452 | return -1; |
4491 | } | 4453 | } |
4492 | 4454 | ||
@@ -4498,14 +4460,10 @@ static void floppy_release_irq_and_dma(void) | |||
4498 | #endif | 4460 | #endif |
4499 | long tmpsize; | 4461 | long tmpsize; |
4500 | unsigned long tmpaddr; | 4462 | unsigned long tmpaddr; |
4501 | unsigned long flags; | ||
4502 | 4463 | ||
4503 | spin_lock_irqsave(&floppy_usage_lock, flags); | 4464 | if (!atomic_dec_and_test(&usage_count)) |
4504 | if (--usage_count) { | ||
4505 | spin_unlock_irqrestore(&floppy_usage_lock, flags); | ||
4506 | return; | 4465 | return; |
4507 | } | 4466 | |
4508 | spin_unlock_irqrestore(&floppy_usage_lock, flags); | ||
4509 | if (irqdma_allocated) { | 4467 | if (irqdma_allocated) { |
4510 | fd_disable_dma(); | 4468 | fd_disable_dma(); |
4511 | fd_free_dma(); | 4469 | fd_free_dma(); |
@@ -4598,7 +4556,7 @@ static void __exit floppy_module_exit(void) | |||
4598 | del_timer_sync(&fd_timer); | 4556 | del_timer_sync(&fd_timer); |
4599 | blk_cleanup_queue(floppy_queue); | 4557 | blk_cleanup_queue(floppy_queue); |
4600 | 4558 | ||
4601 | if (usage_count) | 4559 | if (atomic_read(&usage_count)) |
4602 | floppy_release_irq_and_dma(); | 4560 | floppy_release_irq_and_dma(); |
4603 | 4561 | ||
4604 | /* eject disk, if any */ | 4562 | /* eject disk, if any */ |
diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 81c78b3ce2df..30ec6b37424e 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c | |||
@@ -627,7 +627,7 @@ repeat: | |||
627 | req_data_dir(req) == READ ? "read" : "writ", | 627 | req_data_dir(req) == READ ? "read" : "writ", |
628 | cyl, head, sec, nsect, req->buffer); | 628 | cyl, head, sec, nsect, req->buffer); |
629 | #endif | 629 | #endif |
630 | if (blk_fs_request(req)) { | 630 | if (req->cmd_type == REQ_TYPE_FS) { |
631 | switch (rq_data_dir(req)) { | 631 | switch (rq_data_dir(req)) { |
632 | case READ: | 632 | case READ: |
633 | hd_out(disk, nsect, sec, head, cyl, ATA_CMD_PIO_READ, | 633 | hd_out(disk, nsect, sec, head, cyl, ATA_CMD_PIO_READ, |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 6120922f459f..f3c636d23718 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #include <linux/compat.h> | 67 | #include <linux/compat.h> |
68 | #include <linux/suspend.h> | 68 | #include <linux/suspend.h> |
69 | #include <linux/freezer.h> | 69 | #include <linux/freezer.h> |
70 | #include <linux/smp_lock.h> | ||
70 | #include <linux/writeback.h> | 71 | #include <linux/writeback.h> |
71 | #include <linux/buffer_head.h> /* for invalidate_bdev() */ | 72 | #include <linux/buffer_head.h> /* for invalidate_bdev() */ |
72 | #include <linux/completion.h> | 73 | #include <linux/completion.h> |
@@ -476,7 +477,7 @@ static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) | |||
476 | pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; | 477 | pos = ((loff_t) bio->bi_sector << 9) + lo->lo_offset; |
477 | 478 | ||
478 | if (bio_rw(bio) == WRITE) { | 479 | if (bio_rw(bio) == WRITE) { |
479 | bool barrier = bio_rw_flagged(bio, BIO_RW_BARRIER); | 480 | bool barrier = (bio->bi_rw & REQ_HARDBARRIER); |
480 | struct file *file = lo->lo_backing_file; | 481 | struct file *file = lo->lo_backing_file; |
481 | 482 | ||
482 | if (barrier) { | 483 | if (barrier) { |
@@ -831,7 +832,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, | |||
831 | lo->lo_queue->unplug_fn = loop_unplug; | 832 | lo->lo_queue->unplug_fn = loop_unplug; |
832 | 833 | ||
833 | if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) | 834 | if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync) |
834 | blk_queue_ordered(lo->lo_queue, QUEUE_ORDERED_DRAIN, NULL); | 835 | blk_queue_ordered(lo->lo_queue, QUEUE_ORDERED_DRAIN); |
835 | 836 | ||
836 | set_capacity(lo->lo_disk, size); | 837 | set_capacity(lo->lo_disk, size); |
837 | bd_set_size(bdev, size << 9); | 838 | bd_set_size(bdev, size << 9); |
@@ -1408,9 +1409,11 @@ static int lo_open(struct block_device *bdev, fmode_t mode) | |||
1408 | { | 1409 | { |
1409 | struct loop_device *lo = bdev->bd_disk->private_data; | 1410 | struct loop_device *lo = bdev->bd_disk->private_data; |
1410 | 1411 | ||
1412 | lock_kernel(); | ||
1411 | mutex_lock(&lo->lo_ctl_mutex); | 1413 | mutex_lock(&lo->lo_ctl_mutex); |
1412 | lo->lo_refcnt++; | 1414 | lo->lo_refcnt++; |
1413 | mutex_unlock(&lo->lo_ctl_mutex); | 1415 | mutex_unlock(&lo->lo_ctl_mutex); |
1416 | unlock_kernel(); | ||
1414 | 1417 | ||
1415 | return 0; | 1418 | return 0; |
1416 | } | 1419 | } |
@@ -1420,6 +1423,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode) | |||
1420 | struct loop_device *lo = disk->private_data; | 1423 | struct loop_device *lo = disk->private_data; |
1421 | int err; | 1424 | int err; |
1422 | 1425 | ||
1426 | lock_kernel(); | ||
1423 | mutex_lock(&lo->lo_ctl_mutex); | 1427 | mutex_lock(&lo->lo_ctl_mutex); |
1424 | 1428 | ||
1425 | if (--lo->lo_refcnt) | 1429 | if (--lo->lo_refcnt) |
@@ -1444,6 +1448,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode) | |||
1444 | out: | 1448 | out: |
1445 | mutex_unlock(&lo->lo_ctl_mutex); | 1449 | mutex_unlock(&lo->lo_ctl_mutex); |
1446 | out_unlocked: | 1450 | out_unlocked: |
1451 | lock_kernel(); | ||
1447 | return 0; | 1452 | return 0; |
1448 | } | 1453 | } |
1449 | 1454 | ||
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index 28db925dbdad..b82c5ce5e9df 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c | |||
@@ -670,7 +670,7 @@ static void mg_request_poll(struct request_queue *q) | |||
670 | break; | 670 | break; |
671 | } | 671 | } |
672 | 672 | ||
673 | if (unlikely(!blk_fs_request(host->req))) { | 673 | if (unlikely(host->req->cmd_type != REQ_TYPE_FS)) { |
674 | mg_end_request_cur(host, -EIO); | 674 | mg_end_request_cur(host, -EIO); |
675 | continue; | 675 | continue; |
676 | } | 676 | } |
@@ -756,7 +756,7 @@ static void mg_request(struct request_queue *q) | |||
756 | continue; | 756 | continue; |
757 | } | 757 | } |
758 | 758 | ||
759 | if (unlikely(!blk_fs_request(req))) { | 759 | if (unlikely(req->cmd_type != REQ_TYPE_FS)) { |
760 | mg_end_request_cur(host, -EIO); | 760 | mg_end_request_cur(host, -EIO); |
761 | continue; | 761 | continue; |
762 | } | 762 | } |
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 16c3c8613cd3..0daa422aa281 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/file.h> | 25 | #include <linux/file.h> |
26 | #include <linux/ioctl.h> | 26 | #include <linux/ioctl.h> |
27 | #include <linux/smp_lock.h> | ||
27 | #include <linux/compiler.h> | 28 | #include <linux/compiler.h> |
28 | #include <linux/err.h> | 29 | #include <linux/err.h> |
29 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
@@ -448,7 +449,7 @@ static void nbd_clear_que(struct nbd_device *lo) | |||
448 | 449 | ||
449 | static void nbd_handle_req(struct nbd_device *lo, struct request *req) | 450 | static void nbd_handle_req(struct nbd_device *lo, struct request *req) |
450 | { | 451 | { |
451 | if (!blk_fs_request(req)) | 452 | if (req->cmd_type != REQ_TYPE_FS) |
452 | goto error_out; | 453 | goto error_out; |
453 | 454 | ||
454 | nbd_cmd(req) = NBD_CMD_READ; | 455 | nbd_cmd(req) = NBD_CMD_READ; |
@@ -716,9 +717,11 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode, | |||
716 | dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n", | 717 | dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n", |
717 | lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg); | 718 | lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg); |
718 | 719 | ||
720 | lock_kernel(); | ||
719 | mutex_lock(&lo->tx_lock); | 721 | mutex_lock(&lo->tx_lock); |
720 | error = __nbd_ioctl(bdev, lo, cmd, arg); | 722 | error = __nbd_ioctl(bdev, lo, cmd, arg); |
721 | mutex_unlock(&lo->tx_lock); | 723 | mutex_unlock(&lo->tx_lock); |
724 | unlock_kernel(); | ||
722 | 725 | ||
723 | return error; | 726 | return error; |
724 | } | 727 | } |
@@ -726,7 +729,7 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode, | |||
726 | static const struct block_device_operations nbd_fops = | 729 | static const struct block_device_operations nbd_fops = |
727 | { | 730 | { |
728 | .owner = THIS_MODULE, | 731 | .owner = THIS_MODULE, |
729 | .locked_ioctl = nbd_ioctl, | 732 | .ioctl = nbd_ioctl, |
730 | }; | 733 | }; |
731 | 734 | ||
732 | /* | 735 | /* |
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c index 6cd8b705b11b..2284b4f05c62 100644 --- a/drivers/block/osdblk.c +++ b/drivers/block/osdblk.c | |||
@@ -310,7 +310,8 @@ static void osdblk_rq_fn(struct request_queue *q) | |||
310 | break; | 310 | break; |
311 | 311 | ||
312 | /* filter out block requests we don't understand */ | 312 | /* filter out block requests we don't understand */ |
313 | if (!blk_fs_request(rq) && !blk_barrier_rq(rq)) { | 313 | if (rq->cmd_type != REQ_TYPE_FS && |
314 | !(rq->cmd_flags & REQ_HARDBARRIER)) { | ||
314 | blk_end_request_all(rq, 0); | 315 | blk_end_request_all(rq, 0); |
315 | continue; | 316 | continue; |
316 | } | 317 | } |
@@ -322,7 +323,7 @@ static void osdblk_rq_fn(struct request_queue *q) | |||
322 | * driver-specific, etc. | 323 | * driver-specific, etc. |
323 | */ | 324 | */ |
324 | 325 | ||
325 | do_flush = (rq->special == (void *) 0xdeadbeefUL); | 326 | do_flush = rq->cmd_flags & REQ_FLUSH; |
326 | do_write = (rq_data_dir(rq) == WRITE); | 327 | do_write = (rq_data_dir(rq) == WRITE); |
327 | 328 | ||
328 | if (!do_flush) { /* osd_flush does not use a bio */ | 329 | if (!do_flush) { /* osd_flush does not use a bio */ |
@@ -379,14 +380,6 @@ static void osdblk_rq_fn(struct request_queue *q) | |||
379 | } | 380 | } |
380 | } | 381 | } |
381 | 382 | ||
382 | static void osdblk_prepare_flush(struct request_queue *q, struct request *rq) | ||
383 | { | ||
384 | /* add driver-specific marker, to indicate that this request | ||
385 | * is a flush command | ||
386 | */ | ||
387 | rq->special = (void *) 0xdeadbeefUL; | ||
388 | } | ||
389 | |||
390 | static void osdblk_free_disk(struct osdblk_device *osdev) | 383 | static void osdblk_free_disk(struct osdblk_device *osdev) |
391 | { | 384 | { |
392 | struct gendisk *disk = osdev->disk; | 385 | struct gendisk *disk = osdev->disk; |
@@ -446,7 +439,7 @@ static int osdblk_init_disk(struct osdblk_device *osdev) | |||
446 | blk_queue_stack_limits(q, osd_request_queue(osdev->osd)); | 439 | blk_queue_stack_limits(q, osd_request_queue(osdev->osd)); |
447 | 440 | ||
448 | blk_queue_prep_rq(q, blk_queue_start_tag); | 441 | blk_queue_prep_rq(q, blk_queue_start_tag); |
449 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH, osdblk_prepare_flush); | 442 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH); |
450 | 443 | ||
451 | disk->queue = q; | 444 | disk->queue = q; |
452 | 445 | ||
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 71acf4e53356..76f8565e1e8d 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c | |||
@@ -138,6 +138,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY}; | |||
138 | #include <linux/cdrom.h> | 138 | #include <linux/cdrom.h> |
139 | #include <linux/spinlock.h> | 139 | #include <linux/spinlock.h> |
140 | #include <linux/blkdev.h> | 140 | #include <linux/blkdev.h> |
141 | #include <linux/smp_lock.h> | ||
141 | #include <asm/uaccess.h> | 142 | #include <asm/uaccess.h> |
142 | 143 | ||
143 | static DEFINE_SPINLOCK(pcd_lock); | 144 | static DEFINE_SPINLOCK(pcd_lock); |
@@ -224,13 +225,21 @@ static char *pcd_buf; /* buffer for request in progress */ | |||
224 | static int pcd_block_open(struct block_device *bdev, fmode_t mode) | 225 | static int pcd_block_open(struct block_device *bdev, fmode_t mode) |
225 | { | 226 | { |
226 | struct pcd_unit *cd = bdev->bd_disk->private_data; | 227 | struct pcd_unit *cd = bdev->bd_disk->private_data; |
227 | return cdrom_open(&cd->info, bdev, mode); | 228 | int ret; |
229 | |||
230 | lock_kernel(); | ||
231 | ret = cdrom_open(&cd->info, bdev, mode); | ||
232 | unlock_kernel(); | ||
233 | |||
234 | return ret; | ||
228 | } | 235 | } |
229 | 236 | ||
230 | static int pcd_block_release(struct gendisk *disk, fmode_t mode) | 237 | static int pcd_block_release(struct gendisk *disk, fmode_t mode) |
231 | { | 238 | { |
232 | struct pcd_unit *cd = disk->private_data; | 239 | struct pcd_unit *cd = disk->private_data; |
240 | lock_kernel(); | ||
233 | cdrom_release(&cd->info, mode); | 241 | cdrom_release(&cd->info, mode); |
242 | unlock_kernel(); | ||
234 | return 0; | 243 | return 0; |
235 | } | 244 | } |
236 | 245 | ||
@@ -238,7 +247,13 @@ static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode, | |||
238 | unsigned cmd, unsigned long arg) | 247 | unsigned cmd, unsigned long arg) |
239 | { | 248 | { |
240 | struct pcd_unit *cd = bdev->bd_disk->private_data; | 249 | struct pcd_unit *cd = bdev->bd_disk->private_data; |
241 | return cdrom_ioctl(&cd->info, bdev, mode, cmd, arg); | 250 | int ret; |
251 | |||
252 | lock_kernel(); | ||
253 | ret = cdrom_ioctl(&cd->info, bdev, mode, cmd, arg); | ||
254 | unlock_kernel(); | ||
255 | |||
256 | return ret; | ||
242 | } | 257 | } |
243 | 258 | ||
244 | static int pcd_block_media_changed(struct gendisk *disk) | 259 | static int pcd_block_media_changed(struct gendisk *disk) |
@@ -251,7 +266,7 @@ static const struct block_device_operations pcd_bdops = { | |||
251 | .owner = THIS_MODULE, | 266 | .owner = THIS_MODULE, |
252 | .open = pcd_block_open, | 267 | .open = pcd_block_open, |
253 | .release = pcd_block_release, | 268 | .release = pcd_block_release, |
254 | .locked_ioctl = pcd_block_ioctl, | 269 | .ioctl = pcd_block_ioctl, |
255 | .media_changed = pcd_block_media_changed, | 270 | .media_changed = pcd_block_media_changed, |
256 | }; | 271 | }; |
257 | 272 | ||
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index c1e5cd029b23..985f0d4f1d1e 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c | |||
@@ -153,6 +153,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV}; | |||
153 | #include <linux/blkdev.h> | 153 | #include <linux/blkdev.h> |
154 | #include <linux/blkpg.h> | 154 | #include <linux/blkpg.h> |
155 | #include <linux/kernel.h> | 155 | #include <linux/kernel.h> |
156 | #include <linux/smp_lock.h> | ||
156 | #include <asm/uaccess.h> | 157 | #include <asm/uaccess.h> |
157 | #include <linux/workqueue.h> | 158 | #include <linux/workqueue.h> |
158 | 159 | ||
@@ -439,7 +440,7 @@ static char *pd_buf; /* buffer for request in progress */ | |||
439 | 440 | ||
440 | static enum action do_pd_io_start(void) | 441 | static enum action do_pd_io_start(void) |
441 | { | 442 | { |
442 | if (blk_special_request(pd_req)) { | 443 | if (pd_req->cmd_type == REQ_TYPE_SPECIAL) { |
443 | phase = pd_special; | 444 | phase = pd_special; |
444 | return pd_special(); | 445 | return pd_special(); |
445 | } | 446 | } |
@@ -735,12 +736,14 @@ static int pd_open(struct block_device *bdev, fmode_t mode) | |||
735 | { | 736 | { |
736 | struct pd_unit *disk = bdev->bd_disk->private_data; | 737 | struct pd_unit *disk = bdev->bd_disk->private_data; |
737 | 738 | ||
739 | lock_kernel(); | ||
738 | disk->access++; | 740 | disk->access++; |
739 | 741 | ||
740 | if (disk->removable) { | 742 | if (disk->removable) { |
741 | pd_special_command(disk, pd_media_check); | 743 | pd_special_command(disk, pd_media_check); |
742 | pd_special_command(disk, pd_door_lock); | 744 | pd_special_command(disk, pd_door_lock); |
743 | } | 745 | } |
746 | unlock_kernel(); | ||
744 | return 0; | 747 | return 0; |
745 | } | 748 | } |
746 | 749 | ||
@@ -768,8 +771,10 @@ static int pd_ioctl(struct block_device *bdev, fmode_t mode, | |||
768 | 771 | ||
769 | switch (cmd) { | 772 | switch (cmd) { |
770 | case CDROMEJECT: | 773 | case CDROMEJECT: |
774 | lock_kernel(); | ||
771 | if (disk->access == 1) | 775 | if (disk->access == 1) |
772 | pd_special_command(disk, pd_eject); | 776 | pd_special_command(disk, pd_eject); |
777 | unlock_kernel(); | ||
773 | return 0; | 778 | return 0; |
774 | default: | 779 | default: |
775 | return -EINVAL; | 780 | return -EINVAL; |
@@ -780,8 +785,10 @@ static int pd_release(struct gendisk *p, fmode_t mode) | |||
780 | { | 785 | { |
781 | struct pd_unit *disk = p->private_data; | 786 | struct pd_unit *disk = p->private_data; |
782 | 787 | ||
788 | lock_kernel(); | ||
783 | if (!--disk->access && disk->removable) | 789 | if (!--disk->access && disk->removable) |
784 | pd_special_command(disk, pd_door_unlock); | 790 | pd_special_command(disk, pd_door_unlock); |
791 | unlock_kernel(); | ||
785 | 792 | ||
786 | return 0; | 793 | return 0; |
787 | } | 794 | } |
@@ -812,7 +819,7 @@ static const struct block_device_operations pd_fops = { | |||
812 | .owner = THIS_MODULE, | 819 | .owner = THIS_MODULE, |
813 | .open = pd_open, | 820 | .open = pd_open, |
814 | .release = pd_release, | 821 | .release = pd_release, |
815 | .locked_ioctl = pd_ioctl, | 822 | .ioctl = pd_ioctl, |
816 | .getgeo = pd_getgeo, | 823 | .getgeo = pd_getgeo, |
817 | .media_changed = pd_check_media, | 824 | .media_changed = pd_check_media, |
818 | .revalidate_disk= pd_revalidate | 825 | .revalidate_disk= pd_revalidate |
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index c059aab3006b..4457b494882a 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c | |||
@@ -152,6 +152,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY}; | |||
152 | #include <linux/spinlock.h> | 152 | #include <linux/spinlock.h> |
153 | #include <linux/blkdev.h> | 153 | #include <linux/blkdev.h> |
154 | #include <linux/blkpg.h> | 154 | #include <linux/blkpg.h> |
155 | #include <linux/smp_lock.h> | ||
155 | #include <asm/uaccess.h> | 156 | #include <asm/uaccess.h> |
156 | 157 | ||
157 | static DEFINE_SPINLOCK(pf_spin_lock); | 158 | static DEFINE_SPINLOCK(pf_spin_lock); |
@@ -266,7 +267,7 @@ static const struct block_device_operations pf_fops = { | |||
266 | .owner = THIS_MODULE, | 267 | .owner = THIS_MODULE, |
267 | .open = pf_open, | 268 | .open = pf_open, |
268 | .release = pf_release, | 269 | .release = pf_release, |
269 | .locked_ioctl = pf_ioctl, | 270 | .ioctl = pf_ioctl, |
270 | .getgeo = pf_getgeo, | 271 | .getgeo = pf_getgeo, |
271 | .media_changed = pf_check_media, | 272 | .media_changed = pf_check_media, |
272 | }; | 273 | }; |
@@ -299,20 +300,26 @@ static void __init pf_init_units(void) | |||
299 | static int pf_open(struct block_device *bdev, fmode_t mode) | 300 | static int pf_open(struct block_device *bdev, fmode_t mode) |
300 | { | 301 | { |
301 | struct pf_unit *pf = bdev->bd_disk->private_data; | 302 | struct pf_unit *pf = bdev->bd_disk->private_data; |
303 | int ret; | ||
302 | 304 | ||
305 | lock_kernel(); | ||
303 | pf_identify(pf); | 306 | pf_identify(pf); |
304 | 307 | ||
308 | ret = -ENODEV; | ||
305 | if (pf->media_status == PF_NM) | 309 | if (pf->media_status == PF_NM) |
306 | return -ENODEV; | 310 | goto out; |
307 | 311 | ||
312 | ret = -EROFS; | ||
308 | if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE)) | 313 | if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE)) |
309 | return -EROFS; | 314 | goto out; |
310 | 315 | ||
316 | ret = 0; | ||
311 | pf->access++; | 317 | pf->access++; |
312 | if (pf->removable) | 318 | if (pf->removable) |
313 | pf_lock(pf, 1); | 319 | pf_lock(pf, 1); |
314 | 320 | out: | |
315 | return 0; | 321 | unlock_kernel(); |
322 | return ret; | ||
316 | } | 323 | } |
317 | 324 | ||
318 | static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo) | 325 | static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
@@ -342,7 +349,10 @@ static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u | |||
342 | 349 | ||
343 | if (pf->access != 1) | 350 | if (pf->access != 1) |
344 | return -EBUSY; | 351 | return -EBUSY; |
352 | lock_kernel(); | ||
345 | pf_eject(pf); | 353 | pf_eject(pf); |
354 | unlock_kernel(); | ||
355 | |||
346 | return 0; | 356 | return 0; |
347 | } | 357 | } |
348 | 358 | ||
@@ -350,14 +360,18 @@ static int pf_release(struct gendisk *disk, fmode_t mode) | |||
350 | { | 360 | { |
351 | struct pf_unit *pf = disk->private_data; | 361 | struct pf_unit *pf = disk->private_data; |
352 | 362 | ||
353 | if (pf->access <= 0) | 363 | lock_kernel(); |
364 | if (pf->access <= 0) { | ||
365 | unlock_kernel(); | ||
354 | return -EINVAL; | 366 | return -EINVAL; |
367 | } | ||
355 | 368 | ||
356 | pf->access--; | 369 | pf->access--; |
357 | 370 | ||
358 | if (!pf->access && pf->removable) | 371 | if (!pf->access && pf->removable) |
359 | pf_lock(pf, 0); | 372 | pf_lock(pf, 0); |
360 | 373 | ||
374 | unlock_kernel(); | ||
361 | return 0; | 375 | return 0; |
362 | 376 | ||
363 | } | 377 | } |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 8a549db2aa78..b1cbeb59bb76 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/seq_file.h> | 57 | #include <linux/seq_file.h> |
58 | #include <linux/miscdevice.h> | 58 | #include <linux/miscdevice.h> |
59 | #include <linux/freezer.h> | 59 | #include <linux/freezer.h> |
60 | #include <linux/smp_lock.h> | ||
60 | #include <linux/mutex.h> | 61 | #include <linux/mutex.h> |
61 | #include <linux/slab.h> | 62 | #include <linux/slab.h> |
62 | #include <scsi/scsi_cmnd.h> | 63 | #include <scsi/scsi_cmnd.h> |
@@ -1221,7 +1222,7 @@ static int pkt_start_recovery(struct packet_data *pkt) | |||
1221 | pkt->bio->bi_flags = 1 << BIO_UPTODATE; | 1222 | pkt->bio->bi_flags = 1 << BIO_UPTODATE; |
1222 | pkt->bio->bi_idx = 0; | 1223 | pkt->bio->bi_idx = 0; |
1223 | 1224 | ||
1224 | BUG_ON(pkt->bio->bi_rw != (1 << BIO_RW)); | 1225 | BUG_ON(pkt->bio->bi_rw != REQ_WRITE); |
1225 | BUG_ON(pkt->bio->bi_vcnt != pkt->frames); | 1226 | BUG_ON(pkt->bio->bi_vcnt != pkt->frames); |
1226 | BUG_ON(pkt->bio->bi_size != pkt->frames * CD_FRAMESIZE); | 1227 | BUG_ON(pkt->bio->bi_size != pkt->frames * CD_FRAMESIZE); |
1227 | BUG_ON(pkt->bio->bi_end_io != pkt_end_io_packet_write); | 1228 | BUG_ON(pkt->bio->bi_end_io != pkt_end_io_packet_write); |
@@ -2382,6 +2383,7 @@ static int pkt_open(struct block_device *bdev, fmode_t mode) | |||
2382 | 2383 | ||
2383 | VPRINTK(DRIVER_NAME": entering open\n"); | 2384 | VPRINTK(DRIVER_NAME": entering open\n"); |
2384 | 2385 | ||
2386 | lock_kernel(); | ||
2385 | mutex_lock(&ctl_mutex); | 2387 | mutex_lock(&ctl_mutex); |
2386 | pd = pkt_find_dev_from_minor(MINOR(bdev->bd_dev)); | 2388 | pd = pkt_find_dev_from_minor(MINOR(bdev->bd_dev)); |
2387 | if (!pd) { | 2389 | if (!pd) { |
@@ -2409,6 +2411,7 @@ static int pkt_open(struct block_device *bdev, fmode_t mode) | |||
2409 | } | 2411 | } |
2410 | 2412 | ||
2411 | mutex_unlock(&ctl_mutex); | 2413 | mutex_unlock(&ctl_mutex); |
2414 | unlock_kernel(); | ||
2412 | return 0; | 2415 | return 0; |
2413 | 2416 | ||
2414 | out_dec: | 2417 | out_dec: |
@@ -2416,6 +2419,7 @@ out_dec: | |||
2416 | out: | 2419 | out: |
2417 | VPRINTK(DRIVER_NAME": failed open (%d)\n", ret); | 2420 | VPRINTK(DRIVER_NAME": failed open (%d)\n", ret); |
2418 | mutex_unlock(&ctl_mutex); | 2421 | mutex_unlock(&ctl_mutex); |
2422 | unlock_kernel(); | ||
2419 | return ret; | 2423 | return ret; |
2420 | } | 2424 | } |
2421 | 2425 | ||
@@ -2424,6 +2428,7 @@ static int pkt_close(struct gendisk *disk, fmode_t mode) | |||
2424 | struct pktcdvd_device *pd = disk->private_data; | 2428 | struct pktcdvd_device *pd = disk->private_data; |
2425 | int ret = 0; | 2429 | int ret = 0; |
2426 | 2430 | ||
2431 | lock_kernel(); | ||
2427 | mutex_lock(&ctl_mutex); | 2432 | mutex_lock(&ctl_mutex); |
2428 | pd->refcnt--; | 2433 | pd->refcnt--; |
2429 | BUG_ON(pd->refcnt < 0); | 2434 | BUG_ON(pd->refcnt < 0); |
@@ -2432,6 +2437,7 @@ static int pkt_close(struct gendisk *disk, fmode_t mode) | |||
2432 | pkt_release_dev(pd, flush); | 2437 | pkt_release_dev(pd, flush); |
2433 | } | 2438 | } |
2434 | mutex_unlock(&ctl_mutex); | 2439 | mutex_unlock(&ctl_mutex); |
2440 | unlock_kernel(); | ||
2435 | return ret; | 2441 | return ret; |
2436 | } | 2442 | } |
2437 | 2443 | ||
@@ -2762,10 +2768,12 @@ out_mem: | |||
2762 | static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) | 2768 | static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) |
2763 | { | 2769 | { |
2764 | struct pktcdvd_device *pd = bdev->bd_disk->private_data; | 2770 | struct pktcdvd_device *pd = bdev->bd_disk->private_data; |
2771 | int ret; | ||
2765 | 2772 | ||
2766 | VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, | 2773 | VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, |
2767 | MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); | 2774 | MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); |
2768 | 2775 | ||
2776 | lock_kernel(); | ||
2769 | switch (cmd) { | 2777 | switch (cmd) { |
2770 | case CDROMEJECT: | 2778 | case CDROMEJECT: |
2771 | /* | 2779 | /* |
@@ -2783,14 +2791,16 @@ static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, | |||
2783 | case CDROM_LAST_WRITTEN: | 2791 | case CDROM_LAST_WRITTEN: |
2784 | case CDROM_SEND_PACKET: | 2792 | case CDROM_SEND_PACKET: |
2785 | case SCSI_IOCTL_SEND_COMMAND: | 2793 | case SCSI_IOCTL_SEND_COMMAND: |
2786 | return __blkdev_driver_ioctl(pd->bdev, mode, cmd, arg); | 2794 | ret = __blkdev_driver_ioctl(pd->bdev, mode, cmd, arg); |
2795 | break; | ||
2787 | 2796 | ||
2788 | default: | 2797 | default: |
2789 | VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); | 2798 | VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); |
2790 | return -ENOTTY; | 2799 | ret = -ENOTTY; |
2791 | } | 2800 | } |
2801 | unlock_kernel(); | ||
2792 | 2802 | ||
2793 | return 0; | 2803 | return ret; |
2794 | } | 2804 | } |
2795 | 2805 | ||
2796 | static int pkt_media_changed(struct gendisk *disk) | 2806 | static int pkt_media_changed(struct gendisk *disk) |
@@ -2812,7 +2822,7 @@ static const struct block_device_operations pktcdvd_ops = { | |||
2812 | .owner = THIS_MODULE, | 2822 | .owner = THIS_MODULE, |
2813 | .open = pkt_open, | 2823 | .open = pkt_open, |
2814 | .release = pkt_close, | 2824 | .release = pkt_close, |
2815 | .locked_ioctl = pkt_ioctl, | 2825 | .ioctl = pkt_ioctl, |
2816 | .media_changed = pkt_media_changed, | 2826 | .media_changed = pkt_media_changed, |
2817 | }; | 2827 | }; |
2818 | 2828 | ||
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 3b419e3fffa1..e9da874d0419 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c | |||
@@ -196,13 +196,12 @@ static void ps3disk_do_request(struct ps3_storage_device *dev, | |||
196 | dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__); | 196 | dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__); |
197 | 197 | ||
198 | while ((req = blk_fetch_request(q))) { | 198 | while ((req = blk_fetch_request(q))) { |
199 | if (blk_fs_request(req)) { | 199 | if (req->cmd_flags & REQ_FLUSH) { |
200 | if (ps3disk_submit_request_sg(dev, req)) | ||
201 | break; | ||
202 | } else if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && | ||
203 | req->cmd[0] == REQ_LB_OP_FLUSH) { | ||
204 | if (ps3disk_submit_flush_request(dev, req)) | 200 | if (ps3disk_submit_flush_request(dev, req)) |
205 | break; | 201 | break; |
202 | } else if (req->cmd_type == REQ_TYPE_FS) { | ||
203 | if (ps3disk_submit_request_sg(dev, req)) | ||
204 | break; | ||
206 | } else { | 205 | } else { |
207 | blk_dump_rq_flags(req, DEVICE_NAME " bad request"); | 206 | blk_dump_rq_flags(req, DEVICE_NAME " bad request"); |
208 | __blk_end_request_all(req, -EIO); | 207 | __blk_end_request_all(req, -EIO); |
@@ -257,8 +256,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) | |||
257 | return IRQ_HANDLED; | 256 | return IRQ_HANDLED; |
258 | } | 257 | } |
259 | 258 | ||
260 | if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && | 259 | if (req->cmd_flags & REQ_FLUSH) { |
261 | req->cmd[0] == REQ_LB_OP_FLUSH) { | ||
262 | read = 0; | 260 | read = 0; |
263 | op = "flush"; | 261 | op = "flush"; |
264 | } else { | 262 | } else { |
@@ -398,16 +396,6 @@ static int ps3disk_identify(struct ps3_storage_device *dev) | |||
398 | return 0; | 396 | return 0; |
399 | } | 397 | } |
400 | 398 | ||
401 | static void ps3disk_prepare_flush(struct request_queue *q, struct request *req) | ||
402 | { | ||
403 | struct ps3_storage_device *dev = q->queuedata; | ||
404 | |||
405 | dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__); | ||
406 | |||
407 | req->cmd_type = REQ_TYPE_LINUX_BLOCK; | ||
408 | req->cmd[0] = REQ_LB_OP_FLUSH; | ||
409 | } | ||
410 | |||
411 | static unsigned long ps3disk_mask; | 399 | static unsigned long ps3disk_mask; |
412 | 400 | ||
413 | static DEFINE_MUTEX(ps3disk_mask_mutex); | 401 | static DEFINE_MUTEX(ps3disk_mask_mutex); |
@@ -480,8 +468,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev) | |||
480 | blk_queue_dma_alignment(queue, dev->blk_size-1); | 468 | blk_queue_dma_alignment(queue, dev->blk_size-1); |
481 | blk_queue_logical_block_size(queue, dev->blk_size); | 469 | blk_queue_logical_block_size(queue, dev->blk_size); |
482 | 470 | ||
483 | blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH, | 471 | blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH); |
484 | ps3disk_prepare_flush); | ||
485 | 472 | ||
486 | blk_queue_max_segments(queue, -1); | 473 | blk_queue_max_segments(queue, -1); |
487 | blk_queue_max_segment_size(queue, dev->bounce_size); | 474 | blk_queue_max_segment_size(queue, dev->bounce_size); |
diff --git a/drivers/block/swim.c b/drivers/block/swim.c index e463657569ff..2e46815876df 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/fd.h> | 20 | #include <linux/fd.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/blkdev.h> | 22 | #include <linux/blkdev.h> |
23 | #include <linux/smp_lock.h> | ||
23 | #include <linux/hdreg.h> | 24 | #include <linux/hdreg.h> |
24 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
25 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
@@ -661,11 +662,23 @@ out: | |||
661 | return err; | 662 | return err; |
662 | } | 663 | } |
663 | 664 | ||
665 | static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode) | ||
666 | { | ||
667 | int ret; | ||
668 | |||
669 | lock_kernel(); | ||
670 | ret = floppy_open(bdev, mode); | ||
671 | unlock_kernel(); | ||
672 | |||
673 | return ret; | ||
674 | } | ||
675 | |||
664 | static int floppy_release(struct gendisk *disk, fmode_t mode) | 676 | static int floppy_release(struct gendisk *disk, fmode_t mode) |
665 | { | 677 | { |
666 | struct floppy_state *fs = disk->private_data; | 678 | struct floppy_state *fs = disk->private_data; |
667 | struct swim __iomem *base = fs->swd->base; | 679 | struct swim __iomem *base = fs->swd->base; |
668 | 680 | ||
681 | lock_kernel(); | ||
669 | if (fs->ref_count < 0) | 682 | if (fs->ref_count < 0) |
670 | fs->ref_count = 0; | 683 | fs->ref_count = 0; |
671 | else if (fs->ref_count > 0) | 684 | else if (fs->ref_count > 0) |
@@ -673,6 +686,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) | |||
673 | 686 | ||
674 | if (fs->ref_count == 0) | 687 | if (fs->ref_count == 0) |
675 | swim_motor(base, OFF); | 688 | swim_motor(base, OFF); |
689 | unlock_kernel(); | ||
676 | 690 | ||
677 | return 0; | 691 | return 0; |
678 | } | 692 | } |
@@ -690,7 +704,9 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode, | |||
690 | case FDEJECT: | 704 | case FDEJECT: |
691 | if (fs->ref_count != 1) | 705 | if (fs->ref_count != 1) |
692 | return -EBUSY; | 706 | return -EBUSY; |
707 | lock_kernel(); | ||
693 | err = floppy_eject(fs); | 708 | err = floppy_eject(fs); |
709 | unlock_kernel(); | ||
694 | return err; | 710 | return err; |
695 | 711 | ||
696 | case FDGETPRM: | 712 | case FDGETPRM: |
@@ -751,9 +767,9 @@ static int floppy_revalidate(struct gendisk *disk) | |||
751 | 767 | ||
752 | static const struct block_device_operations floppy_fops = { | 768 | static const struct block_device_operations floppy_fops = { |
753 | .owner = THIS_MODULE, | 769 | .owner = THIS_MODULE, |
754 | .open = floppy_open, | 770 | .open = floppy_unlocked_open, |
755 | .release = floppy_release, | 771 | .release = floppy_release, |
756 | .locked_ioctl = floppy_ioctl, | 772 | .ioctl = floppy_ioctl, |
757 | .getgeo = floppy_getgeo, | 773 | .getgeo = floppy_getgeo, |
758 | .media_changed = floppy_check_change, | 774 | .media_changed = floppy_check_change, |
759 | .revalidate_disk = floppy_revalidate, | 775 | .revalidate_disk = floppy_revalidate, |
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index ed6fb91123ab..cc6a3864822c 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/ioctl.h> | 25 | #include <linux/ioctl.h> |
26 | #include <linux/blkdev.h> | 26 | #include <linux/blkdev.h> |
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/smp_lock.h> | ||
28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
29 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
@@ -839,7 +840,7 @@ static int fd_eject(struct floppy_state *fs) | |||
839 | static struct floppy_struct floppy_type = | 840 | static struct floppy_struct floppy_type = |
840 | { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */ | 841 | { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */ |
841 | 842 | ||
842 | static int floppy_ioctl(struct block_device *bdev, fmode_t mode, | 843 | static int floppy_locked_ioctl(struct block_device *bdev, fmode_t mode, |
843 | unsigned int cmd, unsigned long param) | 844 | unsigned int cmd, unsigned long param) |
844 | { | 845 | { |
845 | struct floppy_state *fs = bdev->bd_disk->private_data; | 846 | struct floppy_state *fs = bdev->bd_disk->private_data; |
@@ -867,6 +868,18 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode, | |||
867 | return -ENOTTY; | 868 | return -ENOTTY; |
868 | } | 869 | } |
869 | 870 | ||
871 | static int floppy_ioctl(struct block_device *bdev, fmode_t mode, | ||
872 | unsigned int cmd, unsigned long param) | ||
873 | { | ||
874 | int ret; | ||
875 | |||
876 | lock_kernel(); | ||
877 | ret = floppy_locked_ioctl(bdev, mode, cmd, param); | ||
878 | unlock_kernel(); | ||
879 | |||
880 | return ret; | ||
881 | } | ||
882 | |||
870 | static int floppy_open(struct block_device *bdev, fmode_t mode) | 883 | static int floppy_open(struct block_device *bdev, fmode_t mode) |
871 | { | 884 | { |
872 | struct floppy_state *fs = bdev->bd_disk->private_data; | 885 | struct floppy_state *fs = bdev->bd_disk->private_data; |
@@ -936,15 +949,28 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) | |||
936 | return 0; | 949 | return 0; |
937 | } | 950 | } |
938 | 951 | ||
952 | static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode) | ||
953 | { | ||
954 | int ret; | ||
955 | |||
956 | lock_kernel(); | ||
957 | ret = floppy_open(bdev, mode); | ||
958 | unlock_kernel(); | ||
959 | |||
960 | return ret; | ||
961 | } | ||
962 | |||
939 | static int floppy_release(struct gendisk *disk, fmode_t mode) | 963 | static int floppy_release(struct gendisk *disk, fmode_t mode) |
940 | { | 964 | { |
941 | struct floppy_state *fs = disk->private_data; | 965 | struct floppy_state *fs = disk->private_data; |
942 | struct swim3 __iomem *sw = fs->swim3; | 966 | struct swim3 __iomem *sw = fs->swim3; |
967 | lock_kernel(); | ||
943 | if (fs->ref_count > 0 && --fs->ref_count == 0) { | 968 | if (fs->ref_count > 0 && --fs->ref_count == 0) { |
944 | swim3_action(fs, MOTOR_OFF); | 969 | swim3_action(fs, MOTOR_OFF); |
945 | out_8(&sw->control_bic, 0xff); | 970 | out_8(&sw->control_bic, 0xff); |
946 | swim3_select(fs, RELAX); | 971 | swim3_select(fs, RELAX); |
947 | } | 972 | } |
973 | unlock_kernel(); | ||
948 | return 0; | 974 | return 0; |
949 | } | 975 | } |
950 | 976 | ||
@@ -995,9 +1021,9 @@ static int floppy_revalidate(struct gendisk *disk) | |||
995 | } | 1021 | } |
996 | 1022 | ||
997 | static const struct block_device_operations floppy_fops = { | 1023 | static const struct block_device_operations floppy_fops = { |
998 | .open = floppy_open, | 1024 | .open = floppy_unlocked_open, |
999 | .release = floppy_release, | 1025 | .release = floppy_release, |
1000 | .locked_ioctl = floppy_ioctl, | 1026 | .ioctl = floppy_ioctl, |
1001 | .media_changed = floppy_check_change, | 1027 | .media_changed = floppy_check_change, |
1002 | .revalidate_disk= floppy_revalidate, | 1028 | .revalidate_disk= floppy_revalidate, |
1003 | }; | 1029 | }; |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 0536b5b29adc..c48e14878582 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/timer.h> | 28 | #include <linux/timer.h> |
29 | #include <linux/scatterlist.h> | 29 | #include <linux/scatterlist.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/smp_lock.h> | ||
31 | #include <scsi/scsi.h> | 32 | #include <scsi/scsi.h> |
32 | 33 | ||
33 | #define DRV_NAME "ub" | 34 | #define DRV_NAME "ub" |
@@ -648,7 +649,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) | |||
648 | return 0; | 649 | return 0; |
649 | } | 650 | } |
650 | 651 | ||
651 | if (lun->changed && !blk_pc_request(rq)) { | 652 | if (lun->changed && rq->cmd_type != REQ_TYPE_BLOCK_PC) { |
652 | blk_start_request(rq); | 653 | blk_start_request(rq); |
653 | ub_end_rq(rq, SAM_STAT_CHECK_CONDITION); | 654 | ub_end_rq(rq, SAM_STAT_CHECK_CONDITION); |
654 | return 0; | 655 | return 0; |
@@ -684,7 +685,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) | |||
684 | } | 685 | } |
685 | urq->nsg = n_elem; | 686 | urq->nsg = n_elem; |
686 | 687 | ||
687 | if (blk_pc_request(rq)) { | 688 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { |
688 | ub_cmd_build_packet(sc, lun, cmd, urq); | 689 | ub_cmd_build_packet(sc, lun, cmd, urq); |
689 | } else { | 690 | } else { |
690 | ub_cmd_build_block(sc, lun, cmd, urq); | 691 | ub_cmd_build_block(sc, lun, cmd, urq); |
@@ -781,7 +782,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
781 | rq = urq->rq; | 782 | rq = urq->rq; |
782 | 783 | ||
783 | if (cmd->error == 0) { | 784 | if (cmd->error == 0) { |
784 | if (blk_pc_request(rq)) { | 785 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { |
785 | if (cmd->act_len >= rq->resid_len) | 786 | if (cmd->act_len >= rq->resid_len) |
786 | rq->resid_len = 0; | 787 | rq->resid_len = 0; |
787 | else | 788 | else |
@@ -795,7 +796,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) | |||
795 | } | 796 | } |
796 | } | 797 | } |
797 | } else { | 798 | } else { |
798 | if (blk_pc_request(rq)) { | 799 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { |
799 | /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */ | 800 | /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */ |
800 | memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE); | 801 | memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE); |
801 | rq->sense_len = UB_SENSE_SIZE; | 802 | rq->sense_len = UB_SENSE_SIZE; |
@@ -1710,6 +1711,18 @@ err_open: | |||
1710 | return rc; | 1711 | return rc; |
1711 | } | 1712 | } |
1712 | 1713 | ||
1714 | static int ub_bd_unlocked_open(struct block_device *bdev, fmode_t mode) | ||
1715 | { | ||
1716 | int ret; | ||
1717 | |||
1718 | lock_kernel(); | ||
1719 | ret = ub_bd_open(bdev, mode); | ||
1720 | unlock_kernel(); | ||
1721 | |||
1722 | return ret; | ||
1723 | } | ||
1724 | |||
1725 | |||
1713 | /* | 1726 | /* |
1714 | */ | 1727 | */ |
1715 | static int ub_bd_release(struct gendisk *disk, fmode_t mode) | 1728 | static int ub_bd_release(struct gendisk *disk, fmode_t mode) |
@@ -1717,7 +1730,10 @@ static int ub_bd_release(struct gendisk *disk, fmode_t mode) | |||
1717 | struct ub_lun *lun = disk->private_data; | 1730 | struct ub_lun *lun = disk->private_data; |
1718 | struct ub_dev *sc = lun->udev; | 1731 | struct ub_dev *sc = lun->udev; |
1719 | 1732 | ||
1733 | lock_kernel(); | ||
1720 | ub_put(sc); | 1734 | ub_put(sc); |
1735 | unlock_kernel(); | ||
1736 | |||
1721 | return 0; | 1737 | return 0; |
1722 | } | 1738 | } |
1723 | 1739 | ||
@@ -1729,8 +1745,13 @@ static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode, | |||
1729 | { | 1745 | { |
1730 | struct gendisk *disk = bdev->bd_disk; | 1746 | struct gendisk *disk = bdev->bd_disk; |
1731 | void __user *usermem = (void __user *) arg; | 1747 | void __user *usermem = (void __user *) arg; |
1748 | int ret; | ||
1749 | |||
1750 | lock_kernel(); | ||
1751 | ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem); | ||
1752 | unlock_kernel(); | ||
1732 | 1753 | ||
1733 | return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem); | 1754 | return ret; |
1734 | } | 1755 | } |
1735 | 1756 | ||
1736 | /* | 1757 | /* |
@@ -1792,9 +1813,9 @@ static int ub_bd_media_changed(struct gendisk *disk) | |||
1792 | 1813 | ||
1793 | static const struct block_device_operations ub_bd_fops = { | 1814 | static const struct block_device_operations ub_bd_fops = { |
1794 | .owner = THIS_MODULE, | 1815 | .owner = THIS_MODULE, |
1795 | .open = ub_bd_open, | 1816 | .open = ub_bd_unlocked_open, |
1796 | .release = ub_bd_release, | 1817 | .release = ub_bd_release, |
1797 | .locked_ioctl = ub_bd_ioctl, | 1818 | .ioctl = ub_bd_ioctl, |
1798 | .media_changed = ub_bd_media_changed, | 1819 | .media_changed = ub_bd_media_changed, |
1799 | .revalidate_disk = ub_bd_revalidate, | 1820 | .revalidate_disk = ub_bd_revalidate, |
1800 | }; | 1821 | }; |
diff --git a/drivers/block/umem.c b/drivers/block/umem.c index 2f9470ff8f7c..8be57151f5d6 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c | |||
@@ -478,7 +478,7 @@ static void process_page(unsigned long data) | |||
478 | le32_to_cpu(desc->local_addr)>>9, | 478 | le32_to_cpu(desc->local_addr)>>9, |
479 | le32_to_cpu(desc->transfer_size)); | 479 | le32_to_cpu(desc->transfer_size)); |
480 | dump_dmastat(card, control); | 480 | dump_dmastat(card, control); |
481 | } else if (test_bit(BIO_RW, &bio->bi_rw) && | 481 | } else if ((bio->bi_rw & REQ_WRITE) && |
482 | le32_to_cpu(desc->local_addr) >> 9 == | 482 | le32_to_cpu(desc->local_addr) >> 9 == |
483 | card->init_size) { | 483 | card->init_size) { |
484 | card->init_size += le32_to_cpu(desc->transfer_size) >> 9; | 484 | card->init_size += le32_to_cpu(desc->transfer_size) >> 9; |
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index 788d93882ab9..f651e51a3319 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/errno.h> | 41 | #include <linux/errno.h> |
42 | #include <linux/init.h> | 42 | #include <linux/init.h> |
43 | #include <linux/string.h> | 43 | #include <linux/string.h> |
44 | #include <linux/smp_lock.h> | ||
44 | #include <linux/dma-mapping.h> | 45 | #include <linux/dma-mapping.h> |
45 | #include <linux/completion.h> | 46 | #include <linux/completion.h> |
46 | #include <linux/device.h> | 47 | #include <linux/device.h> |
@@ -175,6 +176,18 @@ static int viodasd_open(struct block_device *bdev, fmode_t mode) | |||
175 | return 0; | 176 | return 0; |
176 | } | 177 | } |
177 | 178 | ||
179 | static int viodasd_unlocked_open(struct block_device *bdev, fmode_t mode) | ||
180 | { | ||
181 | int ret; | ||
182 | |||
183 | lock_kernel(); | ||
184 | ret = viodasd_open(bdev, mode); | ||
185 | unlock_kernel(); | ||
186 | |||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | |||
178 | /* | 191 | /* |
179 | * External release entry point. | 192 | * External release entry point. |
180 | */ | 193 | */ |
@@ -183,6 +196,7 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode) | |||
183 | struct viodasd_device *d = disk->private_data; | 196 | struct viodasd_device *d = disk->private_data; |
184 | HvLpEvent_Rc hvrc; | 197 | HvLpEvent_Rc hvrc; |
185 | 198 | ||
199 | lock_kernel(); | ||
186 | /* Send the event to OS/400. We DON'T expect a response */ | 200 | /* Send the event to OS/400. We DON'T expect a response */ |
187 | hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, | 201 | hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, |
188 | HvLpEvent_Type_VirtualIo, | 202 | HvLpEvent_Type_VirtualIo, |
@@ -195,6 +209,9 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode) | |||
195 | 0, 0, 0); | 209 | 0, 0, 0); |
196 | if (hvrc != 0) | 210 | if (hvrc != 0) |
197 | pr_warning("HV close call failed %d\n", (int)hvrc); | 211 | pr_warning("HV close call failed %d\n", (int)hvrc); |
212 | |||
213 | unlock_kernel(); | ||
214 | |||
198 | return 0; | 215 | return 0; |
199 | } | 216 | } |
200 | 217 | ||
@@ -219,7 +236,7 @@ static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
219 | */ | 236 | */ |
220 | static const struct block_device_operations viodasd_fops = { | 237 | static const struct block_device_operations viodasd_fops = { |
221 | .owner = THIS_MODULE, | 238 | .owner = THIS_MODULE, |
222 | .open = viodasd_open, | 239 | .open = viodasd_unlocked_open, |
223 | .release = viodasd_release, | 240 | .release = viodasd_release, |
224 | .getgeo = viodasd_getgeo, | 241 | .getgeo = viodasd_getgeo, |
225 | }; | 242 | }; |
@@ -361,7 +378,7 @@ static void do_viodasd_request(struct request_queue *q) | |||
361 | if (req == NULL) | 378 | if (req == NULL) |
362 | return; | 379 | return; |
363 | /* check that request contains a valid command */ | 380 | /* check that request contains a valid command */ |
364 | if (!blk_fs_request(req)) { | 381 | if (req->cmd_type != REQ_TYPE_FS) { |
365 | viodasd_end_request(req, -EIO, blk_rq_sectors(req)); | 382 | viodasd_end_request(req, -EIO, blk_rq_sectors(req)); |
366 | continue; | 383 | continue; |
367 | } | 384 | } |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 23b7c48df843..2aafafca2b13 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/spinlock.h> | 2 | #include <linux/spinlock.h> |
3 | #include <linux/slab.h> | 3 | #include <linux/slab.h> |
4 | #include <linux/blkdev.h> | 4 | #include <linux/blkdev.h> |
5 | #include <linux/smp_lock.h> | ||
5 | #include <linux/hdreg.h> | 6 | #include <linux/hdreg.h> |
6 | #include <linux/virtio.h> | 7 | #include <linux/virtio.h> |
7 | #include <linux/virtio_blk.h> | 8 | #include <linux/virtio_blk.h> |
@@ -65,13 +66,18 @@ static void blk_done(struct virtqueue *vq) | |||
65 | break; | 66 | break; |
66 | } | 67 | } |
67 | 68 | ||
68 | if (blk_pc_request(vbr->req)) { | 69 | switch (vbr->req->cmd_type) { |
70 | case REQ_TYPE_BLOCK_PC: | ||
69 | vbr->req->resid_len = vbr->in_hdr.residual; | 71 | vbr->req->resid_len = vbr->in_hdr.residual; |
70 | vbr->req->sense_len = vbr->in_hdr.sense_len; | 72 | vbr->req->sense_len = vbr->in_hdr.sense_len; |
71 | vbr->req->errors = vbr->in_hdr.errors; | 73 | vbr->req->errors = vbr->in_hdr.errors; |
72 | } | 74 | break; |
73 | if (blk_special_request(vbr->req)) | 75 | case REQ_TYPE_SPECIAL: |
74 | vbr->req->errors = (error != 0); | 76 | vbr->req->errors = (error != 0); |
77 | break; | ||
78 | default: | ||
79 | break; | ||
80 | } | ||
75 | 81 | ||
76 | __blk_end_request_all(vbr->req, error); | 82 | __blk_end_request_all(vbr->req, error); |
77 | list_del(&vbr->list); | 83 | list_del(&vbr->list); |
@@ -94,36 +100,35 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, | |||
94 | return false; | 100 | return false; |
95 | 101 | ||
96 | vbr->req = req; | 102 | vbr->req = req; |
97 | switch (req->cmd_type) { | 103 | |
98 | case REQ_TYPE_FS: | 104 | if (req->cmd_flags & REQ_FLUSH) { |
99 | vbr->out_hdr.type = 0; | 105 | vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; |
100 | vbr->out_hdr.sector = blk_rq_pos(vbr->req); | ||
101 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); | ||
102 | break; | ||
103 | case REQ_TYPE_BLOCK_PC: | ||
104 | vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD; | ||
105 | vbr->out_hdr.sector = 0; | ||
106 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); | ||
107 | break; | ||
108 | case REQ_TYPE_SPECIAL: | ||
109 | vbr->out_hdr.type = VIRTIO_BLK_T_GET_ID; | ||
110 | vbr->out_hdr.sector = 0; | 106 | vbr->out_hdr.sector = 0; |
111 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); | 107 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); |
112 | break; | 108 | } else { |
113 | case REQ_TYPE_LINUX_BLOCK: | 109 | switch (req->cmd_type) { |
114 | if (req->cmd[0] == REQ_LB_OP_FLUSH) { | 110 | case REQ_TYPE_FS: |
115 | vbr->out_hdr.type = VIRTIO_BLK_T_FLUSH; | 111 | vbr->out_hdr.type = 0; |
112 | vbr->out_hdr.sector = blk_rq_pos(vbr->req); | ||
113 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); | ||
114 | break; | ||
115 | case REQ_TYPE_BLOCK_PC: | ||
116 | vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD; | ||
116 | vbr->out_hdr.sector = 0; | 117 | vbr->out_hdr.sector = 0; |
117 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); | 118 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); |
118 | break; | 119 | break; |
120 | case REQ_TYPE_SPECIAL: | ||
121 | vbr->out_hdr.type = VIRTIO_BLK_T_GET_ID; | ||
122 | vbr->out_hdr.sector = 0; | ||
123 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); | ||
124 | break; | ||
125 | default: | ||
126 | /* We don't put anything else in the queue. */ | ||
127 | BUG(); | ||
119 | } | 128 | } |
120 | /*FALLTHRU*/ | ||
121 | default: | ||
122 | /* We don't put anything else in the queue. */ | ||
123 | BUG(); | ||
124 | } | 129 | } |
125 | 130 | ||
126 | if (blk_barrier_rq(vbr->req)) | 131 | if (vbr->req->cmd_flags & REQ_HARDBARRIER) |
127 | vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER; | 132 | vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER; |
128 | 133 | ||
129 | sg_set_buf(&vblk->sg[out++], &vbr->out_hdr, sizeof(vbr->out_hdr)); | 134 | sg_set_buf(&vblk->sg[out++], &vbr->out_hdr, sizeof(vbr->out_hdr)); |
@@ -134,12 +139,12 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, | |||
134 | * block, and before the normal inhdr we put the sense data and the | 139 | * block, and before the normal inhdr we put the sense data and the |
135 | * inhdr with additional status information before the normal inhdr. | 140 | * inhdr with additional status information before the normal inhdr. |
136 | */ | 141 | */ |
137 | if (blk_pc_request(vbr->req)) | 142 | if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) |
138 | sg_set_buf(&vblk->sg[out++], vbr->req->cmd, vbr->req->cmd_len); | 143 | sg_set_buf(&vblk->sg[out++], vbr->req->cmd, vbr->req->cmd_len); |
139 | 144 | ||
140 | num = blk_rq_map_sg(q, vbr->req, vblk->sg + out); | 145 | num = blk_rq_map_sg(q, vbr->req, vblk->sg + out); |
141 | 146 | ||
142 | if (blk_pc_request(vbr->req)) { | 147 | if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) { |
143 | sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, 96); | 148 | sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, 96); |
144 | sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr, | 149 | sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr, |
145 | sizeof(vbr->in_hdr)); | 150 | sizeof(vbr->in_hdr)); |
@@ -190,12 +195,6 @@ static void do_virtblk_request(struct request_queue *q) | |||
190 | virtqueue_kick(vblk->vq); | 195 | virtqueue_kick(vblk->vq); |
191 | } | 196 | } |
192 | 197 | ||
193 | static void virtblk_prepare_flush(struct request_queue *q, struct request *req) | ||
194 | { | ||
195 | req->cmd_type = REQ_TYPE_LINUX_BLOCK; | ||
196 | req->cmd[0] = REQ_LB_OP_FLUSH; | ||
197 | } | ||
198 | |||
199 | /* return id (s/n) string for *disk to *id_str | 198 | /* return id (s/n) string for *disk to *id_str |
200 | */ | 199 | */ |
201 | static int virtblk_get_id(struct gendisk *disk, char *id_str) | 200 | static int virtblk_get_id(struct gendisk *disk, char *id_str) |
@@ -219,7 +218,7 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str) | |||
219 | return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); | 218 | return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); |
220 | } | 219 | } |
221 | 220 | ||
222 | static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, | 221 | static int virtblk_locked_ioctl(struct block_device *bdev, fmode_t mode, |
223 | unsigned cmd, unsigned long data) | 222 | unsigned cmd, unsigned long data) |
224 | { | 223 | { |
225 | struct gendisk *disk = bdev->bd_disk; | 224 | struct gendisk *disk = bdev->bd_disk; |
@@ -235,6 +234,18 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, | |||
235 | (void __user *)data); | 234 | (void __user *)data); |
236 | } | 235 | } |
237 | 236 | ||
237 | static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, | ||
238 | unsigned int cmd, unsigned long param) | ||
239 | { | ||
240 | int ret; | ||
241 | |||
242 | lock_kernel(); | ||
243 | ret = virtblk_locked_ioctl(bdev, mode, cmd, param); | ||
244 | unlock_kernel(); | ||
245 | |||
246 | return ret; | ||
247 | } | ||
248 | |||
238 | /* We provide getgeo only to please some old bootloader/partitioning tools */ | 249 | /* We provide getgeo only to please some old bootloader/partitioning tools */ |
239 | static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) | 250 | static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) |
240 | { | 251 | { |
@@ -261,7 +272,7 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) | |||
261 | } | 272 | } |
262 | 273 | ||
263 | static const struct block_device_operations virtblk_fops = { | 274 | static const struct block_device_operations virtblk_fops = { |
264 | .locked_ioctl = virtblk_ioctl, | 275 | .ioctl = virtblk_ioctl, |
265 | .owner = THIS_MODULE, | 276 | .owner = THIS_MODULE, |
266 | .getgeo = virtblk_getgeo, | 277 | .getgeo = virtblk_getgeo, |
267 | }; | 278 | }; |
@@ -383,8 +394,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) | |||
383 | * flushing a volatile write cache on the host. Use that | 394 | * flushing a volatile write cache on the host. Use that |
384 | * to implement write barrier support. | 395 | * to implement write barrier support. |
385 | */ | 396 | */ |
386 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH, | 397 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN_FLUSH); |
387 | virtblk_prepare_flush); | ||
388 | } else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) { | 398 | } else if (virtio_has_feature(vdev, VIRTIO_BLK_F_BARRIER)) { |
389 | /* | 399 | /* |
390 | * If the BARRIER feature is supported the host expects us | 400 | * If the BARRIER feature is supported the host expects us |
@@ -393,7 +403,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) | |||
393 | * never re-orders outstanding I/O. This feature is not | 403 | * never re-orders outstanding I/O. This feature is not |
394 | * useful for real life scenarious and deprecated. | 404 | * useful for real life scenarious and deprecated. |
395 | */ | 405 | */ |
396 | blk_queue_ordered(q, QUEUE_ORDERED_TAG, NULL); | 406 | blk_queue_ordered(q, QUEUE_ORDERED_TAG); |
397 | } else { | 407 | } else { |
398 | /* | 408 | /* |
399 | * If the FLUSH feature is not supported we must assume that | 409 | * If the FLUSH feature is not supported we must assume that |
@@ -401,7 +411,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) | |||
401 | * caching. We still need to drain the queue to provider | 411 | * caching. We still need to drain the queue to provider |
402 | * proper barrier semantics. | 412 | * proper barrier semantics. |
403 | */ | 413 | */ |
404 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN, NULL); | 414 | blk_queue_ordered(q, QUEUE_ORDERED_DRAIN); |
405 | } | 415 | } |
406 | 416 | ||
407 | /* If disk is read-only in the host, the guest should obey */ | 417 | /* If disk is read-only in the host, the guest should obey */ |
diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 18a80ff57ce8..d5a3cd750561 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/init.h> | 46 | #include <linux/init.h> |
47 | #include <linux/wait.h> | 47 | #include <linux/wait.h> |
48 | #include <linux/blkdev.h> | 48 | #include <linux/blkdev.h> |
49 | #include <linux/smp_lock.h> | ||
49 | #include <linux/blkpg.h> | 50 | #include <linux/blkpg.h> |
50 | #include <linux/delay.h> | 51 | #include <linux/delay.h> |
51 | #include <linux/io.h> | 52 | #include <linux/io.h> |
@@ -133,7 +134,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo); | |||
133 | 134 | ||
134 | static const struct block_device_operations xd_fops = { | 135 | static const struct block_device_operations xd_fops = { |
135 | .owner = THIS_MODULE, | 136 | .owner = THIS_MODULE, |
136 | .locked_ioctl = xd_ioctl, | 137 | .ioctl = xd_ioctl, |
137 | .getgeo = xd_getgeo, | 138 | .getgeo = xd_getgeo, |
138 | }; | 139 | }; |
139 | static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); | 140 | static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); |
@@ -322,7 +323,7 @@ static void do_xd_request (struct request_queue * q) | |||
322 | int res = -EIO; | 323 | int res = -EIO; |
323 | int retry; | 324 | int retry; |
324 | 325 | ||
325 | if (!blk_fs_request(req)) | 326 | if (req->cmd_type != REQ_TYPE_FS) |
326 | goto done; | 327 | goto done; |
327 | if (block + count > get_capacity(req->rq_disk)) | 328 | if (block + count > get_capacity(req->rq_disk)) |
328 | goto done; | 329 | goto done; |
@@ -347,7 +348,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
347 | } | 348 | } |
348 | 349 | ||
349 | /* xd_ioctl: handle device ioctl's */ | 350 | /* xd_ioctl: handle device ioctl's */ |
350 | static int xd_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg) | 351 | static int xd_locked_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg) |
351 | { | 352 | { |
352 | switch (cmd) { | 353 | switch (cmd) { |
353 | case HDIO_SET_DMA: | 354 | case HDIO_SET_DMA: |
@@ -375,6 +376,18 @@ static int xd_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long a | |||
375 | } | 376 | } |
376 | } | 377 | } |
377 | 378 | ||
379 | static int xd_ioctl(struct block_device *bdev, fmode_t mode, | ||
380 | unsigned int cmd, unsigned long param) | ||
381 | { | ||
382 | int ret; | ||
383 | |||
384 | lock_kernel(); | ||
385 | ret = xd_locked_ioctl(bdev, mode, cmd, param); | ||
386 | unlock_kernel(); | ||
387 | |||
388 | return ret; | ||
389 | } | ||
390 | |||
378 | /* xd_readwrite: handle a read/write request */ | 391 | /* xd_readwrite: handle a read/write request */ |
379 | static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count) | 392 | static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count) |
380 | { | 393 | { |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index f63ac3d1f8a4..ac1b682edecb 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/cdrom.h> | 41 | #include <linux/cdrom.h> |
42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/smp_lock.h> | ||
44 | #include <linux/scatterlist.h> | 45 | #include <linux/scatterlist.h> |
45 | 46 | ||
46 | #include <xen/xen.h> | 47 | #include <xen/xen.h> |
@@ -79,6 +80,7 @@ static const struct block_device_operations xlvbd_block_fops; | |||
79 | */ | 80 | */ |
80 | struct blkfront_info | 81 | struct blkfront_info |
81 | { | 82 | { |
83 | struct mutex mutex; | ||
82 | struct xenbus_device *xbdev; | 84 | struct xenbus_device *xbdev; |
83 | struct gendisk *gd; | 85 | struct gendisk *gd; |
84 | int vdevice; | 86 | int vdevice; |
@@ -95,16 +97,14 @@ struct blkfront_info | |||
95 | unsigned long shadow_free; | 97 | unsigned long shadow_free; |
96 | int feature_barrier; | 98 | int feature_barrier; |
97 | int is_ready; | 99 | int is_ready; |
98 | |||
99 | /** | ||
100 | * The number of people holding this device open. We won't allow a | ||
101 | * hot-unplug unless this is 0. | ||
102 | */ | ||
103 | int users; | ||
104 | }; | 100 | }; |
105 | 101 | ||
106 | static DEFINE_SPINLOCK(blkif_io_lock); | 102 | static DEFINE_SPINLOCK(blkif_io_lock); |
107 | 103 | ||
104 | static unsigned int nr_minors; | ||
105 | static unsigned long *minors; | ||
106 | static DEFINE_SPINLOCK(minor_lock); | ||
107 | |||
108 | #define MAXIMUM_OUTSTANDING_BLOCK_REQS \ | 108 | #define MAXIMUM_OUTSTANDING_BLOCK_REQS \ |
109 | (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLK_RING_SIZE) | 109 | (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLK_RING_SIZE) |
110 | #define GRANT_INVALID_REF 0 | 110 | #define GRANT_INVALID_REF 0 |
@@ -139,6 +139,55 @@ static void add_id_to_freelist(struct blkfront_info *info, | |||
139 | info->shadow_free = id; | 139 | info->shadow_free = id; |
140 | } | 140 | } |
141 | 141 | ||
142 | static int xlbd_reserve_minors(unsigned int minor, unsigned int nr) | ||
143 | { | ||
144 | unsigned int end = minor + nr; | ||
145 | int rc; | ||
146 | |||
147 | if (end > nr_minors) { | ||
148 | unsigned long *bitmap, *old; | ||
149 | |||
150 | bitmap = kzalloc(BITS_TO_LONGS(end) * sizeof(*bitmap), | ||
151 | GFP_KERNEL); | ||
152 | if (bitmap == NULL) | ||
153 | return -ENOMEM; | ||
154 | |||
155 | spin_lock(&minor_lock); | ||
156 | if (end > nr_minors) { | ||
157 | old = minors; | ||
158 | memcpy(bitmap, minors, | ||
159 | BITS_TO_LONGS(nr_minors) * sizeof(*bitmap)); | ||
160 | minors = bitmap; | ||
161 | nr_minors = BITS_TO_LONGS(end) * BITS_PER_LONG; | ||
162 | } else | ||
163 | old = bitmap; | ||
164 | spin_unlock(&minor_lock); | ||
165 | kfree(old); | ||
166 | } | ||
167 | |||
168 | spin_lock(&minor_lock); | ||
169 | if (find_next_bit(minors, end, minor) >= end) { | ||
170 | for (; minor < end; ++minor) | ||
171 | __set_bit(minor, minors); | ||
172 | rc = 0; | ||
173 | } else | ||
174 | rc = -EBUSY; | ||
175 | spin_unlock(&minor_lock); | ||
176 | |||
177 | return rc; | ||
178 | } | ||
179 | |||
180 | static void xlbd_release_minors(unsigned int minor, unsigned int nr) | ||
181 | { | ||
182 | unsigned int end = minor + nr; | ||
183 | |||
184 | BUG_ON(end > nr_minors); | ||
185 | spin_lock(&minor_lock); | ||
186 | for (; minor < end; ++minor) | ||
187 | __clear_bit(minor, minors); | ||
188 | spin_unlock(&minor_lock); | ||
189 | } | ||
190 | |||
142 | static void blkif_restart_queue_callback(void *arg) | 191 | static void blkif_restart_queue_callback(void *arg) |
143 | { | 192 | { |
144 | struct blkfront_info *info = (struct blkfront_info *)arg; | 193 | struct blkfront_info *info = (struct blkfront_info *)arg; |
@@ -239,7 +288,7 @@ static int blkif_queue_request(struct request *req) | |||
239 | 288 | ||
240 | ring_req->operation = rq_data_dir(req) ? | 289 | ring_req->operation = rq_data_dir(req) ? |
241 | BLKIF_OP_WRITE : BLKIF_OP_READ; | 290 | BLKIF_OP_WRITE : BLKIF_OP_READ; |
242 | if (blk_barrier_rq(req)) | 291 | if (req->cmd_flags & REQ_HARDBARRIER) |
243 | ring_req->operation = BLKIF_OP_WRITE_BARRIER; | 292 | ring_req->operation = BLKIF_OP_WRITE_BARRIER; |
244 | 293 | ||
245 | ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); | 294 | ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); |
@@ -310,7 +359,7 @@ static void do_blkif_request(struct request_queue *rq) | |||
310 | 359 | ||
311 | blk_start_request(req); | 360 | blk_start_request(req); |
312 | 361 | ||
313 | if (!blk_fs_request(req)) { | 362 | if (req->cmd_type != REQ_TYPE_FS) { |
314 | __blk_end_request_all(req, -EIO); | 363 | __blk_end_request_all(req, -EIO); |
315 | continue; | 364 | continue; |
316 | } | 365 | } |
@@ -372,17 +421,22 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) | |||
372 | static int xlvbd_barrier(struct blkfront_info *info) | 421 | static int xlvbd_barrier(struct blkfront_info *info) |
373 | { | 422 | { |
374 | int err; | 423 | int err; |
424 | const char *barrier; | ||
375 | 425 | ||
376 | err = blk_queue_ordered(info->rq, | 426 | switch (info->feature_barrier) { |
377 | info->feature_barrier ? QUEUE_ORDERED_DRAIN : QUEUE_ORDERED_NONE, | 427 | case QUEUE_ORDERED_DRAIN: barrier = "enabled (drain)"; break; |
378 | NULL); | 428 | case QUEUE_ORDERED_TAG: barrier = "enabled (tag)"; break; |
429 | case QUEUE_ORDERED_NONE: barrier = "disabled"; break; | ||
430 | default: return -EINVAL; | ||
431 | } | ||
432 | |||
433 | err = blk_queue_ordered(info->rq, info->feature_barrier); | ||
379 | 434 | ||
380 | if (err) | 435 | if (err) |
381 | return err; | 436 | return err; |
382 | 437 | ||
383 | printk(KERN_INFO "blkfront: %s: barriers %s\n", | 438 | printk(KERN_INFO "blkfront: %s: barriers %s\n", |
384 | info->gd->disk_name, | 439 | info->gd->disk_name, barrier); |
385 | info->feature_barrier ? "enabled" : "disabled"); | ||
386 | return 0; | 440 | return 0; |
387 | } | 441 | } |
388 | 442 | ||
@@ -418,9 +472,14 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | |||
418 | if ((minor % nr_parts) == 0) | 472 | if ((minor % nr_parts) == 0) |
419 | nr_minors = nr_parts; | 473 | nr_minors = nr_parts; |
420 | 474 | ||
475 | err = xlbd_reserve_minors(minor, nr_minors); | ||
476 | if (err) | ||
477 | goto out; | ||
478 | err = -ENODEV; | ||
479 | |||
421 | gd = alloc_disk(nr_minors); | 480 | gd = alloc_disk(nr_minors); |
422 | if (gd == NULL) | 481 | if (gd == NULL) |
423 | goto out; | 482 | goto release; |
424 | 483 | ||
425 | offset = minor / nr_parts; | 484 | offset = minor / nr_parts; |
426 | 485 | ||
@@ -451,14 +510,13 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | |||
451 | 510 | ||
452 | if (xlvbd_init_blk_queue(gd, sector_size)) { | 511 | if (xlvbd_init_blk_queue(gd, sector_size)) { |
453 | del_gendisk(gd); | 512 | del_gendisk(gd); |
454 | goto out; | 513 | goto release; |
455 | } | 514 | } |
456 | 515 | ||
457 | info->rq = gd->queue; | 516 | info->rq = gd->queue; |
458 | info->gd = gd; | 517 | info->gd = gd; |
459 | 518 | ||
460 | if (info->feature_barrier) | 519 | xlvbd_barrier(info); |
461 | xlvbd_barrier(info); | ||
462 | 520 | ||
463 | if (vdisk_info & VDISK_READONLY) | 521 | if (vdisk_info & VDISK_READONLY) |
464 | set_disk_ro(gd, 1); | 522 | set_disk_ro(gd, 1); |
@@ -471,10 +529,45 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | |||
471 | 529 | ||
472 | return 0; | 530 | return 0; |
473 | 531 | ||
532 | release: | ||
533 | xlbd_release_minors(minor, nr_minors); | ||
474 | out: | 534 | out: |
475 | return err; | 535 | return err; |
476 | } | 536 | } |
477 | 537 | ||
538 | static void xlvbd_release_gendisk(struct blkfront_info *info) | ||
539 | { | ||
540 | unsigned int minor, nr_minors; | ||
541 | unsigned long flags; | ||
542 | |||
543 | if (info->rq == NULL) | ||
544 | return; | ||
545 | |||
546 | spin_lock_irqsave(&blkif_io_lock, flags); | ||
547 | |||
548 | /* No more blkif_request(). */ | ||
549 | blk_stop_queue(info->rq); | ||
550 | |||
551 | /* No more gnttab callback work. */ | ||
552 | gnttab_cancel_free_callback(&info->callback); | ||
553 | spin_unlock_irqrestore(&blkif_io_lock, flags); | ||
554 | |||
555 | /* Flush gnttab callback work. Must be done with no locks held. */ | ||
556 | flush_scheduled_work(); | ||
557 | |||
558 | del_gendisk(info->gd); | ||
559 | |||
560 | minor = info->gd->first_minor; | ||
561 | nr_minors = info->gd->minors; | ||
562 | xlbd_release_minors(minor, nr_minors); | ||
563 | |||
564 | blk_cleanup_queue(info->rq); | ||
565 | info->rq = NULL; | ||
566 | |||
567 | put_disk(info->gd); | ||
568 | info->gd = NULL; | ||
569 | } | ||
570 | |||
478 | static void kick_pending_request_queues(struct blkfront_info *info) | 571 | static void kick_pending_request_queues(struct blkfront_info *info) |
479 | { | 572 | { |
480 | if (!RING_FULL(&info->ring)) { | 573 | if (!RING_FULL(&info->ring)) { |
@@ -569,7 +662,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) | |||
569 | printk(KERN_WARNING "blkfront: %s: write barrier op failed\n", | 662 | printk(KERN_WARNING "blkfront: %s: write barrier op failed\n", |
570 | info->gd->disk_name); | 663 | info->gd->disk_name); |
571 | error = -EOPNOTSUPP; | 664 | error = -EOPNOTSUPP; |
572 | info->feature_barrier = 0; | 665 | info->feature_barrier = QUEUE_ORDERED_NONE; |
573 | xlvbd_barrier(info); | 666 | xlvbd_barrier(info); |
574 | } | 667 | } |
575 | /* fall through */ | 668 | /* fall through */ |
@@ -652,7 +745,7 @@ fail: | |||
652 | 745 | ||
653 | 746 | ||
654 | /* Common code used when first setting up, and when resuming. */ | 747 | /* Common code used when first setting up, and when resuming. */ |
655 | static int talk_to_backend(struct xenbus_device *dev, | 748 | static int talk_to_blkback(struct xenbus_device *dev, |
656 | struct blkfront_info *info) | 749 | struct blkfront_info *info) |
657 | { | 750 | { |
658 | const char *message = NULL; | 751 | const char *message = NULL; |
@@ -712,7 +805,6 @@ again: | |||
712 | return err; | 805 | return err; |
713 | } | 806 | } |
714 | 807 | ||
715 | |||
716 | /** | 808 | /** |
717 | * Entry point to this code when a new device is created. Allocate the basic | 809 | * Entry point to this code when a new device is created. Allocate the basic |
718 | * structures and the ring buffer for communication with the backend, and | 810 | * structures and the ring buffer for communication with the backend, and |
@@ -773,6 +865,7 @@ static int blkfront_probe(struct xenbus_device *dev, | |||
773 | return -ENOMEM; | 865 | return -ENOMEM; |
774 | } | 866 | } |
775 | 867 | ||
868 | mutex_init(&info->mutex); | ||
776 | info->xbdev = dev; | 869 | info->xbdev = dev; |
777 | info->vdevice = vdevice; | 870 | info->vdevice = vdevice; |
778 | info->connected = BLKIF_STATE_DISCONNECTED; | 871 | info->connected = BLKIF_STATE_DISCONNECTED; |
@@ -786,7 +879,7 @@ static int blkfront_probe(struct xenbus_device *dev, | |||
786 | info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0); | 879 | info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0); |
787 | dev_set_drvdata(&dev->dev, info); | 880 | dev_set_drvdata(&dev->dev, info); |
788 | 881 | ||
789 | err = talk_to_backend(dev, info); | 882 | err = talk_to_blkback(dev, info); |
790 | if (err) { | 883 | if (err) { |
791 | kfree(info); | 884 | kfree(info); |
792 | dev_set_drvdata(&dev->dev, NULL); | 885 | dev_set_drvdata(&dev->dev, NULL); |
@@ -881,13 +974,50 @@ static int blkfront_resume(struct xenbus_device *dev) | |||
881 | 974 | ||
882 | blkif_free(info, info->connected == BLKIF_STATE_CONNECTED); | 975 | blkif_free(info, info->connected == BLKIF_STATE_CONNECTED); |
883 | 976 | ||
884 | err = talk_to_backend(dev, info); | 977 | err = talk_to_blkback(dev, info); |
885 | if (info->connected == BLKIF_STATE_SUSPENDED && !err) | 978 | if (info->connected == BLKIF_STATE_SUSPENDED && !err) |
886 | err = blkif_recover(info); | 979 | err = blkif_recover(info); |
887 | 980 | ||
888 | return err; | 981 | return err; |
889 | } | 982 | } |
890 | 983 | ||
984 | static void | ||
985 | blkfront_closing(struct blkfront_info *info) | ||
986 | { | ||
987 | struct xenbus_device *xbdev = info->xbdev; | ||
988 | struct block_device *bdev = NULL; | ||
989 | |||
990 | mutex_lock(&info->mutex); | ||
991 | |||
992 | if (xbdev->state == XenbusStateClosing) { | ||
993 | mutex_unlock(&info->mutex); | ||
994 | return; | ||
995 | } | ||
996 | |||
997 | if (info->gd) | ||
998 | bdev = bdget_disk(info->gd, 0); | ||
999 | |||
1000 | mutex_unlock(&info->mutex); | ||
1001 | |||
1002 | if (!bdev) { | ||
1003 | xenbus_frontend_closed(xbdev); | ||
1004 | return; | ||
1005 | } | ||
1006 | |||
1007 | mutex_lock(&bdev->bd_mutex); | ||
1008 | |||
1009 | if (bdev->bd_openers) { | ||
1010 | xenbus_dev_error(xbdev, -EBUSY, | ||
1011 | "Device in use; refusing to close"); | ||
1012 | xenbus_switch_state(xbdev, XenbusStateClosing); | ||
1013 | } else { | ||
1014 | xlvbd_release_gendisk(info); | ||
1015 | xenbus_frontend_closed(xbdev); | ||
1016 | } | ||
1017 | |||
1018 | mutex_unlock(&bdev->bd_mutex); | ||
1019 | bdput(bdev); | ||
1020 | } | ||
891 | 1021 | ||
892 | /* | 1022 | /* |
893 | * Invoked when the backend is finally 'ready' (and has told produced | 1023 | * Invoked when the backend is finally 'ready' (and has told produced |
@@ -899,11 +1029,31 @@ static void blkfront_connect(struct blkfront_info *info) | |||
899 | unsigned long sector_size; | 1029 | unsigned long sector_size; |
900 | unsigned int binfo; | 1030 | unsigned int binfo; |
901 | int err; | 1031 | int err; |
902 | 1032 | int barrier; | |
903 | if ((info->connected == BLKIF_STATE_CONNECTED) || | 1033 | |
904 | (info->connected == BLKIF_STATE_SUSPENDED) ) | 1034 | switch (info->connected) { |
1035 | case BLKIF_STATE_CONNECTED: | ||
1036 | /* | ||
1037 | * Potentially, the back-end may be signalling | ||
1038 | * a capacity change; update the capacity. | ||
1039 | */ | ||
1040 | err = xenbus_scanf(XBT_NIL, info->xbdev->otherend, | ||
1041 | "sectors", "%Lu", §ors); | ||
1042 | if (XENBUS_EXIST_ERR(err)) | ||
1043 | return; | ||
1044 | printk(KERN_INFO "Setting capacity to %Lu\n", | ||
1045 | sectors); | ||
1046 | set_capacity(info->gd, sectors); | ||
1047 | revalidate_disk(info->gd); | ||
1048 | |||
1049 | /* fall through */ | ||
1050 | case BLKIF_STATE_SUSPENDED: | ||
905 | return; | 1051 | return; |
906 | 1052 | ||
1053 | default: | ||
1054 | break; | ||
1055 | } | ||
1056 | |||
907 | dev_dbg(&info->xbdev->dev, "%s:%s.\n", | 1057 | dev_dbg(&info->xbdev->dev, "%s:%s.\n", |
908 | __func__, info->xbdev->otherend); | 1058 | __func__, info->xbdev->otherend); |
909 | 1059 | ||
@@ -920,10 +1070,26 @@ static void blkfront_connect(struct blkfront_info *info) | |||
920 | } | 1070 | } |
921 | 1071 | ||
922 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | 1072 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, |
923 | "feature-barrier", "%lu", &info->feature_barrier, | 1073 | "feature-barrier", "%lu", &barrier, |
924 | NULL); | 1074 | NULL); |
1075 | |||
1076 | /* | ||
1077 | * If there's no "feature-barrier" defined, then it means | ||
1078 | * we're dealing with a very old backend which writes | ||
1079 | * synchronously; draining will do what needs to get done. | ||
1080 | * | ||
1081 | * If there are barriers, then we can do full queued writes | ||
1082 | * with tagged barriers. | ||
1083 | * | ||
1084 | * If barriers are not supported, then there's no much we can | ||
1085 | * do, so just set ordering to NONE. | ||
1086 | */ | ||
925 | if (err) | 1087 | if (err) |
926 | info->feature_barrier = 0; | 1088 | info->feature_barrier = QUEUE_ORDERED_DRAIN; |
1089 | else if (barrier) | ||
1090 | info->feature_barrier = QUEUE_ORDERED_TAG; | ||
1091 | else | ||
1092 | info->feature_barrier = QUEUE_ORDERED_NONE; | ||
927 | 1093 | ||
928 | err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size); | 1094 | err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size); |
929 | if (err) { | 1095 | if (err) { |
@@ -946,52 +1112,14 @@ static void blkfront_connect(struct blkfront_info *info) | |||
946 | } | 1112 | } |
947 | 1113 | ||
948 | /** | 1114 | /** |
949 | * Handle the change of state of the backend to Closing. We must delete our | ||
950 | * device-layer structures now, to ensure that writes are flushed through to | ||
951 | * the backend. Once is this done, we can switch to Closed in | ||
952 | * acknowledgement. | ||
953 | */ | ||
954 | static void blkfront_closing(struct xenbus_device *dev) | ||
955 | { | ||
956 | struct blkfront_info *info = dev_get_drvdata(&dev->dev); | ||
957 | unsigned long flags; | ||
958 | |||
959 | dev_dbg(&dev->dev, "blkfront_closing: %s removed\n", dev->nodename); | ||
960 | |||
961 | if (info->rq == NULL) | ||
962 | goto out; | ||
963 | |||
964 | spin_lock_irqsave(&blkif_io_lock, flags); | ||
965 | |||
966 | /* No more blkif_request(). */ | ||
967 | blk_stop_queue(info->rq); | ||
968 | |||
969 | /* No more gnttab callback work. */ | ||
970 | gnttab_cancel_free_callback(&info->callback); | ||
971 | spin_unlock_irqrestore(&blkif_io_lock, flags); | ||
972 | |||
973 | /* Flush gnttab callback work. Must be done with no locks held. */ | ||
974 | flush_scheduled_work(); | ||
975 | |||
976 | blk_cleanup_queue(info->rq); | ||
977 | info->rq = NULL; | ||
978 | |||
979 | del_gendisk(info->gd); | ||
980 | |||
981 | out: | ||
982 | xenbus_frontend_closed(dev); | ||
983 | } | ||
984 | |||
985 | /** | ||
986 | * Callback received when the backend's state changes. | 1115 | * Callback received when the backend's state changes. |
987 | */ | 1116 | */ |
988 | static void backend_changed(struct xenbus_device *dev, | 1117 | static void blkback_changed(struct xenbus_device *dev, |
989 | enum xenbus_state backend_state) | 1118 | enum xenbus_state backend_state) |
990 | { | 1119 | { |
991 | struct blkfront_info *info = dev_get_drvdata(&dev->dev); | 1120 | struct blkfront_info *info = dev_get_drvdata(&dev->dev); |
992 | struct block_device *bd; | ||
993 | 1121 | ||
994 | dev_dbg(&dev->dev, "blkfront:backend_changed.\n"); | 1122 | dev_dbg(&dev->dev, "blkfront:blkback_changed to state %d.\n", backend_state); |
995 | 1123 | ||
996 | switch (backend_state) { | 1124 | switch (backend_state) { |
997 | case XenbusStateInitialising: | 1125 | case XenbusStateInitialising: |
@@ -1006,35 +1134,56 @@ static void backend_changed(struct xenbus_device *dev, | |||
1006 | break; | 1134 | break; |
1007 | 1135 | ||
1008 | case XenbusStateClosing: | 1136 | case XenbusStateClosing: |
1009 | if (info->gd == NULL) { | 1137 | blkfront_closing(info); |
1010 | xenbus_frontend_closed(dev); | ||
1011 | break; | ||
1012 | } | ||
1013 | bd = bdget_disk(info->gd, 0); | ||
1014 | if (bd == NULL) | ||
1015 | xenbus_dev_fatal(dev, -ENODEV, "bdget failed"); | ||
1016 | |||
1017 | mutex_lock(&bd->bd_mutex); | ||
1018 | if (info->users > 0) | ||
1019 | xenbus_dev_error(dev, -EBUSY, | ||
1020 | "Device in use; refusing to close"); | ||
1021 | else | ||
1022 | blkfront_closing(dev); | ||
1023 | mutex_unlock(&bd->bd_mutex); | ||
1024 | bdput(bd); | ||
1025 | break; | 1138 | break; |
1026 | } | 1139 | } |
1027 | } | 1140 | } |
1028 | 1141 | ||
1029 | static int blkfront_remove(struct xenbus_device *dev) | 1142 | static int blkfront_remove(struct xenbus_device *xbdev) |
1030 | { | 1143 | { |
1031 | struct blkfront_info *info = dev_get_drvdata(&dev->dev); | 1144 | struct blkfront_info *info = dev_get_drvdata(&xbdev->dev); |
1145 | struct block_device *bdev = NULL; | ||
1146 | struct gendisk *disk; | ||
1032 | 1147 | ||
1033 | dev_dbg(&dev->dev, "blkfront_remove: %s removed\n", dev->nodename); | 1148 | dev_dbg(&xbdev->dev, "%s removed", xbdev->nodename); |
1034 | 1149 | ||
1035 | blkif_free(info, 0); | 1150 | blkif_free(info, 0); |
1036 | 1151 | ||
1037 | kfree(info); | 1152 | mutex_lock(&info->mutex); |
1153 | |||
1154 | disk = info->gd; | ||
1155 | if (disk) | ||
1156 | bdev = bdget_disk(disk, 0); | ||
1157 | |||
1158 | info->xbdev = NULL; | ||
1159 | mutex_unlock(&info->mutex); | ||
1160 | |||
1161 | if (!bdev) { | ||
1162 | kfree(info); | ||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | /* | ||
1167 | * The xbdev was removed before we reached the Closed | ||
1168 | * state. See if it's safe to remove the disk. If the bdev | ||
1169 | * isn't closed yet, we let release take care of it. | ||
1170 | */ | ||
1171 | |||
1172 | mutex_lock(&bdev->bd_mutex); | ||
1173 | info = disk->private_data; | ||
1174 | |||
1175 | dev_warn(disk_to_dev(disk), | ||
1176 | "%s was hot-unplugged, %d stale handles\n", | ||
1177 | xbdev->nodename, bdev->bd_openers); | ||
1178 | |||
1179 | if (info && !bdev->bd_openers) { | ||
1180 | xlvbd_release_gendisk(info); | ||
1181 | disk->private_data = NULL; | ||
1182 | kfree(info); | ||
1183 | } | ||
1184 | |||
1185 | mutex_unlock(&bdev->bd_mutex); | ||
1186 | bdput(bdev); | ||
1038 | 1187 | ||
1039 | return 0; | 1188 | return 0; |
1040 | } | 1189 | } |
@@ -1043,30 +1192,78 @@ static int blkfront_is_ready(struct xenbus_device *dev) | |||
1043 | { | 1192 | { |
1044 | struct blkfront_info *info = dev_get_drvdata(&dev->dev); | 1193 | struct blkfront_info *info = dev_get_drvdata(&dev->dev); |
1045 | 1194 | ||
1046 | return info->is_ready; | 1195 | return info->is_ready && info->xbdev; |
1047 | } | 1196 | } |
1048 | 1197 | ||
1049 | static int blkif_open(struct block_device *bdev, fmode_t mode) | 1198 | static int blkif_open(struct block_device *bdev, fmode_t mode) |
1050 | { | 1199 | { |
1051 | struct blkfront_info *info = bdev->bd_disk->private_data; | 1200 | struct gendisk *disk = bdev->bd_disk; |
1052 | info->users++; | 1201 | struct blkfront_info *info; |
1053 | return 0; | 1202 | int err = 0; |
1203 | |||
1204 | lock_kernel(); | ||
1205 | |||
1206 | info = disk->private_data; | ||
1207 | if (!info) { | ||
1208 | /* xbdev gone */ | ||
1209 | err = -ERESTARTSYS; | ||
1210 | goto out; | ||
1211 | } | ||
1212 | |||
1213 | mutex_lock(&info->mutex); | ||
1214 | |||
1215 | if (!info->gd) | ||
1216 | /* xbdev is closed */ | ||
1217 | err = -ERESTARTSYS; | ||
1218 | |||
1219 | mutex_unlock(&info->mutex); | ||
1220 | |||
1221 | out: | ||
1222 | unlock_kernel(); | ||
1223 | return err; | ||
1054 | } | 1224 | } |
1055 | 1225 | ||
1056 | static int blkif_release(struct gendisk *disk, fmode_t mode) | 1226 | static int blkif_release(struct gendisk *disk, fmode_t mode) |
1057 | { | 1227 | { |
1058 | struct blkfront_info *info = disk->private_data; | 1228 | struct blkfront_info *info = disk->private_data; |
1059 | info->users--; | 1229 | struct block_device *bdev; |
1060 | if (info->users == 0) { | 1230 | struct xenbus_device *xbdev; |
1061 | /* Check whether we have been instructed to close. We will | 1231 | |
1062 | have ignored this request initially, as the device was | 1232 | lock_kernel(); |
1063 | still mounted. */ | 1233 | |
1064 | struct xenbus_device *dev = info->xbdev; | 1234 | bdev = bdget_disk(disk, 0); |
1065 | enum xenbus_state state = xenbus_read_driver_state(dev->otherend); | 1235 | bdput(bdev); |
1066 | 1236 | ||
1067 | if (state == XenbusStateClosing && info->is_ready) | 1237 | if (bdev->bd_openers) |
1068 | blkfront_closing(dev); | 1238 | goto out; |
1239 | |||
1240 | /* | ||
1241 | * Check if we have been instructed to close. We will have | ||
1242 | * deferred this request, because the bdev was still open. | ||
1243 | */ | ||
1244 | |||
1245 | mutex_lock(&info->mutex); | ||
1246 | xbdev = info->xbdev; | ||
1247 | |||
1248 | if (xbdev && xbdev->state == XenbusStateClosing) { | ||
1249 | /* pending switch to state closed */ | ||
1250 | dev_info(disk_to_dev(bdev->bd_disk), "releasing disk\n"); | ||
1251 | xlvbd_release_gendisk(info); | ||
1252 | xenbus_frontend_closed(info->xbdev); | ||
1253 | } | ||
1254 | |||
1255 | mutex_unlock(&info->mutex); | ||
1256 | |||
1257 | if (!xbdev) { | ||
1258 | /* sudden device removal */ | ||
1259 | dev_info(disk_to_dev(bdev->bd_disk), "releasing disk\n"); | ||
1260 | xlvbd_release_gendisk(info); | ||
1261 | disk->private_data = NULL; | ||
1262 | kfree(info); | ||
1069 | } | 1263 | } |
1264 | |||
1265 | out: | ||
1266 | unlock_kernel(); | ||
1070 | return 0; | 1267 | return 0; |
1071 | } | 1268 | } |
1072 | 1269 | ||
@@ -1076,7 +1273,7 @@ static const struct block_device_operations xlvbd_block_fops = | |||
1076 | .open = blkif_open, | 1273 | .open = blkif_open, |
1077 | .release = blkif_release, | 1274 | .release = blkif_release, |
1078 | .getgeo = blkif_getgeo, | 1275 | .getgeo = blkif_getgeo, |
1079 | .locked_ioctl = blkif_ioctl, | 1276 | .ioctl = blkif_ioctl, |
1080 | }; | 1277 | }; |
1081 | 1278 | ||
1082 | 1279 | ||
@@ -1092,7 +1289,7 @@ static struct xenbus_driver blkfront = { | |||
1092 | .probe = blkfront_probe, | 1289 | .probe = blkfront_probe, |
1093 | .remove = blkfront_remove, | 1290 | .remove = blkfront_remove, |
1094 | .resume = blkfront_resume, | 1291 | .resume = blkfront_resume, |
1095 | .otherend_changed = backend_changed, | 1292 | .otherend_changed = blkback_changed, |
1096 | .is_ready = blkfront_is_ready, | 1293 | .is_ready = blkfront_is_ready, |
1097 | }; | 1294 | }; |
1098 | 1295 | ||
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index a7b83c0a7eb5..b71888b909a0 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c | |||
@@ -89,6 +89,7 @@ | |||
89 | #include <linux/delay.h> | 89 | #include <linux/delay.h> |
90 | #include <linux/slab.h> | 90 | #include <linux/slab.h> |
91 | #include <linux/blkdev.h> | 91 | #include <linux/blkdev.h> |
92 | #include <linux/smp_lock.h> | ||
92 | #include <linux/ata.h> | 93 | #include <linux/ata.h> |
93 | #include <linux/hdreg.h> | 94 | #include <linux/hdreg.h> |
94 | #include <linux/platform_device.h> | 95 | #include <linux/platform_device.h> |
@@ -465,7 +466,7 @@ struct request *ace_get_next_request(struct request_queue * q) | |||
465 | struct request *req; | 466 | struct request *req; |
466 | 467 | ||
467 | while ((req = blk_peek_request(q)) != NULL) { | 468 | while ((req = blk_peek_request(q)) != NULL) { |
468 | if (blk_fs_request(req)) | 469 | if (req->cmd_type == REQ_TYPE_FS) |
469 | break; | 470 | break; |
470 | blk_start_request(req); | 471 | blk_start_request(req); |
471 | __blk_end_request_all(req, -EIO); | 472 | __blk_end_request_all(req, -EIO); |
@@ -901,11 +902,14 @@ static int ace_open(struct block_device *bdev, fmode_t mode) | |||
901 | 902 | ||
902 | dev_dbg(ace->dev, "ace_open() users=%i\n", ace->users + 1); | 903 | dev_dbg(ace->dev, "ace_open() users=%i\n", ace->users + 1); |
903 | 904 | ||
905 | lock_kernel(); | ||
904 | spin_lock_irqsave(&ace->lock, flags); | 906 | spin_lock_irqsave(&ace->lock, flags); |
905 | ace->users++; | 907 | ace->users++; |
906 | spin_unlock_irqrestore(&ace->lock, flags); | 908 | spin_unlock_irqrestore(&ace->lock, flags); |
907 | 909 | ||
908 | check_disk_change(bdev); | 910 | check_disk_change(bdev); |
911 | unlock_kernel(); | ||
912 | |||
909 | return 0; | 913 | return 0; |
910 | } | 914 | } |
911 | 915 | ||
@@ -917,6 +921,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode) | |||
917 | 921 | ||
918 | dev_dbg(ace->dev, "ace_release() users=%i\n", ace->users - 1); | 922 | dev_dbg(ace->dev, "ace_release() users=%i\n", ace->users - 1); |
919 | 923 | ||
924 | lock_kernel(); | ||
920 | spin_lock_irqsave(&ace->lock, flags); | 925 | spin_lock_irqsave(&ace->lock, flags); |
921 | ace->users--; | 926 | ace->users--; |
922 | if (ace->users == 0) { | 927 | if (ace->users == 0) { |
@@ -924,6 +929,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode) | |||
924 | ace_out(ace, ACE_CTRL, val & ~ACE_CTRL_LOCKREQ); | 929 | ace_out(ace, ACE_CTRL, val & ~ACE_CTRL_LOCKREQ); |
925 | } | 930 | } |
926 | spin_unlock_irqrestore(&ace->lock, flags); | 931 | spin_unlock_irqrestore(&ace->lock, flags); |
932 | unlock_kernel(); | ||
927 | return 0; | 933 | return 0; |
928 | } | 934 | } |
929 | 935 | ||
diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 9114654b54d9..d75b2bb601ad 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/blkdev.h> | 34 | #include <linux/blkdev.h> |
35 | #include <linux/bitops.h> | 35 | #include <linux/bitops.h> |
36 | #include <linux/smp_lock.h> | ||
36 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
37 | 38 | ||
38 | #include <asm/setup.h> | 39 | #include <asm/setup.h> |
@@ -153,6 +154,7 @@ static int z2_open(struct block_device *bdev, fmode_t mode) | |||
153 | 154 | ||
154 | device = MINOR(bdev->bd_dev); | 155 | device = MINOR(bdev->bd_dev); |
155 | 156 | ||
157 | lock_kernel(); | ||
156 | if ( current_device != -1 && current_device != device ) | 158 | if ( current_device != -1 && current_device != device ) |
157 | { | 159 | { |
158 | rc = -EBUSY; | 160 | rc = -EBUSY; |
@@ -294,20 +296,25 @@ static int z2_open(struct block_device *bdev, fmode_t mode) | |||
294 | set_capacity(z2ram_gendisk, z2ram_size >> 9); | 296 | set_capacity(z2ram_gendisk, z2ram_size >> 9); |
295 | } | 297 | } |
296 | 298 | ||
299 | unlock_kernel(); | ||
297 | return 0; | 300 | return 0; |
298 | 301 | ||
299 | err_out_kfree: | 302 | err_out_kfree: |
300 | kfree(z2ram_map); | 303 | kfree(z2ram_map); |
301 | err_out: | 304 | err_out: |
305 | unlock_kernel(); | ||
302 | return rc; | 306 | return rc; |
303 | } | 307 | } |
304 | 308 | ||
305 | static int | 309 | static int |
306 | z2_release(struct gendisk *disk, fmode_t mode) | 310 | z2_release(struct gendisk *disk, fmode_t mode) |
307 | { | 311 | { |
308 | if ( current_device == -1 ) | 312 | lock_kernel(); |
309 | return 0; | 313 | if ( current_device == -1 ) { |
310 | 314 | unlock_kernel(); | |
315 | return 0; | ||
316 | } | ||
317 | unlock_kernel(); | ||
311 | /* | 318 | /* |
312 | * FIXME: unmap memory | 319 | * FIXME: unmap memory |
313 | */ | 320 | */ |