diff options
| -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 | } |
