diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-07 21:13:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-08-07 21:13:30 -0400 |
commit | 8e43e12d638f732fa32600c324711f4be8fe0b1d (patch) | |
tree | a0e545bebea11b3ce08147d2e36f2acb1a13de1d | |
parent | 01b09b6c605ed119fba75b82582f017e44dd4a55 (diff) | |
parent | 62aa0054da220b8bbe6f23c0eb1d97a99005d0b3 (diff) |
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
xen-blkfront.c: make blkif_ioctl() static
bio: make use of bvec_nr_vecs
cciss: fix bug if scsi tape support is disabled
cciss: add support for multi lun tape devices
cciss: change the way we notify scsi midlayer of tape drives
cciss: fix negative logical drive count in procfs
cciss: remove redundant code
cciss: make rebuild_lun_table behave better
cciss: return -EFAULT if copy_from_user() fails
-rw-r--r-- | Documentation/cciss.txt | 21 | ||||
-rw-r--r-- | drivers/block/cciss.c | 748 | ||||
-rw-r--r-- | drivers/block/cciss.h | 2 | ||||
-rw-r--r-- | drivers/block/cciss_scsi.c | 195 | ||||
-rw-r--r-- | drivers/block/xen-blkfront.c | 4 | ||||
-rw-r--r-- | fs/bio.c | 9 |
6 files changed, 522 insertions, 457 deletions
diff --git a/Documentation/cciss.txt b/Documentation/cciss.txt index 63e59b8847c5..8244c6442faa 100644 --- a/Documentation/cciss.txt +++ b/Documentation/cciss.txt | |||
@@ -112,27 +112,18 @@ Hot plug support for SCSI tape drives | |||
112 | 112 | ||
113 | Hot plugging of SCSI tape drives is supported, with some caveats. | 113 | Hot plugging of SCSI tape drives is supported, with some caveats. |
114 | The cciss driver must be informed that changes to the SCSI bus | 114 | The cciss driver must be informed that changes to the SCSI bus |
115 | have been made, in addition to and prior to informing the SCSI | 115 | have been made. This may be done via the /proc filesystem. |
116 | mid layer. This may be done via the /proc filesystem. For example: | 116 | For example: |
117 | 117 | ||
118 | echo "rescan" > /proc/scsi/cciss0/1 | 118 | echo "rescan" > /proc/scsi/cciss0/1 |
119 | 119 | ||
120 | This causes the adapter to query the adapter about changes to the | 120 | This causes the driver to query the adapter about changes to the |
121 | physical SCSI buses and/or fibre channel arbitrated loop and the | 121 | physical SCSI buses and/or fibre channel arbitrated loop and the |
122 | driver to make note of any new or removed sequential access devices | 122 | driver to make note of any new or removed sequential access devices |
123 | or medium changers. The driver will output messages indicating what | 123 | or medium changers. The driver will output messages indicating what |
124 | devices have been added or removed and the controller, bus, target and | 124 | devices have been added or removed and the controller, bus, target and |
125 | lun used to address the device. Once this is done, the SCSI mid layer | 125 | lun used to address the device. It then notifies the SCSI mid layer |
126 | can be informed of changes to the virtual SCSI bus which the driver | 126 | of these changes. |
127 | presents to it in the usual way. For example: | ||
128 | |||
129 | echo scsi add-single-device 3 2 1 0 > /proc/scsi/scsi | ||
130 | |||
131 | to add a device on controller 3, bus 2, target 1, lun 0. Note that | ||
132 | the driver makes an effort to preserve the devices positions | ||
133 | in the virtual SCSI bus, so if you are only moving tape drives | ||
134 | around on the same adapter and not adding or removing tape drives | ||
135 | from the adapter, informing the SCSI mid layer may not be necessary. | ||
136 | 127 | ||
137 | Note that the naming convention of the /proc filesystem entries | 128 | Note that the naming convention of the /proc filesystem entries |
138 | contains a number in addition to the driver name. (E.g. "cciss0" | 129 | contains a number in addition to the driver name. (E.g. "cciss0" |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 0ce0c279aabf..b73116ef9236 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -159,7 +159,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
159 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); | 159 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); |
160 | 160 | ||
161 | static int cciss_revalidate(struct gendisk *disk); | 161 | static int cciss_revalidate(struct gendisk *disk); |
162 | static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk); | 162 | static int rebuild_lun_table(ctlr_info_t *h, int first_time); |
163 | static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | 163 | static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, |
164 | int clear_all); | 164 | int clear_all); |
165 | 165 | ||
@@ -171,7 +171,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, | |||
171 | int withirq, sector_t total_size, | 171 | int withirq, sector_t total_size, |
172 | unsigned int block_size, InquiryData_struct *inq_buff, | 172 | unsigned int block_size, InquiryData_struct *inq_buff, |
173 | drive_info_struct *drv); | 173 | drive_info_struct *drv); |
174 | static void cciss_getgeometry(int cntl_num); | ||
175 | static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, | 174 | static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, |
176 | __u32); | 175 | __u32); |
177 | static void start_io(ctlr_info_t *h); | 176 | static void start_io(ctlr_info_t *h); |
@@ -929,8 +928,10 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
929 | return 0; | 928 | return 0; |
930 | } | 929 | } |
931 | 930 | ||
931 | case CCISS_DEREGDISK: | ||
932 | case CCISS_REGNEWD: | ||
932 | case CCISS_REVALIDVOLS: | 933 | case CCISS_REVALIDVOLS: |
933 | return rebuild_lun_table(host, NULL); | 934 | return rebuild_lun_table(host, 0); |
934 | 935 | ||
935 | case CCISS_GETLUNINFO:{ | 936 | case CCISS_GETLUNINFO:{ |
936 | LogvolInfo_struct luninfo; | 937 | LogvolInfo_struct luninfo; |
@@ -943,12 +944,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
943 | return -EFAULT; | 944 | return -EFAULT; |
944 | return 0; | 945 | return 0; |
945 | } | 946 | } |
946 | case CCISS_DEREGDISK: | ||
947 | return rebuild_lun_table(host, disk); | ||
948 | |||
949 | case CCISS_REGNEWD: | ||
950 | return rebuild_lun_table(host, NULL); | ||
951 | |||
952 | case CCISS_PASSTHRU: | 947 | case CCISS_PASSTHRU: |
953 | { | 948 | { |
954 | IOCTL_Command_struct iocommand; | 949 | IOCTL_Command_struct iocommand; |
@@ -1134,7 +1129,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
1134 | if (ioc->Request.Type.Direction == XFER_WRITE) { | 1129 | if (ioc->Request.Type.Direction == XFER_WRITE) { |
1135 | if (copy_from_user | 1130 | if (copy_from_user |
1136 | (buff[sg_used], data_ptr, sz)) { | 1131 | (buff[sg_used], data_ptr, sz)) { |
1137 | status = -ENOMEM; | 1132 | status = -EFAULT; |
1138 | goto cleanup1; | 1133 | goto cleanup1; |
1139 | } | 1134 | } |
1140 | } else { | 1135 | } else { |
@@ -1330,15 +1325,84 @@ static void cciss_softirq_done(struct request *rq) | |||
1330 | spin_unlock_irqrestore(&h->lock, flags); | 1325 | spin_unlock_irqrestore(&h->lock, flags); |
1331 | } | 1326 | } |
1332 | 1327 | ||
1328 | /* This function gets the serial number of a logical drive via | ||
1329 | * inquiry page 0x83. Serial no. is 16 bytes. If the serial | ||
1330 | * number cannot be had, for whatever reason, 16 bytes of 0xff | ||
1331 | * are returned instead. | ||
1332 | */ | ||
1333 | static void cciss_get_serial_no(int ctlr, int logvol, int withirq, | ||
1334 | unsigned char *serial_no, int buflen) | ||
1335 | { | ||
1336 | #define PAGE_83_INQ_BYTES 64 | ||
1337 | int rc; | ||
1338 | unsigned char *buf; | ||
1339 | |||
1340 | if (buflen > 16) | ||
1341 | buflen = 16; | ||
1342 | memset(serial_no, 0xff, buflen); | ||
1343 | buf = kzalloc(PAGE_83_INQ_BYTES, GFP_KERNEL); | ||
1344 | if (!buf) | ||
1345 | return; | ||
1346 | memset(serial_no, 0, buflen); | ||
1347 | if (withirq) | ||
1348 | rc = sendcmd_withirq(CISS_INQUIRY, ctlr, buf, | ||
1349 | PAGE_83_INQ_BYTES, 1, logvol, 0x83, TYPE_CMD); | ||
1350 | else | ||
1351 | rc = sendcmd(CISS_INQUIRY, ctlr, buf, | ||
1352 | PAGE_83_INQ_BYTES, 1, logvol, 0x83, NULL, TYPE_CMD); | ||
1353 | if (rc == IO_OK) | ||
1354 | memcpy(serial_no, &buf[8], buflen); | ||
1355 | kfree(buf); | ||
1356 | return; | ||
1357 | } | ||
1358 | |||
1359 | static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | ||
1360 | int drv_index) | ||
1361 | { | ||
1362 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | ||
1363 | sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index); | ||
1364 | disk->major = h->major; | ||
1365 | disk->first_minor = drv_index << NWD_SHIFT; | ||
1366 | disk->fops = &cciss_fops; | ||
1367 | disk->private_data = &h->drv[drv_index]; | ||
1368 | |||
1369 | /* Set up queue information */ | ||
1370 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); | ||
1371 | |||
1372 | /* This is a hardware imposed limit. */ | ||
1373 | blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES); | ||
1374 | |||
1375 | /* This is a limit in the driver and could be eliminated. */ | ||
1376 | blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); | ||
1377 | |||
1378 | blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); | ||
1379 | |||
1380 | blk_queue_softirq_done(disk->queue, cciss_softirq_done); | ||
1381 | |||
1382 | disk->queue->queuedata = h; | ||
1383 | |||
1384 | blk_queue_hardsect_size(disk->queue, | ||
1385 | h->drv[drv_index].block_size); | ||
1386 | |||
1387 | /* Make sure all queue data is written out before */ | ||
1388 | /* setting h->drv[drv_index].queue, as setting this */ | ||
1389 | /* allows the interrupt handler to start the queue */ | ||
1390 | wmb(); | ||
1391 | h->drv[drv_index].queue = disk->queue; | ||
1392 | add_disk(disk); | ||
1393 | } | ||
1394 | |||
1333 | /* This function will check the usage_count of the drive to be updated/added. | 1395 | /* This function will check the usage_count of the drive to be updated/added. |
1334 | * If the usage_count is zero then the drive information will be updated and | 1396 | * If the usage_count is zero and it is a heretofore unknown drive, or, |
1335 | * the disk will be re-registered with the kernel. If not then it will be | 1397 | * the drive's capacity, geometry, or serial number has changed, |
1336 | * left alone for the next reboot. The exception to this is disk 0 which | 1398 | * then the drive information will be updated and the disk will be |
1337 | * will always be left registered with the kernel since it is also the | 1399 | * re-registered with the kernel. If these conditions don't hold, |
1338 | * controller node. Any changes to disk 0 will show up on the next | 1400 | * then it will be left alone for the next reboot. The exception to this |
1339 | * reboot. | 1401 | * is disk 0 which will always be left registered with the kernel since it |
1402 | * is also the controller node. Any changes to disk 0 will show up on | ||
1403 | * the next reboot. | ||
1340 | */ | 1404 | */ |
1341 | static void cciss_update_drive_info(int ctlr, int drv_index) | 1405 | static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) |
1342 | { | 1406 | { |
1343 | ctlr_info_t *h = hba[ctlr]; | 1407 | ctlr_info_t *h = hba[ctlr]; |
1344 | struct gendisk *disk; | 1408 | struct gendisk *disk; |
@@ -1347,16 +1411,81 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
1347 | sector_t total_size; | 1411 | sector_t total_size; |
1348 | unsigned long flags = 0; | 1412 | unsigned long flags = 0; |
1349 | int ret = 0; | 1413 | int ret = 0; |
1414 | drive_info_struct *drvinfo; | ||
1415 | int was_only_controller_node; | ||
1416 | |||
1417 | /* Get information about the disk and modify the driver structure */ | ||
1418 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
1419 | drvinfo = kmalloc(sizeof(*drvinfo), GFP_KERNEL); | ||
1420 | if (inq_buff == NULL || drvinfo == NULL) | ||
1421 | goto mem_msg; | ||
1422 | |||
1423 | /* See if we're trying to update the "controller node" | ||
1424 | * this will happen the when the first logical drive gets | ||
1425 | * created by ACU. | ||
1426 | */ | ||
1427 | was_only_controller_node = (drv_index == 0 && | ||
1428 | h->drv[0].raid_level == -1); | ||
1350 | 1429 | ||
1351 | /* if the disk already exists then deregister it before proceeding */ | 1430 | /* testing to see if 16-byte CDBs are already being used */ |
1352 | if (h->drv[drv_index].raid_level != -1) { | 1431 | if (h->cciss_read == CCISS_READ_16) { |
1432 | cciss_read_capacity_16(h->ctlr, drv_index, 1, | ||
1433 | &total_size, &block_size); | ||
1434 | |||
1435 | } else { | ||
1436 | cciss_read_capacity(ctlr, drv_index, 1, | ||
1437 | &total_size, &block_size); | ||
1438 | |||
1439 | /* if read_capacity returns all F's this volume is >2TB */ | ||
1440 | /* in size so we switch to 16-byte CDB's for all */ | ||
1441 | /* read/write ops */ | ||
1442 | if (total_size == 0xFFFFFFFFULL) { | ||
1443 | cciss_read_capacity_16(ctlr, drv_index, 1, | ||
1444 | &total_size, &block_size); | ||
1445 | h->cciss_read = CCISS_READ_16; | ||
1446 | h->cciss_write = CCISS_WRITE_16; | ||
1447 | } else { | ||
1448 | h->cciss_read = CCISS_READ_10; | ||
1449 | h->cciss_write = CCISS_WRITE_10; | ||
1450 | } | ||
1451 | } | ||
1452 | |||
1453 | cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, | ||
1454 | inq_buff, drvinfo); | ||
1455 | drvinfo->block_size = block_size; | ||
1456 | drvinfo->nr_blocks = total_size + 1; | ||
1457 | |||
1458 | cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, | ||
1459 | sizeof(drvinfo->serial_no)); | ||
1460 | |||
1461 | /* Is it the same disk we already know, and nothing's changed? */ | ||
1462 | if (h->drv[drv_index].raid_level != -1 && | ||
1463 | ((memcmp(drvinfo->serial_no, | ||
1464 | h->drv[drv_index].serial_no, 16) == 0) && | ||
1465 | drvinfo->block_size == h->drv[drv_index].block_size && | ||
1466 | drvinfo->nr_blocks == h->drv[drv_index].nr_blocks && | ||
1467 | drvinfo->heads == h->drv[drv_index].heads && | ||
1468 | drvinfo->sectors == h->drv[drv_index].sectors && | ||
1469 | drvinfo->cylinders == h->drv[drv_index].cylinders)) | ||
1470 | /* The disk is unchanged, nothing to update */ | ||
1471 | goto freeret; | ||
1472 | |||
1473 | /* If we get here it's not the same disk, or something's changed, | ||
1474 | * so we need to * deregister it, and re-register it, if it's not | ||
1475 | * in use. | ||
1476 | * If the disk already exists then deregister it before proceeding | ||
1477 | * (unless it's the first disk (for the controller node). | ||
1478 | */ | ||
1479 | if (h->drv[drv_index].raid_level != -1 && drv_index != 0) { | ||
1480 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); | ||
1353 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1481 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
1354 | h->drv[drv_index].busy_configuring = 1; | 1482 | h->drv[drv_index].busy_configuring = 1; |
1355 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1483 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
1356 | 1484 | ||
1357 | /* deregister_disk sets h->drv[drv_index].queue = NULL */ | 1485 | /* deregister_disk sets h->drv[drv_index].queue = NULL |
1358 | /* which keeps the interrupt handler from starting */ | 1486 | * which keeps the interrupt handler from starting |
1359 | /* the queue. */ | 1487 | * the queue. |
1488 | */ | ||
1360 | ret = deregister_disk(h->gendisk[drv_index], | 1489 | ret = deregister_disk(h->gendisk[drv_index], |
1361 | &h->drv[drv_index], 0); | 1490 | &h->drv[drv_index], 0); |
1362 | h->drv[drv_index].busy_configuring = 0; | 1491 | h->drv[drv_index].busy_configuring = 0; |
@@ -1364,81 +1493,37 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
1364 | 1493 | ||
1365 | /* If the disk is in use return */ | 1494 | /* If the disk is in use return */ |
1366 | if (ret) | 1495 | if (ret) |
1367 | return; | 1496 | goto freeret; |
1368 | 1497 | ||
1369 | /* Get information about the disk and modify the driver structure */ | 1498 | /* Save the new information from cciss_geometry_inquiry |
1370 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | 1499 | * and serial number inquiry. |
1371 | if (inq_buff == NULL) | 1500 | */ |
1372 | goto mem_msg; | 1501 | h->drv[drv_index].block_size = drvinfo->block_size; |
1373 | 1502 | h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; | |
1374 | /* testing to see if 16-byte CDBs are already being used */ | 1503 | h->drv[drv_index].heads = drvinfo->heads; |
1375 | if (h->cciss_read == CCISS_READ_16) { | 1504 | h->drv[drv_index].sectors = drvinfo->sectors; |
1376 | cciss_read_capacity_16(h->ctlr, drv_index, 1, | 1505 | h->drv[drv_index].cylinders = drvinfo->cylinders; |
1377 | &total_size, &block_size); | 1506 | h->drv[drv_index].raid_level = drvinfo->raid_level; |
1378 | goto geo_inq; | 1507 | memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16); |
1379 | } | ||
1380 | |||
1381 | cciss_read_capacity(ctlr, drv_index, 1, | ||
1382 | &total_size, &block_size); | ||
1383 | |||
1384 | /* if read_capacity returns all F's this volume is >2TB in size */ | ||
1385 | /* so we switch to 16-byte CDB's for all read/write ops */ | ||
1386 | if (total_size == 0xFFFFFFFFULL) { | ||
1387 | cciss_read_capacity_16(ctlr, drv_index, 1, | ||
1388 | &total_size, &block_size); | ||
1389 | h->cciss_read = CCISS_READ_16; | ||
1390 | h->cciss_write = CCISS_WRITE_16; | ||
1391 | } else { | ||
1392 | h->cciss_read = CCISS_READ_10; | ||
1393 | h->cciss_write = CCISS_WRITE_10; | ||
1394 | } | ||
1395 | geo_inq: | ||
1396 | cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, | ||
1397 | inq_buff, &h->drv[drv_index]); | ||
1398 | 1508 | ||
1399 | ++h->num_luns; | 1509 | ++h->num_luns; |
1400 | disk = h->gendisk[drv_index]; | 1510 | disk = h->gendisk[drv_index]; |
1401 | set_capacity(disk, h->drv[drv_index].nr_blocks); | 1511 | set_capacity(disk, h->drv[drv_index].nr_blocks); |
1402 | 1512 | ||
1403 | /* if it's the controller it's already added */ | 1513 | /* If it's not disk 0 (drv_index != 0) |
1404 | if (drv_index) { | 1514 | * or if it was disk 0, but there was previously |
1405 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | 1515 | * no actual corresponding configured logical drive |
1406 | sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index); | 1516 | * (raid_leve == -1) then we want to update the |
1407 | disk->major = h->major; | 1517 | * logical drive's information. |
1408 | disk->first_minor = drv_index << NWD_SHIFT; | 1518 | */ |
1409 | disk->fops = &cciss_fops; | 1519 | if (drv_index || first_time) |
1410 | disk->private_data = &h->drv[drv_index]; | 1520 | cciss_add_disk(h, disk, drv_index); |
1411 | |||
1412 | /* Set up queue information */ | ||
1413 | blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask); | ||
1414 | |||
1415 | /* This is a hardware imposed limit. */ | ||
1416 | blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES); | ||
1417 | |||
1418 | /* This is a limit in the driver and could be eliminated. */ | ||
1419 | blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); | ||
1420 | |||
1421 | blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); | ||
1422 | |||
1423 | blk_queue_softirq_done(disk->queue, cciss_softirq_done); | ||
1424 | |||
1425 | disk->queue->queuedata = hba[ctlr]; | ||
1426 | |||
1427 | blk_queue_hardsect_size(disk->queue, | ||
1428 | hba[ctlr]->drv[drv_index].block_size); | ||
1429 | |||
1430 | /* Make sure all queue data is written out before */ | ||
1431 | /* setting h->drv[drv_index].queue, as setting this */ | ||
1432 | /* allows the interrupt handler to start the queue */ | ||
1433 | wmb(); | ||
1434 | h->drv[drv_index].queue = disk->queue; | ||
1435 | add_disk(disk); | ||
1436 | } | ||
1437 | 1521 | ||
1438 | freeret: | 1522 | freeret: |
1439 | kfree(inq_buff); | 1523 | kfree(inq_buff); |
1524 | kfree(drvinfo); | ||
1440 | return; | 1525 | return; |
1441 | mem_msg: | 1526 | mem_msg: |
1442 | printk(KERN_ERR "cciss: out of memory\n"); | 1527 | printk(KERN_ERR "cciss: out of memory\n"); |
1443 | goto freeret; | 1528 | goto freeret; |
1444 | } | 1529 | } |
@@ -1448,21 +1533,91 @@ geo_inq: | |||
1448 | * where new drives will be added. If the index to be returned is greater | 1533 | * where new drives will be added. If the index to be returned is greater |
1449 | * than the highest_lun index for the controller then highest_lun is set | 1534 | * than the highest_lun index for the controller then highest_lun is set |
1450 | * to this new index. If there are no available indexes then -1 is returned. | 1535 | * to this new index. If there are no available indexes then -1 is returned. |
1536 | * "controller_node" is used to know if this is a real logical drive, or just | ||
1537 | * the controller node, which determines if this counts towards highest_lun. | ||
1451 | */ | 1538 | */ |
1452 | static int cciss_find_free_drive_index(int ctlr) | 1539 | static int cciss_find_free_drive_index(int ctlr, int controller_node) |
1453 | { | 1540 | { |
1454 | int i; | 1541 | int i; |
1455 | 1542 | ||
1456 | for (i = 0; i < CISS_MAX_LUN; i++) { | 1543 | for (i = 0; i < CISS_MAX_LUN; i++) { |
1457 | if (hba[ctlr]->drv[i].raid_level == -1) { | 1544 | if (hba[ctlr]->drv[i].raid_level == -1) { |
1458 | if (i > hba[ctlr]->highest_lun) | 1545 | if (i > hba[ctlr]->highest_lun) |
1459 | hba[ctlr]->highest_lun = i; | 1546 | if (!controller_node) |
1547 | hba[ctlr]->highest_lun = i; | ||
1460 | return i; | 1548 | return i; |
1461 | } | 1549 | } |
1462 | } | 1550 | } |
1463 | return -1; | 1551 | return -1; |
1464 | } | 1552 | } |
1465 | 1553 | ||
1554 | /* cciss_add_gendisk finds a free hba[]->drv structure | ||
1555 | * and allocates a gendisk if needed, and sets the lunid | ||
1556 | * in the drvinfo structure. It returns the index into | ||
1557 | * the ->drv[] array, or -1 if none are free. | ||
1558 | * is_controller_node indicates whether highest_lun should | ||
1559 | * count this disk, or if it's only being added to provide | ||
1560 | * a means to talk to the controller in case no logical | ||
1561 | * drives have yet been configured. | ||
1562 | */ | ||
1563 | static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) | ||
1564 | { | ||
1565 | int drv_index; | ||
1566 | |||
1567 | drv_index = cciss_find_free_drive_index(h->ctlr, controller_node); | ||
1568 | if (drv_index == -1) | ||
1569 | return -1; | ||
1570 | /*Check if the gendisk needs to be allocated */ | ||
1571 | if (!h->gendisk[drv_index]) { | ||
1572 | h->gendisk[drv_index] = | ||
1573 | alloc_disk(1 << NWD_SHIFT); | ||
1574 | if (!h->gendisk[drv_index]) { | ||
1575 | printk(KERN_ERR "cciss%d: could not " | ||
1576 | "allocate a new disk %d\n", | ||
1577 | h->ctlr, drv_index); | ||
1578 | return -1; | ||
1579 | } | ||
1580 | } | ||
1581 | h->drv[drv_index].LunID = lunid; | ||
1582 | |||
1583 | /* Don't need to mark this busy because nobody */ | ||
1584 | /* else knows about this disk yet to contend */ | ||
1585 | /* for access to it. */ | ||
1586 | h->drv[drv_index].busy_configuring = 0; | ||
1587 | wmb(); | ||
1588 | return drv_index; | ||
1589 | } | ||
1590 | |||
1591 | /* This is for the special case of a controller which | ||
1592 | * has no logical drives. In this case, we still need | ||
1593 | * to register a disk so the controller can be accessed | ||
1594 | * by the Array Config Utility. | ||
1595 | */ | ||
1596 | static void cciss_add_controller_node(ctlr_info_t *h) | ||
1597 | { | ||
1598 | struct gendisk *disk; | ||
1599 | int drv_index; | ||
1600 | |||
1601 | if (h->gendisk[0] != NULL) /* already did this? Then bail. */ | ||
1602 | return; | ||
1603 | |||
1604 | drv_index = cciss_add_gendisk(h, 0, 1); | ||
1605 | if (drv_index == -1) { | ||
1606 | printk(KERN_WARNING "cciss%d: could not " | ||
1607 | "add disk 0.\n", h->ctlr); | ||
1608 | return; | ||
1609 | } | ||
1610 | h->drv[drv_index].block_size = 512; | ||
1611 | h->drv[drv_index].nr_blocks = 0; | ||
1612 | h->drv[drv_index].heads = 0; | ||
1613 | h->drv[drv_index].sectors = 0; | ||
1614 | h->drv[drv_index].cylinders = 0; | ||
1615 | h->drv[drv_index].raid_level = -1; | ||
1616 | memset(h->drv[drv_index].serial_no, 0, 16); | ||
1617 | disk = h->gendisk[drv_index]; | ||
1618 | cciss_add_disk(h, disk, drv_index); | ||
1619 | } | ||
1620 | |||
1466 | /* This function will add and remove logical drives from the Logical | 1621 | /* This function will add and remove logical drives from the Logical |
1467 | * drive array of the controller and maintain persistency of ordering | 1622 | * drive array of the controller and maintain persistency of ordering |
1468 | * so that mount points are preserved until the next reboot. This allows | 1623 | * so that mount points are preserved until the next reboot. This allows |
@@ -1470,15 +1625,12 @@ static int cciss_find_free_drive_index(int ctlr) | |||
1470 | * without a re-ordering of those drives. | 1625 | * without a re-ordering of those drives. |
1471 | * INPUT | 1626 | * INPUT |
1472 | * h = The controller to perform the operations on | 1627 | * h = The controller to perform the operations on |
1473 | * del_disk = The disk to remove if specified. If the value given | ||
1474 | * is NULL then no disk is removed. | ||
1475 | */ | 1628 | */ |
1476 | static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | 1629 | static int rebuild_lun_table(ctlr_info_t *h, int first_time) |
1477 | { | 1630 | { |
1478 | int ctlr = h->ctlr; | 1631 | int ctlr = h->ctlr; |
1479 | int num_luns; | 1632 | int num_luns; |
1480 | ReportLunData_struct *ld_buff = NULL; | 1633 | ReportLunData_struct *ld_buff = NULL; |
1481 | drive_info_struct *drv = NULL; | ||
1482 | int return_code; | 1634 | int return_code; |
1483 | int listlength = 0; | 1635 | int listlength = 0; |
1484 | int i; | 1636 | int i; |
@@ -1487,6 +1639,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1487 | __u32 lunid = 0; | 1639 | __u32 lunid = 0; |
1488 | unsigned long flags; | 1640 | unsigned long flags; |
1489 | 1641 | ||
1642 | if (!capable(CAP_SYS_RAWIO)) | ||
1643 | return -EPERM; | ||
1644 | |||
1490 | /* Set busy_configuring flag for this operation */ | 1645 | /* Set busy_configuring flag for this operation */ |
1491 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1646 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
1492 | if (h->busy_configuring) { | 1647 | if (h->busy_configuring) { |
@@ -1494,100 +1649,100 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1494 | return -EBUSY; | 1649 | return -EBUSY; |
1495 | } | 1650 | } |
1496 | h->busy_configuring = 1; | 1651 | h->busy_configuring = 1; |
1652 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1497 | 1653 | ||
1498 | /* if del_disk is NULL then we are being called to add a new disk | 1654 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); |
1499 | * and update the logical drive table. If it is not NULL then | 1655 | if (ld_buff == NULL) |
1500 | * we will check if the disk is in use or not. | 1656 | goto mem_msg; |
1501 | */ | ||
1502 | if (del_disk != NULL) { | ||
1503 | drv = get_drv(del_disk); | ||
1504 | drv->busy_configuring = 1; | ||
1505 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1506 | return_code = deregister_disk(del_disk, drv, 1); | ||
1507 | drv->busy_configuring = 0; | ||
1508 | h->busy_configuring = 0; | ||
1509 | return return_code; | ||
1510 | } else { | ||
1511 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1512 | if (!capable(CAP_SYS_RAWIO)) | ||
1513 | return -EPERM; | ||
1514 | 1657 | ||
1515 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | 1658 | return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, |
1516 | if (ld_buff == NULL) | 1659 | sizeof(ReportLunData_struct), 0, |
1517 | goto mem_msg; | 1660 | 0, 0, TYPE_CMD); |
1518 | |||
1519 | return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, | ||
1520 | sizeof(ReportLunData_struct), 0, | ||
1521 | 0, 0, TYPE_CMD); | ||
1522 | |||
1523 | if (return_code == IO_OK) { | ||
1524 | listlength = | ||
1525 | be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); | ||
1526 | } else { /* reading number of logical volumes failed */ | ||
1527 | printk(KERN_WARNING "cciss: report logical volume" | ||
1528 | " command failed\n"); | ||
1529 | listlength = 0; | ||
1530 | goto freeret; | ||
1531 | } | ||
1532 | 1661 | ||
1533 | num_luns = listlength / 8; /* 8 bytes per entry */ | 1662 | if (return_code == IO_OK) |
1534 | if (num_luns > CISS_MAX_LUN) { | 1663 | listlength = be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); |
1535 | num_luns = CISS_MAX_LUN; | 1664 | else { /* reading number of logical volumes failed */ |
1536 | printk(KERN_WARNING "cciss: more luns configured" | 1665 | printk(KERN_WARNING "cciss: report logical volume" |
1537 | " on controller than can be handled by" | 1666 | " command failed\n"); |
1538 | " this driver.\n"); | 1667 | listlength = 0; |
1668 | goto freeret; | ||
1669 | } | ||
1670 | |||
1671 | num_luns = listlength / 8; /* 8 bytes per entry */ | ||
1672 | if (num_luns > CISS_MAX_LUN) { | ||
1673 | num_luns = CISS_MAX_LUN; | ||
1674 | printk(KERN_WARNING "cciss: more luns configured" | ||
1675 | " on controller than can be handled by" | ||
1676 | " this driver.\n"); | ||
1677 | } | ||
1678 | |||
1679 | if (num_luns == 0) | ||
1680 | cciss_add_controller_node(h); | ||
1681 | |||
1682 | /* Compare controller drive array to driver's drive array | ||
1683 | * to see if any drives are missing on the controller due | ||
1684 | * to action of Array Config Utility (user deletes drive) | ||
1685 | * and deregister logical drives which have disappeared. | ||
1686 | */ | ||
1687 | for (i = 0; i <= h->highest_lun; i++) { | ||
1688 | int j; | ||
1689 | drv_found = 0; | ||
1690 | for (j = 0; j < num_luns; j++) { | ||
1691 | memcpy(&lunid, &ld_buff->LUN[j][0], 4); | ||
1692 | lunid = le32_to_cpu(lunid); | ||
1693 | if (h->drv[i].LunID == lunid) { | ||
1694 | drv_found = 1; | ||
1695 | break; | ||
1696 | } | ||
1539 | } | 1697 | } |
1698 | if (!drv_found) { | ||
1699 | /* Deregister it from the OS, it's gone. */ | ||
1700 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
1701 | h->drv[i].busy_configuring = 1; | ||
1702 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1703 | return_code = deregister_disk(h->gendisk[i], | ||
1704 | &h->drv[i], 1); | ||
1705 | h->drv[i].busy_configuring = 0; | ||
1706 | } | ||
1707 | } | ||
1708 | |||
1709 | /* Compare controller drive array to driver's drive array. | ||
1710 | * Check for updates in the drive information and any new drives | ||
1711 | * on the controller due to ACU adding logical drives, or changing | ||
1712 | * a logical drive's size, etc. Reregister any new/changed drives | ||
1713 | */ | ||
1714 | for (i = 0; i < num_luns; i++) { | ||
1715 | int j; | ||
1540 | 1716 | ||
1541 | /* Compare controller drive array to drivers drive array. | 1717 | drv_found = 0; |
1542 | * Check for updates in the drive information and any new drives | 1718 | |
1543 | * on the controller. | 1719 | memcpy(&lunid, &ld_buff->LUN[i][0], 4); |
1720 | lunid = le32_to_cpu(lunid); | ||
1721 | |||
1722 | /* Find if the LUN is already in the drive array | ||
1723 | * of the driver. If so then update its info | ||
1724 | * if not in use. If it does not exist then find | ||
1725 | * the first free index and add it. | ||
1544 | */ | 1726 | */ |
1545 | for (i = 0; i < num_luns; i++) { | 1727 | for (j = 0; j <= h->highest_lun; j++) { |
1546 | int j; | 1728 | if (h->drv[j].raid_level != -1 && |
1547 | 1729 | h->drv[j].LunID == lunid) { | |
1548 | drv_found = 0; | 1730 | drv_index = j; |
1549 | 1731 | drv_found = 1; | |
1550 | lunid = (0xff & | 1732 | break; |
1551 | (unsigned int)(ld_buff->LUN[i][3])) << 24; | ||
1552 | lunid |= (0xff & | ||
1553 | (unsigned int)(ld_buff->LUN[i][2])) << 16; | ||
1554 | lunid |= (0xff & | ||
1555 | (unsigned int)(ld_buff->LUN[i][1])) << 8; | ||
1556 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | ||
1557 | |||
1558 | /* Find if the LUN is already in the drive array | ||
1559 | * of the controller. If so then update its info | ||
1560 | * if not is use. If it does not exist then find | ||
1561 | * the first free index and add it. | ||
1562 | */ | ||
1563 | for (j = 0; j <= h->highest_lun; j++) { | ||
1564 | if (h->drv[j].LunID == lunid) { | ||
1565 | drv_index = j; | ||
1566 | drv_found = 1; | ||
1567 | } | ||
1568 | } | 1733 | } |
1734 | } | ||
1569 | 1735 | ||
1570 | /* check if the drive was found already in the array */ | 1736 | /* check if the drive was found already in the array */ |
1571 | if (!drv_found) { | 1737 | if (!drv_found) { |
1572 | drv_index = cciss_find_free_drive_index(ctlr); | 1738 | drv_index = cciss_add_gendisk(h, lunid, 0); |
1573 | if (drv_index == -1) | 1739 | if (drv_index == -1) |
1574 | goto freeret; | 1740 | goto freeret; |
1575 | 1741 | } | |
1576 | /*Check if the gendisk needs to be allocated */ | 1742 | cciss_update_drive_info(ctlr, drv_index, first_time); |
1577 | if (!h->gendisk[drv_index]){ | 1743 | } /* end for */ |
1578 | h->gendisk[drv_index] = alloc_disk(1 << NWD_SHIFT); | ||
1579 | if (!h->gendisk[drv_index]){ | ||
1580 | printk(KERN_ERR "cciss: could not allocate new disk %d\n", drv_index); | ||
1581 | goto mem_msg; | ||
1582 | } | ||
1583 | } | ||
1584 | } | ||
1585 | h->drv[drv_index].LunID = lunid; | ||
1586 | cciss_update_drive_info(ctlr, drv_index); | ||
1587 | } /* end for */ | ||
1588 | } /* end else */ | ||
1589 | 1744 | ||
1590 | freeret: | 1745 | freeret: |
1591 | kfree(ld_buff); | 1746 | kfree(ld_buff); |
1592 | h->busy_configuring = 0; | 1747 | h->busy_configuring = 0; |
1593 | /* We return -1 here to tell the ACU that we have registered/updated | 1748 | /* We return -1 here to tell the ACU that we have registered/updated |
@@ -1595,8 +1750,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1595 | * additional times. | 1750 | * additional times. |
1596 | */ | 1751 | */ |
1597 | return -1; | 1752 | return -1; |
1598 | mem_msg: | 1753 | mem_msg: |
1599 | printk(KERN_ERR "cciss: out of memory\n"); | 1754 | printk(KERN_ERR "cciss: out of memory\n"); |
1755 | h->busy_configuring = 0; | ||
1600 | goto freeret; | 1756 | goto freeret; |
1601 | } | 1757 | } |
1602 | 1758 | ||
@@ -1652,15 +1808,15 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | |||
1652 | * other than disk 0 we will call put_disk. We do not | 1808 | * other than disk 0 we will call put_disk. We do not |
1653 | * do this for disk 0 as we need it to be able to | 1809 | * do this for disk 0 as we need it to be able to |
1654 | * configure the controller. | 1810 | * configure the controller. |
1655 | */ | 1811 | */ |
1656 | if (clear_all){ | 1812 | if (clear_all){ |
1657 | /* This isn't pretty, but we need to find the | 1813 | /* This isn't pretty, but we need to find the |
1658 | * disk in our array and NULL our the pointer. | 1814 | * disk in our array and NULL our the pointer. |
1659 | * This is so that we will call alloc_disk if | 1815 | * This is so that we will call alloc_disk if |
1660 | * this index is used again later. | 1816 | * this index is used again later. |
1661 | */ | 1817 | */ |
1662 | for (i=0; i < CISS_MAX_LUN; i++){ | 1818 | for (i=0; i < CISS_MAX_LUN; i++){ |
1663 | if(h->gendisk[i] == disk){ | 1819 | if (h->gendisk[i] == disk) { |
1664 | h->gendisk[i] = NULL; | 1820 | h->gendisk[i] = NULL; |
1665 | break; | 1821 | break; |
1666 | } | 1822 | } |
@@ -1688,7 +1844,7 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | |||
1688 | if (drv == h->drv + h->highest_lun) { | 1844 | if (drv == h->drv + h->highest_lun) { |
1689 | /* if so, find the new hightest lun */ | 1845 | /* if so, find the new hightest lun */ |
1690 | int i, newhighest = -1; | 1846 | int i, newhighest = -1; |
1691 | for (i = 0; i < h->highest_lun; i++) { | 1847 | for (i = 0; i <= h->highest_lun; i++) { |
1692 | /* if the disk has size > 0, it is available */ | 1848 | /* if the disk has size > 0, it is available */ |
1693 | if (h->drv[i].heads) | 1849 | if (h->drv[i].heads) |
1694 | newhighest = i; | 1850 | newhighest = i; |
@@ -3199,136 +3355,9 @@ err_out_free_res: | |||
3199 | return err; | 3355 | return err; |
3200 | } | 3356 | } |
3201 | 3357 | ||
3202 | /* | 3358 | /* Function to find the first free pointer into our hba[] array |
3203 | * Gets information about the local volumes attached to the controller. | 3359 | * Returns -1 if no free entries are left. |
3204 | */ | 3360 | */ |
3205 | static void cciss_getgeometry(int cntl_num) | ||
3206 | { | ||
3207 | ReportLunData_struct *ld_buff; | ||
3208 | InquiryData_struct *inq_buff; | ||
3209 | int return_code; | ||
3210 | int i; | ||
3211 | int listlength = 0; | ||
3212 | __u32 lunid = 0; | ||
3213 | unsigned block_size; | ||
3214 | sector_t total_size; | ||
3215 | |||
3216 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | ||
3217 | if (ld_buff == NULL) { | ||
3218 | printk(KERN_ERR "cciss: out of memory\n"); | ||
3219 | return; | ||
3220 | } | ||
3221 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
3222 | if (inq_buff == NULL) { | ||
3223 | printk(KERN_ERR "cciss: out of memory\n"); | ||
3224 | kfree(ld_buff); | ||
3225 | return; | ||
3226 | } | ||
3227 | /* Get the firmware version */ | ||
3228 | return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, | ||
3229 | sizeof(InquiryData_struct), 0, 0, 0, NULL, | ||
3230 | TYPE_CMD); | ||
3231 | if (return_code == IO_OK) { | ||
3232 | hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32]; | ||
3233 | hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33]; | ||
3234 | hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34]; | ||
3235 | hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35]; | ||
3236 | } else { /* send command failed */ | ||
3237 | |||
3238 | printk(KERN_WARNING "cciss: unable to determine firmware" | ||
3239 | " version of controller\n"); | ||
3240 | } | ||
3241 | /* Get the number of logical volumes */ | ||
3242 | return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, | ||
3243 | sizeof(ReportLunData_struct), 0, 0, 0, NULL, | ||
3244 | TYPE_CMD); | ||
3245 | |||
3246 | if (return_code == IO_OK) { | ||
3247 | #ifdef CCISS_DEBUG | ||
3248 | printk("LUN Data\n--------------------------\n"); | ||
3249 | #endif /* CCISS_DEBUG */ | ||
3250 | |||
3251 | listlength |= | ||
3252 | (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; | ||
3253 | listlength |= | ||
3254 | (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; | ||
3255 | listlength |= | ||
3256 | (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; | ||
3257 | listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); | ||
3258 | } else { /* reading number of logical volumes failed */ | ||
3259 | |||
3260 | printk(KERN_WARNING "cciss: report logical volume" | ||
3261 | " command failed\n"); | ||
3262 | listlength = 0; | ||
3263 | } | ||
3264 | hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry | ||
3265 | if (hba[cntl_num]->num_luns > CISS_MAX_LUN) { | ||
3266 | printk(KERN_ERR | ||
3267 | "ciss: only %d number of logical volumes supported\n", | ||
3268 | CISS_MAX_LUN); | ||
3269 | hba[cntl_num]->num_luns = CISS_MAX_LUN; | ||
3270 | } | ||
3271 | #ifdef CCISS_DEBUG | ||
3272 | printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", | ||
3273 | ld_buff->LUNListLength[0], ld_buff->LUNListLength[1], | ||
3274 | ld_buff->LUNListLength[2], ld_buff->LUNListLength[3], | ||
3275 | hba[cntl_num]->num_luns); | ||
3276 | #endif /* CCISS_DEBUG */ | ||
3277 | |||
3278 | hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1; | ||
3279 | for (i = 0; i < CISS_MAX_LUN; i++) { | ||
3280 | if (i < hba[cntl_num]->num_luns) { | ||
3281 | lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) | ||
3282 | << 24; | ||
3283 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) | ||
3284 | << 16; | ||
3285 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) | ||
3286 | << 8; | ||
3287 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | ||
3288 | |||
3289 | hba[cntl_num]->drv[i].LunID = lunid; | ||
3290 | |||
3291 | #ifdef CCISS_DEBUG | ||
3292 | printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i, | ||
3293 | ld_buff->LUN[i][0], ld_buff->LUN[i][1], | ||
3294 | ld_buff->LUN[i][2], ld_buff->LUN[i][3], | ||
3295 | hba[cntl_num]->drv[i].LunID); | ||
3296 | #endif /* CCISS_DEBUG */ | ||
3297 | |||
3298 | /* testing to see if 16-byte CDBs are already being used */ | ||
3299 | if(hba[cntl_num]->cciss_read == CCISS_READ_16) { | ||
3300 | cciss_read_capacity_16(cntl_num, i, 0, | ||
3301 | &total_size, &block_size); | ||
3302 | goto geo_inq; | ||
3303 | } | ||
3304 | cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size); | ||
3305 | |||
3306 | /* If read_capacity returns all F's the logical is >2TB */ | ||
3307 | /* so we switch to 16-byte CDBs for all read/write ops */ | ||
3308 | if(total_size == 0xFFFFFFFFULL) { | ||
3309 | cciss_read_capacity_16(cntl_num, i, 0, | ||
3310 | &total_size, &block_size); | ||
3311 | hba[cntl_num]->cciss_read = CCISS_READ_16; | ||
3312 | hba[cntl_num]->cciss_write = CCISS_WRITE_16; | ||
3313 | } else { | ||
3314 | hba[cntl_num]->cciss_read = CCISS_READ_10; | ||
3315 | hba[cntl_num]->cciss_write = CCISS_WRITE_10; | ||
3316 | } | ||
3317 | geo_inq: | ||
3318 | cciss_geometry_inquiry(cntl_num, i, 0, total_size, | ||
3319 | block_size, inq_buff, | ||
3320 | &hba[cntl_num]->drv[i]); | ||
3321 | } else { | ||
3322 | /* initialize raid_level to indicate a free space */ | ||
3323 | hba[cntl_num]->drv[i].raid_level = -1; | ||
3324 | } | ||
3325 | } | ||
3326 | kfree(ld_buff); | ||
3327 | kfree(inq_buff); | ||
3328 | } | ||
3329 | |||
3330 | /* Function to find the first free pointer into our hba[] array */ | ||
3331 | /* Returns -1 if no free entries are left. */ | ||
3332 | static int alloc_cciss_hba(void) | 3361 | static int alloc_cciss_hba(void) |
3333 | { | 3362 | { |
3334 | int i; | 3363 | int i; |
@@ -3340,11 +3369,6 @@ static int alloc_cciss_hba(void) | |||
3340 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); | 3369 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); |
3341 | if (!p) | 3370 | if (!p) |
3342 | goto Enomem; | 3371 | goto Enomem; |
3343 | p->gendisk[0] = alloc_disk(1 << NWD_SHIFT); | ||
3344 | if (!p->gendisk[0]) { | ||
3345 | kfree(p); | ||
3346 | goto Enomem; | ||
3347 | } | ||
3348 | hba[i] = p; | 3372 | hba[i] = p; |
3349 | return i; | 3373 | return i; |
3350 | } | 3374 | } |
@@ -3472,11 +3496,13 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3472 | ((hba[i]->nr_cmds + BITS_PER_LONG - | 3496 | ((hba[i]->nr_cmds + BITS_PER_LONG - |
3473 | 1) / BITS_PER_LONG) * sizeof(unsigned long)); | 3497 | 1) / BITS_PER_LONG) * sizeof(unsigned long)); |
3474 | 3498 | ||
3475 | #ifdef CCISS_DEBUG | 3499 | hba[i]->num_luns = 0; |
3476 | printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n", i); | 3500 | hba[i]->highest_lun = -1; |
3477 | #endif /* CCISS_DEBUG */ | 3501 | for (j = 0; j < CISS_MAX_LUN; j++) { |
3478 | 3502 | hba[i]->drv[j].raid_level = -1; | |
3479 | cciss_getgeometry(i); | 3503 | hba[i]->drv[j].queue = NULL; |
3504 | hba[i]->gendisk[j] = NULL; | ||
3505 | } | ||
3480 | 3506 | ||
3481 | cciss_scsi_setup(i); | 3507 | cciss_scsi_setup(i); |
3482 | 3508 | ||
@@ -3489,76 +3515,10 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3489 | 3515 | ||
3490 | hba[i]->busy_initializing = 0; | 3516 | hba[i]->busy_initializing = 0; |
3491 | 3517 | ||
3492 | do { | 3518 | rebuild_lun_table(hba[i], 1); |
3493 | drive_info_struct *drv = &(hba[i]->drv[j]); | ||
3494 | struct gendisk *disk = hba[i]->gendisk[j]; | ||
3495 | struct request_queue *q; | ||
3496 | |||
3497 | /* Check if the disk was allocated already */ | ||
3498 | if (!disk){ | ||
3499 | hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT); | ||
3500 | disk = hba[i]->gendisk[j]; | ||
3501 | } | ||
3502 | |||
3503 | /* Check that the disk was able to be allocated */ | ||
3504 | if (!disk) { | ||
3505 | printk(KERN_ERR "cciss: unable to allocate memory for disk %d\n", j); | ||
3506 | goto clean4; | ||
3507 | } | ||
3508 | |||
3509 | q = blk_init_queue(do_cciss_request, &hba[i]->lock); | ||
3510 | if (!q) { | ||
3511 | printk(KERN_ERR | ||
3512 | "cciss: unable to allocate queue for disk %d\n", | ||
3513 | j); | ||
3514 | goto clean4; | ||
3515 | } | ||
3516 | drv->queue = q; | ||
3517 | |||
3518 | blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); | ||
3519 | |||
3520 | /* This is a hardware imposed limit. */ | ||
3521 | blk_queue_max_hw_segments(q, MAXSGENTRIES); | ||
3522 | |||
3523 | /* This is a limit in the driver and could be eliminated. */ | ||
3524 | blk_queue_max_phys_segments(q, MAXSGENTRIES); | ||
3525 | |||
3526 | blk_queue_max_sectors(q, hba[i]->cciss_max_sectors); | ||
3527 | |||
3528 | blk_queue_softirq_done(q, cciss_softirq_done); | ||
3529 | |||
3530 | q->queuedata = hba[i]; | ||
3531 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); | ||
3532 | disk->major = hba[i]->major; | ||
3533 | disk->first_minor = j << NWD_SHIFT; | ||
3534 | disk->fops = &cciss_fops; | ||
3535 | disk->queue = q; | ||
3536 | disk->private_data = drv; | ||
3537 | disk->driverfs_dev = &pdev->dev; | ||
3538 | /* we must register the controller even if no disks exist */ | ||
3539 | /* this is for the online array utilities */ | ||
3540 | if (!drv->heads && j) | ||
3541 | continue; | ||
3542 | blk_queue_hardsect_size(q, drv->block_size); | ||
3543 | set_capacity(disk, drv->nr_blocks); | ||
3544 | j++; | ||
3545 | } while (j <= hba[i]->highest_lun); | ||
3546 | |||
3547 | /* Make sure all queue data is written out before */ | ||
3548 | /* interrupt handler, triggered by add_disk, */ | ||
3549 | /* is allowed to start them. */ | ||
3550 | wmb(); | ||
3551 | |||
3552 | for (j = 0; j <= hba[i]->highest_lun; j++) | ||
3553 | add_disk(hba[i]->gendisk[j]); | ||
3554 | |||
3555 | /* we must register the controller even if no disks exist */ | ||
3556 | if (hba[i]->highest_lun == -1) | ||
3557 | add_disk(hba[i]->gendisk[0]); | ||
3558 | |||
3559 | return 1; | 3519 | return 1; |
3560 | 3520 | ||
3561 | clean4: | 3521 | clean4: |
3562 | #ifdef CONFIG_CISS_SCSI_TAPE | 3522 | #ifdef CONFIG_CISS_SCSI_TAPE |
3563 | kfree(hba[i]->scsi_rejects.complete); | 3523 | kfree(hba[i]->scsi_rejects.complete); |
3564 | #endif | 3524 | #endif |
@@ -3573,9 +3533,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3573 | hba[i]->errinfo_pool, | 3533 | hba[i]->errinfo_pool, |
3574 | hba[i]->errinfo_pool_dhandle); | 3534 | hba[i]->errinfo_pool_dhandle); |
3575 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); | 3535 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); |
3576 | clean2: | 3536 | clean2: |
3577 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 3537 | unregister_blkdev(hba[i]->major, hba[i]->devname); |
3578 | clean1: | 3538 | clean1: |
3579 | hba[i]->busy_initializing = 0; | 3539 | hba[i]->busy_initializing = 0; |
3580 | /* cleanup any queues that may have been initialized */ | 3540 | /* cleanup any queues that may have been initialized */ |
3581 | for (j=0; j <= hba[i]->highest_lun; j++){ | 3541 | for (j=0; j <= hba[i]->highest_lun; j++){ |
@@ -3654,7 +3614,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
3654 | } | 3614 | } |
3655 | } | 3615 | } |
3656 | 3616 | ||
3617 | #ifdef CONFIG_CISS_SCSI_TAPE | ||
3657 | cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ | 3618 | cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ |
3619 | #endif | ||
3658 | 3620 | ||
3659 | cciss_shutdown(pdev); | 3621 | cciss_shutdown(pdev); |
3660 | 3622 | ||
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index b70988dd33ec..24a7efa993ab 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -39,6 +39,8 @@ typedef struct _drive_info_struct | |||
39 | *to prevent it from being opened or it's queue | 39 | *to prevent it from being opened or it's queue |
40 | *from being started. | 40 | *from being started. |
41 | */ | 41 | */ |
42 | __u8 serial_no[16]; /* from inquiry page 0x83, */ | ||
43 | /* not necc. null terminated. */ | ||
42 | } drive_info_struct; | 44 | } drive_info_struct; |
43 | 45 | ||
44 | #ifdef CONFIG_CISS_SCSI_TAPE | 46 | #ifdef CONFIG_CISS_SCSI_TAPE |
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index e4bf9a11ca0d..e1233aabda77 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
@@ -358,23 +358,68 @@ find_bus_target_lun(int ctlr, int *bus, int *target, int *lun) | |||
358 | } | 358 | } |
359 | return (!found); | 359 | return (!found); |
360 | } | 360 | } |
361 | struct scsi2map { | ||
362 | char scsi3addr[8]; | ||
363 | int bus, target, lun; | ||
364 | }; | ||
361 | 365 | ||
362 | static int | 366 | static int |
363 | cciss_scsi_add_entry(int ctlr, int hostno, | 367 | cciss_scsi_add_entry(int ctlr, int hostno, |
364 | unsigned char *scsi3addr, int devtype) | 368 | unsigned char *scsi3addr, int devtype, |
369 | struct scsi2map *added, int *nadded) | ||
365 | { | 370 | { |
366 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ | 371 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ |
367 | int n = ccissscsi[ctlr].ndevices; | 372 | int n = ccissscsi[ctlr].ndevices; |
368 | struct cciss_scsi_dev_t *sd; | 373 | struct cciss_scsi_dev_t *sd; |
374 | int i, bus, target, lun; | ||
375 | unsigned char addr1[8], addr2[8]; | ||
369 | 376 | ||
370 | if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { | 377 | if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { |
371 | printk("cciss%d: Too many devices, " | 378 | printk("cciss%d: Too many devices, " |
372 | "some will be inaccessible.\n", ctlr); | 379 | "some will be inaccessible.\n", ctlr); |
373 | return -1; | 380 | return -1; |
374 | } | 381 | } |
382 | |||
383 | bus = target = -1; | ||
384 | lun = 0; | ||
385 | /* Is this device a non-zero lun of a multi-lun device */ | ||
386 | /* byte 4 of the 8-byte LUN addr will contain the logical unit no. */ | ||
387 | if (scsi3addr[4] != 0) { | ||
388 | /* Search through our list and find the device which */ | ||
389 | /* has the same 8 byte LUN address, excepting byte 4. */ | ||
390 | /* Assign the same bus and target for this new LUN. */ | ||
391 | /* Use the logical unit number from the firmware. */ | ||
392 | memcpy(addr1, scsi3addr, 8); | ||
393 | addr1[4] = 0; | ||
394 | for (i = 0; i < n; i++) { | ||
395 | sd = &ccissscsi[ctlr].dev[i]; | ||
396 | memcpy(addr2, sd->scsi3addr, 8); | ||
397 | addr2[4] = 0; | ||
398 | /* differ only in byte 4? */ | ||
399 | if (memcmp(addr1, addr2, 8) == 0) { | ||
400 | bus = sd->bus; | ||
401 | target = sd->target; | ||
402 | lun = scsi3addr[4]; | ||
403 | break; | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | |||
375 | sd = &ccissscsi[ctlr].dev[n]; | 408 | sd = &ccissscsi[ctlr].dev[n]; |
376 | if (find_bus_target_lun(ctlr, &sd->bus, &sd->target, &sd->lun) != 0) | 409 | if (lun == 0) { |
377 | return -1; | 410 | if (find_bus_target_lun(ctlr, |
411 | &sd->bus, &sd->target, &sd->lun) != 0) | ||
412 | return -1; | ||
413 | } else { | ||
414 | sd->bus = bus; | ||
415 | sd->target = target; | ||
416 | sd->lun = lun; | ||
417 | } | ||
418 | added[*nadded].bus = sd->bus; | ||
419 | added[*nadded].target = sd->target; | ||
420 | added[*nadded].lun = sd->lun; | ||
421 | (*nadded)++; | ||
422 | |||
378 | memcpy(&sd->scsi3addr[0], scsi3addr, 8); | 423 | memcpy(&sd->scsi3addr[0], scsi3addr, 8); |
379 | sd->devtype = devtype; | 424 | sd->devtype = devtype; |
380 | ccissscsi[ctlr].ndevices++; | 425 | ccissscsi[ctlr].ndevices++; |
@@ -390,7 +435,8 @@ cciss_scsi_add_entry(int ctlr, int hostno, | |||
390 | } | 435 | } |
391 | 436 | ||
392 | static void | 437 | static void |
393 | cciss_scsi_remove_entry(int ctlr, int hostno, int entry) | 438 | cciss_scsi_remove_entry(int ctlr, int hostno, int entry, |
439 | struct scsi2map *removed, int *nremoved) | ||
394 | { | 440 | { |
395 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ | 441 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ |
396 | int i; | 442 | int i; |
@@ -398,6 +444,10 @@ cciss_scsi_remove_entry(int ctlr, int hostno, int entry) | |||
398 | 444 | ||
399 | if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return; | 445 | if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return; |
400 | sd = ccissscsi[ctlr].dev[entry]; | 446 | sd = ccissscsi[ctlr].dev[entry]; |
447 | removed[*nremoved].bus = sd.bus; | ||
448 | removed[*nremoved].target = sd.target; | ||
449 | removed[*nremoved].lun = sd.lun; | ||
450 | (*nremoved)++; | ||
401 | for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++) | 451 | for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++) |
402 | ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1]; | 452 | ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1]; |
403 | ccissscsi[ctlr].ndevices--; | 453 | ccissscsi[ctlr].ndevices--; |
@@ -417,6 +467,26 @@ cciss_scsi_remove_entry(int ctlr, int hostno, int entry) | |||
417 | (a)[1] == (b)[1] && \ | 467 | (a)[1] == (b)[1] && \ |
418 | (a)[0] == (b)[0]) | 468 | (a)[0] == (b)[0]) |
419 | 469 | ||
470 | static void fixup_botched_add(int ctlr, char *scsi3addr) | ||
471 | { | ||
472 | /* called when scsi_add_device fails in order to re-adjust */ | ||
473 | /* ccissscsi[] to match the mid layer's view. */ | ||
474 | unsigned long flags; | ||
475 | int i, j; | ||
476 | CPQ_TAPE_LOCK(ctlr, flags); | ||
477 | for (i = 0; i < ccissscsi[ctlr].ndevices; i++) { | ||
478 | if (memcmp(scsi3addr, | ||
479 | ccissscsi[ctlr].dev[i].scsi3addr, 8) == 0) { | ||
480 | for (j = i; j < ccissscsi[ctlr].ndevices-1; j++) | ||
481 | ccissscsi[ctlr].dev[j] = | ||
482 | ccissscsi[ctlr].dev[j+1]; | ||
483 | ccissscsi[ctlr].ndevices--; | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | CPQ_TAPE_UNLOCK(ctlr, flags); | ||
488 | } | ||
489 | |||
420 | static int | 490 | static int |
421 | adjust_cciss_scsi_table(int ctlr, int hostno, | 491 | adjust_cciss_scsi_table(int ctlr, int hostno, |
422 | struct cciss_scsi_dev_t sd[], int nsds) | 492 | struct cciss_scsi_dev_t sd[], int nsds) |
@@ -429,13 +499,33 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
429 | int i,j, found, changes=0; | 499 | int i,j, found, changes=0; |
430 | struct cciss_scsi_dev_t *csd; | 500 | struct cciss_scsi_dev_t *csd; |
431 | unsigned long flags; | 501 | unsigned long flags; |
502 | struct scsi2map *added, *removed; | ||
503 | int nadded, nremoved; | ||
504 | struct Scsi_Host *sh = NULL; | ||
505 | |||
506 | added = kzalloc(sizeof(*added) * CCISS_MAX_SCSI_DEVS_PER_HBA, | ||
507 | GFP_KERNEL); | ||
508 | removed = kzalloc(sizeof(*removed) * CCISS_MAX_SCSI_DEVS_PER_HBA, | ||
509 | GFP_KERNEL); | ||
510 | |||
511 | if (!added || !removed) { | ||
512 | printk(KERN_WARNING "cciss%d: Out of memory in " | ||
513 | "adjust_cciss_scsi_table\n", ctlr); | ||
514 | goto free_and_out; | ||
515 | } | ||
432 | 516 | ||
433 | CPQ_TAPE_LOCK(ctlr, flags); | 517 | CPQ_TAPE_LOCK(ctlr, flags); |
434 | 518 | ||
519 | if (hostno != -1) /* if it's not the first time... */ | ||
520 | sh = ((struct cciss_scsi_adapter_data_t *) | ||
521 | hba[ctlr]->scsi_ctlr)->scsi_host; | ||
522 | |||
435 | /* find any devices in ccissscsi[] that are not in | 523 | /* find any devices in ccissscsi[] that are not in |
436 | sd[] and remove them from ccissscsi[] */ | 524 | sd[] and remove them from ccissscsi[] */ |
437 | 525 | ||
438 | i = 0; | 526 | i = 0; |
527 | nremoved = 0; | ||
528 | nadded = 0; | ||
439 | while(i<ccissscsi[ctlr].ndevices) { | 529 | while(i<ccissscsi[ctlr].ndevices) { |
440 | csd = &ccissscsi[ctlr].dev[i]; | 530 | csd = &ccissscsi[ctlr].dev[i]; |
441 | found=0; | 531 | found=0; |
@@ -455,8 +545,9 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
455 | /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n", | 545 | /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n", |
456 | ctlr, scsi_device_type(csd->devtype), hostno, | 546 | ctlr, scsi_device_type(csd->devtype), hostno, |
457 | csd->bus, csd->target, csd->lun); */ | 547 | csd->bus, csd->target, csd->lun); */ |
458 | cciss_scsi_remove_entry(ctlr, hostno, i); | 548 | cciss_scsi_remove_entry(ctlr, hostno, i, |
459 | /* note, i not incremented */ | 549 | removed, &nremoved); |
550 | /* remove ^^^, hence i not incremented */ | ||
460 | } | 551 | } |
461 | else if (found == 1) { /* device is different kind */ | 552 | else if (found == 1) { /* device is different kind */ |
462 | changes++; | 553 | changes++; |
@@ -464,8 +555,15 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
464 | "(device type now %s).\n", | 555 | "(device type now %s).\n", |
465 | ctlr, hostno, csd->bus, csd->target, csd->lun, | 556 | ctlr, hostno, csd->bus, csd->target, csd->lun, |
466 | scsi_device_type(csd->devtype)); | 557 | scsi_device_type(csd->devtype)); |
558 | cciss_scsi_remove_entry(ctlr, hostno, i, | ||
559 | removed, &nremoved); | ||
560 | /* remove ^^^, hence i not incremented */ | ||
561 | if (cciss_scsi_add_entry(ctlr, hostno, | ||
562 | &sd[j].scsi3addr[0], sd[j].devtype, | ||
563 | added, &nadded) != 0) | ||
564 | /* we just removed one, so add can't fail. */ | ||
565 | BUG(); | ||
467 | csd->devtype = sd[j].devtype; | 566 | csd->devtype = sd[j].devtype; |
468 | i++; /* so just move along. */ | ||
469 | } else /* device is same as it ever was, */ | 567 | } else /* device is same as it ever was, */ |
470 | i++; /* so just move along. */ | 568 | i++; /* so just move along. */ |
471 | } | 569 | } |
@@ -489,7 +587,9 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
489 | if (!found) { | 587 | if (!found) { |
490 | changes++; | 588 | changes++; |
491 | if (cciss_scsi_add_entry(ctlr, hostno, | 589 | if (cciss_scsi_add_entry(ctlr, hostno, |
492 | &sd[i].scsi3addr[0], sd[i].devtype) != 0) | 590 | |
591 | &sd[i].scsi3addr[0], sd[i].devtype, | ||
592 | added, &nadded) != 0) | ||
493 | break; | 593 | break; |
494 | } else if (found == 1) { | 594 | } else if (found == 1) { |
495 | /* should never happen... */ | 595 | /* should never happen... */ |
@@ -501,9 +601,50 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
501 | } | 601 | } |
502 | CPQ_TAPE_UNLOCK(ctlr, flags); | 602 | CPQ_TAPE_UNLOCK(ctlr, flags); |
503 | 603 | ||
504 | if (!changes) | 604 | /* Don't notify scsi mid layer of any changes the first time through */ |
505 | printk("cciss%d: No device changes detected.\n", ctlr); | 605 | /* (or if there are no changes) scsi_scan_host will do it later the */ |
606 | /* first time through. */ | ||
607 | if (hostno == -1 || !changes) | ||
608 | goto free_and_out; | ||
609 | |||
610 | /* Notify scsi mid layer of any removed devices */ | ||
611 | for (i = 0; i < nremoved; i++) { | ||
612 | struct scsi_device *sdev = | ||
613 | scsi_device_lookup(sh, removed[i].bus, | ||
614 | removed[i].target, removed[i].lun); | ||
615 | if (sdev != NULL) { | ||
616 | scsi_remove_device(sdev); | ||
617 | scsi_device_put(sdev); | ||
618 | } else { | ||
619 | /* We don't expect to get here. */ | ||
620 | /* future cmds to this device will get selection */ | ||
621 | /* timeout as if the device was gone. */ | ||
622 | printk(KERN_WARNING "cciss%d: didn't find " | ||
623 | "c%db%dt%dl%d\n for removal.", | ||
624 | ctlr, hostno, removed[i].bus, | ||
625 | removed[i].target, removed[i].lun); | ||
626 | } | ||
627 | } | ||
628 | |||
629 | /* Notify scsi mid layer of any added devices */ | ||
630 | for (i = 0; i < nadded; i++) { | ||
631 | int rc; | ||
632 | rc = scsi_add_device(sh, added[i].bus, | ||
633 | added[i].target, added[i].lun); | ||
634 | if (rc == 0) | ||
635 | continue; | ||
636 | printk(KERN_WARNING "cciss%d: scsi_add_device " | ||
637 | "c%db%dt%dl%d failed, device not added.\n", | ||
638 | ctlr, hostno, | ||
639 | added[i].bus, added[i].target, added[i].lun); | ||
640 | /* now we have to remove it from ccissscsi, */ | ||
641 | /* since it didn't get added to scsi mid layer */ | ||
642 | fixup_botched_add(ctlr, added[i].scsi3addr); | ||
643 | } | ||
506 | 644 | ||
645 | free_and_out: | ||
646 | kfree(added); | ||
647 | kfree(removed); | ||
507 | return 0; | 648 | return 0; |
508 | } | 649 | } |
509 | 650 | ||
@@ -1355,32 +1496,6 @@ cciss_unregister_scsi(int ctlr) | |||
1355 | } | 1496 | } |
1356 | 1497 | ||
1357 | static int | 1498 | static int |
1358 | cciss_register_scsi(int ctlr) | ||
1359 | { | ||
1360 | unsigned long flags; | ||
1361 | |||
1362 | CPQ_TAPE_LOCK(ctlr, flags); | ||
1363 | |||
1364 | /* Since this is really a block driver, the SCSI core may not be | ||
1365 | initialized at init time, in which case, calling scsi_register_host | ||
1366 | would hang. Instead, we do it later, via /proc filesystem | ||
1367 | and rc scripts, when we know SCSI core is good to go. */ | ||
1368 | |||
1369 | /* Only register if SCSI devices are detected. */ | ||
1370 | if (ccissscsi[ctlr].ndevices != 0) { | ||
1371 | ((struct cciss_scsi_adapter_data_t *) | ||
1372 | hba[ctlr]->scsi_ctlr)->registered = 1; | ||
1373 | CPQ_TAPE_UNLOCK(ctlr, flags); | ||
1374 | return cciss_scsi_detect(ctlr); | ||
1375 | } | ||
1376 | CPQ_TAPE_UNLOCK(ctlr, flags); | ||
1377 | printk(KERN_INFO | ||
1378 | "cciss%d: No appropriate SCSI device detected, " | ||
1379 | "SCSI subsystem not engaged.\n", ctlr); | ||
1380 | return 0; | ||
1381 | } | ||
1382 | |||
1383 | static int | ||
1384 | cciss_engage_scsi(int ctlr) | 1499 | cciss_engage_scsi(int ctlr) |
1385 | { | 1500 | { |
1386 | struct cciss_scsi_adapter_data_t *sa; | 1501 | struct cciss_scsi_adapter_data_t *sa; |
@@ -1391,15 +1506,15 @@ cciss_engage_scsi(int ctlr) | |||
1391 | sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr; | 1506 | sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr; |
1392 | stk = &sa->cmd_stack; | 1507 | stk = &sa->cmd_stack; |
1393 | 1508 | ||
1394 | if (((struct cciss_scsi_adapter_data_t *) | 1509 | if (sa->registered) { |
1395 | hba[ctlr]->scsi_ctlr)->registered) { | ||
1396 | printk("cciss%d: SCSI subsystem already engaged.\n", ctlr); | 1510 | printk("cciss%d: SCSI subsystem already engaged.\n", ctlr); |
1397 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1511 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); |
1398 | return ENXIO; | 1512 | return ENXIO; |
1399 | } | 1513 | } |
1514 | sa->registered = 1; | ||
1400 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1515 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); |
1401 | cciss_update_non_disk_devices(ctlr, -1); | 1516 | cciss_update_non_disk_devices(ctlr, -1); |
1402 | cciss_register_scsi(ctlr); | 1517 | cciss_scsi_detect(ctlr); |
1403 | return 0; | 1518 | return 0; |
1404 | } | 1519 | } |
1405 | 1520 | ||
@@ -1493,7 +1608,5 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd) | |||
1493 | /* If no tape support, then these become defined out of existence */ | 1608 | /* If no tape support, then these become defined out of existence */ |
1494 | 1609 | ||
1495 | #define cciss_scsi_setup(cntl_num) | 1610 | #define cciss_scsi_setup(cntl_num) |
1496 | #define cciss_unregister_scsi(ctlr) | ||
1497 | #define cciss_register_scsi(ctlr) | ||
1498 | 1611 | ||
1499 | #endif /* CONFIG_CISS_SCSI_TAPE */ | 1612 | #endif /* CONFIG_CISS_SCSI_TAPE */ |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 9ae05c584234..3ca643cafccd 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -154,8 +154,8 @@ static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) | |||
154 | return 0; | 154 | return 0; |
155 | } | 155 | } |
156 | 156 | ||
157 | int blkif_ioctl(struct inode *inode, struct file *filep, | 157 | static int blkif_ioctl(struct inode *inode, struct file *filep, |
158 | unsigned command, unsigned long argument) | 158 | unsigned command, unsigned long argument) |
159 | { | 159 | { |
160 | struct blkfront_info *info = | 160 | struct blkfront_info *info = |
161 | inode->i_bdev->bd_disk->private_data; | 161 | inode->i_bdev->bd_disk->private_data; |
@@ -77,11 +77,8 @@ struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct | |||
77 | */ | 77 | */ |
78 | 78 | ||
79 | bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask); | 79 | bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask); |
80 | if (bvl) { | 80 | if (bvl) |
81 | struct biovec_slab *bp = bvec_slabs + *idx; | 81 | memset(bvl, 0, bvec_nr_vecs(*idx) * sizeof(struct bio_vec)); |
82 | |||
83 | memset(bvl, 0, bp->nr_vecs * sizeof(struct bio_vec)); | ||
84 | } | ||
85 | 82 | ||
86 | return bvl; | 83 | return bvl; |
87 | } | 84 | } |
@@ -149,7 +146,7 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs) | |||
149 | goto out; | 146 | goto out; |
150 | } | 147 | } |
151 | bio->bi_flags |= idx << BIO_POOL_OFFSET; | 148 | bio->bi_flags |= idx << BIO_POOL_OFFSET; |
152 | bio->bi_max_vecs = bvec_slabs[idx].nr_vecs; | 149 | bio->bi_max_vecs = bvec_nr_vecs(idx); |
153 | } | 150 | } |
154 | bio->bi_io_vec = bvl; | 151 | bio->bi_io_vec = bvl; |
155 | } | 152 | } |