diff options
Diffstat (limited to 'drivers/block/cciss.c')
-rw-r--r-- | drivers/block/cciss.c | 750 |
1 files changed, 355 insertions, 395 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index d81632cd7d06..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 { |
@@ -1292,8 +1287,6 @@ static void cciss_check_queues(ctlr_info_t *h) | |||
1292 | h->next_to_run = curr_queue; | 1287 | h->next_to_run = curr_queue; |
1293 | break; | 1288 | break; |
1294 | } | 1289 | } |
1295 | } else { | ||
1296 | curr_queue = (curr_queue + 1) % (h->highest_lun + 1); | ||
1297 | } | 1290 | } |
1298 | } | 1291 | } |
1299 | } | 1292 | } |
@@ -1332,15 +1325,84 @@ static void cciss_softirq_done(struct request *rq) | |||
1332 | spin_unlock_irqrestore(&h->lock, flags); | 1325 | spin_unlock_irqrestore(&h->lock, flags); |
1333 | } | 1326 | } |
1334 | 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 | |||
1335 | /* 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. |
1336 | * 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, |
1337 | * 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, |
1338 | * 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 |
1339 | * 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, |
1340 | * 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 |
1341 | * 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. | ||
1342 | */ | 1404 | */ |
1343 | 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) |
1344 | { | 1406 | { |
1345 | ctlr_info_t *h = hba[ctlr]; | 1407 | ctlr_info_t *h = hba[ctlr]; |
1346 | struct gendisk *disk; | 1408 | struct gendisk *disk; |
@@ -1349,16 +1411,81 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
1349 | sector_t total_size; | 1411 | sector_t total_size; |
1350 | unsigned long flags = 0; | 1412 | unsigned long flags = 0; |
1351 | 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); | ||
1352 | 1429 | ||
1353 | /* if the disk already exists then deregister it before proceeding */ | 1430 | /* testing to see if 16-byte CDBs are already being used */ |
1354 | 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); | ||
1355 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1481 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
1356 | h->drv[drv_index].busy_configuring = 1; | 1482 | h->drv[drv_index].busy_configuring = 1; |
1357 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1483 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
1358 | 1484 | ||
1359 | /* deregister_disk sets h->drv[drv_index].queue = NULL */ | 1485 | /* deregister_disk sets h->drv[drv_index].queue = NULL |
1360 | /* which keeps the interrupt handler from starting */ | 1486 | * which keeps the interrupt handler from starting |
1361 | /* the queue. */ | 1487 | * the queue. |
1488 | */ | ||
1362 | ret = deregister_disk(h->gendisk[drv_index], | 1489 | ret = deregister_disk(h->gendisk[drv_index], |
1363 | &h->drv[drv_index], 0); | 1490 | &h->drv[drv_index], 0); |
1364 | h->drv[drv_index].busy_configuring = 0; | 1491 | h->drv[drv_index].busy_configuring = 0; |
@@ -1366,81 +1493,37 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
1366 | 1493 | ||
1367 | /* If the disk is in use return */ | 1494 | /* If the disk is in use return */ |
1368 | if (ret) | 1495 | if (ret) |
1369 | return; | 1496 | goto freeret; |
1370 | 1497 | ||
1371 | /* Get information about the disk and modify the driver structure */ | 1498 | /* Save the new information from cciss_geometry_inquiry |
1372 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | 1499 | * and serial number inquiry. |
1373 | if (inq_buff == NULL) | 1500 | */ |
1374 | goto mem_msg; | 1501 | h->drv[drv_index].block_size = drvinfo->block_size; |
1375 | 1502 | h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; | |
1376 | /* testing to see if 16-byte CDBs are already being used */ | 1503 | h->drv[drv_index].heads = drvinfo->heads; |
1377 | if (h->cciss_read == CCISS_READ_16) { | 1504 | h->drv[drv_index].sectors = drvinfo->sectors; |
1378 | cciss_read_capacity_16(h->ctlr, drv_index, 1, | 1505 | h->drv[drv_index].cylinders = drvinfo->cylinders; |
1379 | &total_size, &block_size); | 1506 | h->drv[drv_index].raid_level = drvinfo->raid_level; |
1380 | goto geo_inq; | 1507 | memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16); |
1381 | } | ||
1382 | |||
1383 | cciss_read_capacity(ctlr, drv_index, 1, | ||
1384 | &total_size, &block_size); | ||
1385 | |||
1386 | /* if read_capacity returns all F's this volume is >2TB in size */ | ||
1387 | /* so we switch to 16-byte CDB's for all read/write ops */ | ||
1388 | if (total_size == 0xFFFFFFFFULL) { | ||
1389 | cciss_read_capacity_16(ctlr, drv_index, 1, | ||
1390 | &total_size, &block_size); | ||
1391 | h->cciss_read = CCISS_READ_16; | ||
1392 | h->cciss_write = CCISS_WRITE_16; | ||
1393 | } else { | ||
1394 | h->cciss_read = CCISS_READ_10; | ||
1395 | h->cciss_write = CCISS_WRITE_10; | ||
1396 | } | ||
1397 | geo_inq: | ||
1398 | cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, | ||
1399 | inq_buff, &h->drv[drv_index]); | ||
1400 | 1508 | ||
1401 | ++h->num_luns; | 1509 | ++h->num_luns; |
1402 | disk = h->gendisk[drv_index]; | 1510 | disk = h->gendisk[drv_index]; |
1403 | set_capacity(disk, h->drv[drv_index].nr_blocks); | 1511 | set_capacity(disk, h->drv[drv_index].nr_blocks); |
1404 | 1512 | ||
1405 | /* if it's the controller it's already added */ | 1513 | /* If it's not disk 0 (drv_index != 0) |
1406 | if (drv_index) { | 1514 | * or if it was disk 0, but there was previously |
1407 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | 1515 | * no actual corresponding configured logical drive |
1408 | sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index); | 1516 | * (raid_leve == -1) then we want to update the |
1409 | disk->major = h->major; | 1517 | * logical drive's information. |
1410 | disk->first_minor = drv_index << NWD_SHIFT; | 1518 | */ |
1411 | disk->fops = &cciss_fops; | 1519 | if (drv_index || first_time) |
1412 | disk->private_data = &h->drv[drv_index]; | 1520 | cciss_add_disk(h, disk, drv_index); |
1413 | |||
1414 | /* Set up queue information */ | ||
1415 | blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask); | ||
1416 | |||
1417 | /* This is a hardware imposed limit. */ | ||
1418 | blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES); | ||
1419 | |||
1420 | /* This is a limit in the driver and could be eliminated. */ | ||
1421 | blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); | ||
1422 | |||
1423 | blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); | ||
1424 | |||
1425 | blk_queue_softirq_done(disk->queue, cciss_softirq_done); | ||
1426 | |||
1427 | disk->queue->queuedata = hba[ctlr]; | ||
1428 | |||
1429 | blk_queue_hardsect_size(disk->queue, | ||
1430 | hba[ctlr]->drv[drv_index].block_size); | ||
1431 | |||
1432 | /* Make sure all queue data is written out before */ | ||
1433 | /* setting h->drv[drv_index].queue, as setting this */ | ||
1434 | /* allows the interrupt handler to start the queue */ | ||
1435 | wmb(); | ||
1436 | h->drv[drv_index].queue = disk->queue; | ||
1437 | add_disk(disk); | ||
1438 | } | ||
1439 | 1521 | ||
1440 | freeret: | 1522 | freeret: |
1441 | kfree(inq_buff); | 1523 | kfree(inq_buff); |
1524 | kfree(drvinfo); | ||
1442 | return; | 1525 | return; |
1443 | mem_msg: | 1526 | mem_msg: |
1444 | printk(KERN_ERR "cciss: out of memory\n"); | 1527 | printk(KERN_ERR "cciss: out of memory\n"); |
1445 | goto freeret; | 1528 | goto freeret; |
1446 | } | 1529 | } |
@@ -1450,21 +1533,91 @@ geo_inq: | |||
1450 | * 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 |
1451 | * 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 |
1452 | * 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. | ||
1453 | */ | 1538 | */ |
1454 | static int cciss_find_free_drive_index(int ctlr) | 1539 | static int cciss_find_free_drive_index(int ctlr, int controller_node) |
1455 | { | 1540 | { |
1456 | int i; | 1541 | int i; |
1457 | 1542 | ||
1458 | for (i = 0; i < CISS_MAX_LUN; i++) { | 1543 | for (i = 0; i < CISS_MAX_LUN; i++) { |
1459 | if (hba[ctlr]->drv[i].raid_level == -1) { | 1544 | if (hba[ctlr]->drv[i].raid_level == -1) { |
1460 | if (i > hba[ctlr]->highest_lun) | 1545 | if (i > hba[ctlr]->highest_lun) |
1461 | hba[ctlr]->highest_lun = i; | 1546 | if (!controller_node) |
1547 | hba[ctlr]->highest_lun = i; | ||
1462 | return i; | 1548 | return i; |
1463 | } | 1549 | } |
1464 | } | 1550 | } |
1465 | return -1; | 1551 | return -1; |
1466 | } | 1552 | } |
1467 | 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 | |||
1468 | /* This function will add and remove logical drives from the Logical | 1621 | /* This function will add and remove logical drives from the Logical |
1469 | * drive array of the controller and maintain persistency of ordering | 1622 | * drive array of the controller and maintain persistency of ordering |
1470 | * 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 |
@@ -1472,15 +1625,12 @@ static int cciss_find_free_drive_index(int ctlr) | |||
1472 | * without a re-ordering of those drives. | 1625 | * without a re-ordering of those drives. |
1473 | * INPUT | 1626 | * INPUT |
1474 | * h = The controller to perform the operations on | 1627 | * h = The controller to perform the operations on |
1475 | * del_disk = The disk to remove if specified. If the value given | ||
1476 | * is NULL then no disk is removed. | ||
1477 | */ | 1628 | */ |
1478 | 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) |
1479 | { | 1630 | { |
1480 | int ctlr = h->ctlr; | 1631 | int ctlr = h->ctlr; |
1481 | int num_luns; | 1632 | int num_luns; |
1482 | ReportLunData_struct *ld_buff = NULL; | 1633 | ReportLunData_struct *ld_buff = NULL; |
1483 | drive_info_struct *drv = NULL; | ||
1484 | int return_code; | 1634 | int return_code; |
1485 | int listlength = 0; | 1635 | int listlength = 0; |
1486 | int i; | 1636 | int i; |
@@ -1489,6 +1639,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1489 | __u32 lunid = 0; | 1639 | __u32 lunid = 0; |
1490 | unsigned long flags; | 1640 | unsigned long flags; |
1491 | 1641 | ||
1642 | if (!capable(CAP_SYS_RAWIO)) | ||
1643 | return -EPERM; | ||
1644 | |||
1492 | /* Set busy_configuring flag for this operation */ | 1645 | /* Set busy_configuring flag for this operation */ |
1493 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1646 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
1494 | if (h->busy_configuring) { | 1647 | if (h->busy_configuring) { |
@@ -1496,100 +1649,100 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1496 | return -EBUSY; | 1649 | return -EBUSY; |
1497 | } | 1650 | } |
1498 | h->busy_configuring = 1; | 1651 | h->busy_configuring = 1; |
1652 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1499 | 1653 | ||
1500 | /* if del_disk is NULL then we are being called to add a new disk | 1654 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); |
1501 | * and update the logical drive table. If it is not NULL then | 1655 | if (ld_buff == NULL) |
1502 | * we will check if the disk is in use or not. | 1656 | goto mem_msg; |
1503 | */ | ||
1504 | if (del_disk != NULL) { | ||
1505 | drv = get_drv(del_disk); | ||
1506 | drv->busy_configuring = 1; | ||
1507 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1508 | return_code = deregister_disk(del_disk, drv, 1); | ||
1509 | drv->busy_configuring = 0; | ||
1510 | h->busy_configuring = 0; | ||
1511 | return return_code; | ||
1512 | } else { | ||
1513 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1514 | if (!capable(CAP_SYS_RAWIO)) | ||
1515 | return -EPERM; | ||
1516 | 1657 | ||
1517 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | 1658 | return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, |
1518 | if (ld_buff == NULL) | 1659 | sizeof(ReportLunData_struct), 0, |
1519 | goto mem_msg; | 1660 | 0, 0, TYPE_CMD); |
1520 | 1661 | ||
1521 | return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, | 1662 | if (return_code == IO_OK) |
1522 | sizeof(ReportLunData_struct), 0, | 1663 | listlength = be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); |
1523 | 0, 0, TYPE_CMD); | 1664 | else { /* reading number of logical volumes failed */ |
1524 | 1665 | printk(KERN_WARNING "cciss: report logical volume" | |
1525 | if (return_code == IO_OK) { | 1666 | " command failed\n"); |
1526 | listlength = | 1667 | listlength = 0; |
1527 | be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); | 1668 | goto freeret; |
1528 | } else { /* reading number of logical volumes failed */ | 1669 | } |
1529 | printk(KERN_WARNING "cciss: report logical volume" | 1670 | |
1530 | " command failed\n"); | 1671 | num_luns = listlength / 8; /* 8 bytes per entry */ |
1531 | listlength = 0; | 1672 | if (num_luns > CISS_MAX_LUN) { |
1532 | goto freeret; | 1673 | num_luns = CISS_MAX_LUN; |
1533 | } | 1674 | printk(KERN_WARNING "cciss: more luns configured" |
1675 | " on controller than can be handled by" | ||
1676 | " this driver.\n"); | ||
1677 | } | ||
1534 | 1678 | ||
1535 | num_luns = listlength / 8; /* 8 bytes per entry */ | 1679 | if (num_luns == 0) |
1536 | if (num_luns > CISS_MAX_LUN) { | 1680 | cciss_add_controller_node(h); |
1537 | num_luns = CISS_MAX_LUN; | 1681 | |
1538 | printk(KERN_WARNING "cciss: more luns configured" | 1682 | /* Compare controller drive array to driver's drive array |
1539 | " on controller than can be handled by" | 1683 | * to see if any drives are missing on the controller due |
1540 | " this driver.\n"); | 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 | } | ||
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; | ||
1541 | } | 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; | ||
1716 | |||
1717 | drv_found = 0; | ||
1718 | |||
1719 | memcpy(&lunid, &ld_buff->LUN[i][0], 4); | ||
1720 | lunid = le32_to_cpu(lunid); | ||
1542 | 1721 | ||
1543 | /* Compare controller drive array to drivers drive array. | 1722 | /* Find if the LUN is already in the drive array |
1544 | * Check for updates in the drive information and any new drives | 1723 | * of the driver. If so then update its info |
1545 | * on the controller. | 1724 | * if not in use. If it does not exist then find |
1725 | * the first free index and add it. | ||
1546 | */ | 1726 | */ |
1547 | for (i = 0; i < num_luns; i++) { | 1727 | for (j = 0; j <= h->highest_lun; j++) { |
1548 | int j; | 1728 | if (h->drv[j].raid_level != -1 && |
1549 | 1729 | h->drv[j].LunID == lunid) { | |
1550 | drv_found = 0; | 1730 | drv_index = j; |
1551 | 1731 | drv_found = 1; | |
1552 | lunid = (0xff & | 1732 | break; |
1553 | (unsigned int)(ld_buff->LUN[i][3])) << 24; | ||
1554 | lunid |= (0xff & | ||
1555 | (unsigned int)(ld_buff->LUN[i][2])) << 16; | ||
1556 | lunid |= (0xff & | ||
1557 | (unsigned int)(ld_buff->LUN[i][1])) << 8; | ||
1558 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | ||
1559 | |||
1560 | /* Find if the LUN is already in the drive array | ||
1561 | * of the controller. If so then update its info | ||
1562 | * if not is use. If it does not exist then find | ||
1563 | * the first free index and add it. | ||
1564 | */ | ||
1565 | for (j = 0; j <= h->highest_lun; j++) { | ||
1566 | if (h->drv[j].LunID == lunid) { | ||
1567 | drv_index = j; | ||
1568 | drv_found = 1; | ||
1569 | } | ||
1570 | } | 1733 | } |
1734 | } | ||
1571 | 1735 | ||
1572 | /* check if the drive was found already in the array */ | 1736 | /* check if the drive was found already in the array */ |
1573 | if (!drv_found) { | 1737 | if (!drv_found) { |
1574 | drv_index = cciss_find_free_drive_index(ctlr); | 1738 | drv_index = cciss_add_gendisk(h, lunid, 0); |
1575 | if (drv_index == -1) | 1739 | if (drv_index == -1) |
1576 | goto freeret; | 1740 | goto freeret; |
1577 | 1741 | } | |
1578 | /*Check if the gendisk needs to be allocated */ | 1742 | cciss_update_drive_info(ctlr, drv_index, first_time); |
1579 | if (!h->gendisk[drv_index]){ | 1743 | } /* end for */ |
1580 | h->gendisk[drv_index] = alloc_disk(1 << NWD_SHIFT); | ||
1581 | if (!h->gendisk[drv_index]){ | ||
1582 | printk(KERN_ERR "cciss: could not allocate new disk %d\n", drv_index); | ||
1583 | goto mem_msg; | ||
1584 | } | ||
1585 | } | ||
1586 | } | ||
1587 | h->drv[drv_index].LunID = lunid; | ||
1588 | cciss_update_drive_info(ctlr, drv_index); | ||
1589 | } /* end for */ | ||
1590 | } /* end else */ | ||
1591 | 1744 | ||
1592 | freeret: | 1745 | freeret: |
1593 | kfree(ld_buff); | 1746 | kfree(ld_buff); |
1594 | h->busy_configuring = 0; | 1747 | h->busy_configuring = 0; |
1595 | /* 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 |
@@ -1597,8 +1750,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1597 | * additional times. | 1750 | * additional times. |
1598 | */ | 1751 | */ |
1599 | return -1; | 1752 | return -1; |
1600 | mem_msg: | 1753 | mem_msg: |
1601 | printk(KERN_ERR "cciss: out of memory\n"); | 1754 | printk(KERN_ERR "cciss: out of memory\n"); |
1755 | h->busy_configuring = 0; | ||
1602 | goto freeret; | 1756 | goto freeret; |
1603 | } | 1757 | } |
1604 | 1758 | ||
@@ -1654,15 +1808,15 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | |||
1654 | * 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 |
1655 | * 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 |
1656 | * configure the controller. | 1810 | * configure the controller. |
1657 | */ | 1811 | */ |
1658 | if (clear_all){ | 1812 | if (clear_all){ |
1659 | /* This isn't pretty, but we need to find the | 1813 | /* This isn't pretty, but we need to find the |
1660 | * disk in our array and NULL our the pointer. | 1814 | * disk in our array and NULL our the pointer. |
1661 | * This is so that we will call alloc_disk if | 1815 | * This is so that we will call alloc_disk if |
1662 | * this index is used again later. | 1816 | * this index is used again later. |
1663 | */ | 1817 | */ |
1664 | for (i=0; i < CISS_MAX_LUN; i++){ | 1818 | for (i=0; i < CISS_MAX_LUN; i++){ |
1665 | if(h->gendisk[i] == disk){ | 1819 | if (h->gendisk[i] == disk) { |
1666 | h->gendisk[i] = NULL; | 1820 | h->gendisk[i] = NULL; |
1667 | break; | 1821 | break; |
1668 | } | 1822 | } |
@@ -1690,7 +1844,7 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | |||
1690 | if (drv == h->drv + h->highest_lun) { | 1844 | if (drv == h->drv + h->highest_lun) { |
1691 | /* if so, find the new hightest lun */ | 1845 | /* if so, find the new hightest lun */ |
1692 | int i, newhighest = -1; | 1846 | int i, newhighest = -1; |
1693 | for (i = 0; i < h->highest_lun; i++) { | 1847 | for (i = 0; i <= h->highest_lun; i++) { |
1694 | /* if the disk has size > 0, it is available */ | 1848 | /* if the disk has size > 0, it is available */ |
1695 | if (h->drv[i].heads) | 1849 | if (h->drv[i].heads) |
1696 | newhighest = i; | 1850 | newhighest = i; |
@@ -3201,136 +3355,9 @@ err_out_free_res: | |||
3201 | return err; | 3355 | return err; |
3202 | } | 3356 | } |
3203 | 3357 | ||
3204 | /* | 3358 | /* Function to find the first free pointer into our hba[] array |
3205 | * Gets information about the local volumes attached to the controller. | 3359 | * Returns -1 if no free entries are left. |
3206 | */ | 3360 | */ |
3207 | static void cciss_getgeometry(int cntl_num) | ||
3208 | { | ||
3209 | ReportLunData_struct *ld_buff; | ||
3210 | InquiryData_struct *inq_buff; | ||
3211 | int return_code; | ||
3212 | int i; | ||
3213 | int listlength = 0; | ||
3214 | __u32 lunid = 0; | ||
3215 | unsigned block_size; | ||
3216 | sector_t total_size; | ||
3217 | |||
3218 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | ||
3219 | if (ld_buff == NULL) { | ||
3220 | printk(KERN_ERR "cciss: out of memory\n"); | ||
3221 | return; | ||
3222 | } | ||
3223 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
3224 | if (inq_buff == NULL) { | ||
3225 | printk(KERN_ERR "cciss: out of memory\n"); | ||
3226 | kfree(ld_buff); | ||
3227 | return; | ||
3228 | } | ||
3229 | /* Get the firmware version */ | ||
3230 | return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, | ||
3231 | sizeof(InquiryData_struct), 0, 0, 0, NULL, | ||
3232 | TYPE_CMD); | ||
3233 | if (return_code == IO_OK) { | ||
3234 | hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32]; | ||
3235 | hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33]; | ||
3236 | hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34]; | ||
3237 | hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35]; | ||
3238 | } else { /* send command failed */ | ||
3239 | |||
3240 | printk(KERN_WARNING "cciss: unable to determine firmware" | ||
3241 | " version of controller\n"); | ||
3242 | } | ||
3243 | /* Get the number of logical volumes */ | ||
3244 | return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, | ||
3245 | sizeof(ReportLunData_struct), 0, 0, 0, NULL, | ||
3246 | TYPE_CMD); | ||
3247 | |||
3248 | if (return_code == IO_OK) { | ||
3249 | #ifdef CCISS_DEBUG | ||
3250 | printk("LUN Data\n--------------------------\n"); | ||
3251 | #endif /* CCISS_DEBUG */ | ||
3252 | |||
3253 | listlength |= | ||
3254 | (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; | ||
3255 | listlength |= | ||
3256 | (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; | ||
3257 | listlength |= | ||
3258 | (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; | ||
3259 | listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); | ||
3260 | } else { /* reading number of logical volumes failed */ | ||
3261 | |||
3262 | printk(KERN_WARNING "cciss: report logical volume" | ||
3263 | " command failed\n"); | ||
3264 | listlength = 0; | ||
3265 | } | ||
3266 | hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry | ||
3267 | if (hba[cntl_num]->num_luns > CISS_MAX_LUN) { | ||
3268 | printk(KERN_ERR | ||
3269 | "ciss: only %d number of logical volumes supported\n", | ||
3270 | CISS_MAX_LUN); | ||
3271 | hba[cntl_num]->num_luns = CISS_MAX_LUN; | ||
3272 | } | ||
3273 | #ifdef CCISS_DEBUG | ||
3274 | printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", | ||
3275 | ld_buff->LUNListLength[0], ld_buff->LUNListLength[1], | ||
3276 | ld_buff->LUNListLength[2], ld_buff->LUNListLength[3], | ||
3277 | hba[cntl_num]->num_luns); | ||
3278 | #endif /* CCISS_DEBUG */ | ||
3279 | |||
3280 | hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1; | ||
3281 | for (i = 0; i < CISS_MAX_LUN; i++) { | ||
3282 | if (i < hba[cntl_num]->num_luns) { | ||
3283 | lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) | ||
3284 | << 24; | ||
3285 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) | ||
3286 | << 16; | ||
3287 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) | ||
3288 | << 8; | ||
3289 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | ||
3290 | |||
3291 | hba[cntl_num]->drv[i].LunID = lunid; | ||
3292 | |||
3293 | #ifdef CCISS_DEBUG | ||
3294 | printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i, | ||
3295 | ld_buff->LUN[i][0], ld_buff->LUN[i][1], | ||
3296 | ld_buff->LUN[i][2], ld_buff->LUN[i][3], | ||
3297 | hba[cntl_num]->drv[i].LunID); | ||
3298 | #endif /* CCISS_DEBUG */ | ||
3299 | |||
3300 | /* testing to see if 16-byte CDBs are already being used */ | ||
3301 | if(hba[cntl_num]->cciss_read == CCISS_READ_16) { | ||
3302 | cciss_read_capacity_16(cntl_num, i, 0, | ||
3303 | &total_size, &block_size); | ||
3304 | goto geo_inq; | ||
3305 | } | ||
3306 | cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size); | ||
3307 | |||
3308 | /* If read_capacity returns all F's the logical is >2TB */ | ||
3309 | /* so we switch to 16-byte CDBs for all read/write ops */ | ||
3310 | if(total_size == 0xFFFFFFFFULL) { | ||
3311 | cciss_read_capacity_16(cntl_num, i, 0, | ||
3312 | &total_size, &block_size); | ||
3313 | hba[cntl_num]->cciss_read = CCISS_READ_16; | ||
3314 | hba[cntl_num]->cciss_write = CCISS_WRITE_16; | ||
3315 | } else { | ||
3316 | hba[cntl_num]->cciss_read = CCISS_READ_10; | ||
3317 | hba[cntl_num]->cciss_write = CCISS_WRITE_10; | ||
3318 | } | ||
3319 | geo_inq: | ||
3320 | cciss_geometry_inquiry(cntl_num, i, 0, total_size, | ||
3321 | block_size, inq_buff, | ||
3322 | &hba[cntl_num]->drv[i]); | ||
3323 | } else { | ||
3324 | /* initialize raid_level to indicate a free space */ | ||
3325 | hba[cntl_num]->drv[i].raid_level = -1; | ||
3326 | } | ||
3327 | } | ||
3328 | kfree(ld_buff); | ||
3329 | kfree(inq_buff); | ||
3330 | } | ||
3331 | |||
3332 | /* Function to find the first free pointer into our hba[] array */ | ||
3333 | /* Returns -1 if no free entries are left. */ | ||
3334 | static int alloc_cciss_hba(void) | 3361 | static int alloc_cciss_hba(void) |
3335 | { | 3362 | { |
3336 | int i; | 3363 | int i; |
@@ -3342,11 +3369,6 @@ static int alloc_cciss_hba(void) | |||
3342 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); | 3369 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); |
3343 | if (!p) | 3370 | if (!p) |
3344 | goto Enomem; | 3371 | goto Enomem; |
3345 | p->gendisk[0] = alloc_disk(1 << NWD_SHIFT); | ||
3346 | if (!p->gendisk[0]) { | ||
3347 | kfree(p); | ||
3348 | goto Enomem; | ||
3349 | } | ||
3350 | hba[i] = p; | 3372 | hba[i] = p; |
3351 | return i; | 3373 | return i; |
3352 | } | 3374 | } |
@@ -3474,11 +3496,13 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3474 | ((hba[i]->nr_cmds + BITS_PER_LONG - | 3496 | ((hba[i]->nr_cmds + BITS_PER_LONG - |
3475 | 1) / BITS_PER_LONG) * sizeof(unsigned long)); | 3497 | 1) / BITS_PER_LONG) * sizeof(unsigned long)); |
3476 | 3498 | ||
3477 | #ifdef CCISS_DEBUG | 3499 | hba[i]->num_luns = 0; |
3478 | printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n", i); | 3500 | hba[i]->highest_lun = -1; |
3479 | #endif /* CCISS_DEBUG */ | 3501 | for (j = 0; j < CISS_MAX_LUN; j++) { |
3480 | 3502 | hba[i]->drv[j].raid_level = -1; | |
3481 | cciss_getgeometry(i); | 3503 | hba[i]->drv[j].queue = NULL; |
3504 | hba[i]->gendisk[j] = NULL; | ||
3505 | } | ||
3482 | 3506 | ||
3483 | cciss_scsi_setup(i); | 3507 | cciss_scsi_setup(i); |
3484 | 3508 | ||
@@ -3491,76 +3515,10 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3491 | 3515 | ||
3492 | hba[i]->busy_initializing = 0; | 3516 | hba[i]->busy_initializing = 0; |
3493 | 3517 | ||
3494 | do { | 3518 | rebuild_lun_table(hba[i], 1); |
3495 | drive_info_struct *drv = &(hba[i]->drv[j]); | ||
3496 | struct gendisk *disk = hba[i]->gendisk[j]; | ||
3497 | struct request_queue *q; | ||
3498 | |||
3499 | /* Check if the disk was allocated already */ | ||
3500 | if (!disk){ | ||
3501 | hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT); | ||
3502 | disk = hba[i]->gendisk[j]; | ||
3503 | } | ||
3504 | |||
3505 | /* Check that the disk was able to be allocated */ | ||
3506 | if (!disk) { | ||
3507 | printk(KERN_ERR "cciss: unable to allocate memory for disk %d\n", j); | ||
3508 | goto clean4; | ||
3509 | } | ||
3510 | |||
3511 | q = blk_init_queue(do_cciss_request, &hba[i]->lock); | ||
3512 | if (!q) { | ||
3513 | printk(KERN_ERR | ||
3514 | "cciss: unable to allocate queue for disk %d\n", | ||
3515 | j); | ||
3516 | goto clean4; | ||
3517 | } | ||
3518 | drv->queue = q; | ||
3519 | |||
3520 | blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); | ||
3521 | |||
3522 | /* This is a hardware imposed limit. */ | ||
3523 | blk_queue_max_hw_segments(q, MAXSGENTRIES); | ||
3524 | |||
3525 | /* This is a limit in the driver and could be eliminated. */ | ||
3526 | blk_queue_max_phys_segments(q, MAXSGENTRIES); | ||
3527 | |||
3528 | blk_queue_max_sectors(q, hba[i]->cciss_max_sectors); | ||
3529 | |||
3530 | blk_queue_softirq_done(q, cciss_softirq_done); | ||
3531 | |||
3532 | q->queuedata = hba[i]; | ||
3533 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); | ||
3534 | disk->major = hba[i]->major; | ||
3535 | disk->first_minor = j << NWD_SHIFT; | ||
3536 | disk->fops = &cciss_fops; | ||
3537 | disk->queue = q; | ||
3538 | disk->private_data = drv; | ||
3539 | disk->driverfs_dev = &pdev->dev; | ||
3540 | /* we must register the controller even if no disks exist */ | ||
3541 | /* this is for the online array utilities */ | ||
3542 | if (!drv->heads && j) | ||
3543 | continue; | ||
3544 | blk_queue_hardsect_size(q, drv->block_size); | ||
3545 | set_capacity(disk, drv->nr_blocks); | ||
3546 | j++; | ||
3547 | } while (j <= hba[i]->highest_lun); | ||
3548 | |||
3549 | /* Make sure all queue data is written out before */ | ||
3550 | /* interrupt handler, triggered by add_disk, */ | ||
3551 | /* is allowed to start them. */ | ||
3552 | wmb(); | ||
3553 | |||
3554 | for (j = 0; j <= hba[i]->highest_lun; j++) | ||
3555 | add_disk(hba[i]->gendisk[j]); | ||
3556 | |||
3557 | /* we must register the controller even if no disks exist */ | ||
3558 | if (hba[i]->highest_lun == -1) | ||
3559 | add_disk(hba[i]->gendisk[0]); | ||
3560 | |||
3561 | return 1; | 3519 | return 1; |
3562 | 3520 | ||
3563 | clean4: | 3521 | clean4: |
3564 | #ifdef CONFIG_CISS_SCSI_TAPE | 3522 | #ifdef CONFIG_CISS_SCSI_TAPE |
3565 | kfree(hba[i]->scsi_rejects.complete); | 3523 | kfree(hba[i]->scsi_rejects.complete); |
3566 | #endif | 3524 | #endif |
@@ -3575,9 +3533,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3575 | hba[i]->errinfo_pool, | 3533 | hba[i]->errinfo_pool, |
3576 | hba[i]->errinfo_pool_dhandle); | 3534 | hba[i]->errinfo_pool_dhandle); |
3577 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); | 3535 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); |
3578 | clean2: | 3536 | clean2: |
3579 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 3537 | unregister_blkdev(hba[i]->major, hba[i]->devname); |
3580 | clean1: | 3538 | clean1: |
3581 | hba[i]->busy_initializing = 0; | 3539 | hba[i]->busy_initializing = 0; |
3582 | /* cleanup any queues that may have been initialized */ | 3540 | /* cleanup any queues that may have been initialized */ |
3583 | for (j=0; j <= hba[i]->highest_lun; j++){ | 3541 | for (j=0; j <= hba[i]->highest_lun; j++){ |
@@ -3656,7 +3614,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
3656 | } | 3614 | } |
3657 | } | 3615 | } |
3658 | 3616 | ||
3617 | #ifdef CONFIG_CISS_SCSI_TAPE | ||
3659 | cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ | 3618 | cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ |
3619 | #endif | ||
3660 | 3620 | ||
3661 | cciss_shutdown(pdev); | 3621 | cciss_shutdown(pdev); |
3662 | 3622 | ||