diff options
| -rw-r--r-- | drivers/block/cciss.c | 473 |
1 files changed, 169 insertions, 304 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index f9f10a15d253..08255644e80a 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; |
| @@ -1361,6 +1356,42 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq, | |||
| 1361 | return; | 1356 | return; |
| 1362 | } | 1357 | } |
| 1363 | 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 | |||
| 1364 | /* 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. |
| 1365 | * If the usage_count is zero and it is a heretofore unknown drive, or, | 1396 | * If the usage_count is zero and it is a heretofore unknown drive, or, |
| 1366 | * the drive's capacity, geometry, or serial number has changed, | 1397 | * the drive's capacity, geometry, or serial number has changed, |
| @@ -1371,7 +1402,7 @@ static void cciss_get_serial_no(int ctlr, int logvol, int withirq, | |||
| 1371 | * is also the controller node. Any changes to disk 0 will show up on | 1402 | * is also the controller node. Any changes to disk 0 will show up on |
| 1372 | * the next reboot. | 1403 | * the next reboot. |
| 1373 | */ | 1404 | */ |
| 1374 | 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) |
| 1375 | { | 1406 | { |
| 1376 | ctlr_info_t *h = hba[ctlr]; | 1407 | ctlr_info_t *h = hba[ctlr]; |
| 1377 | struct gendisk *disk; | 1408 | struct gendisk *disk; |
| @@ -1381,6 +1412,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
| 1381 | unsigned long flags = 0; | 1412 | unsigned long flags = 0; |
| 1382 | int ret = 0; | 1413 | int ret = 0; |
| 1383 | drive_info_struct *drvinfo; | 1414 | drive_info_struct *drvinfo; |
| 1415 | int was_only_controller_node; | ||
| 1384 | 1416 | ||
| 1385 | /* Get information about the disk and modify the driver structure */ | 1417 | /* Get information about the disk and modify the driver structure */ |
| 1386 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | 1418 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); |
| @@ -1388,6 +1420,13 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
| 1388 | if (inq_buff == NULL || drvinfo == NULL) | 1420 | if (inq_buff == NULL || drvinfo == NULL) |
| 1389 | goto mem_msg; | 1421 | goto mem_msg; |
| 1390 | 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); | ||
| 1429 | |||
| 1391 | /* testing to see if 16-byte CDBs are already being used */ | 1430 | /* testing to see if 16-byte CDBs are already being used */ |
| 1392 | if (h->cciss_read == CCISS_READ_16) { | 1431 | if (h->cciss_read == CCISS_READ_16) { |
| 1393 | cciss_read_capacity_16(h->ctlr, drv_index, 1, | 1432 | cciss_read_capacity_16(h->ctlr, drv_index, 1, |
| @@ -1427,25 +1466,26 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
| 1427 | drvinfo->nr_blocks == h->drv[drv_index].nr_blocks && | 1466 | drvinfo->nr_blocks == h->drv[drv_index].nr_blocks && |
| 1428 | drvinfo->heads == h->drv[drv_index].heads && | 1467 | drvinfo->heads == h->drv[drv_index].heads && |
| 1429 | drvinfo->sectors == h->drv[drv_index].sectors && | 1468 | drvinfo->sectors == h->drv[drv_index].sectors && |
| 1430 | drvinfo->cylinders == h->drv[drv_index].cylinders)) { | 1469 | drvinfo->cylinders == h->drv[drv_index].cylinders)) |
| 1431 | /* The disk is unchanged, nothing to update */ | 1470 | /* The disk is unchanged, nothing to update */ |
| 1432 | goto freeret; | 1471 | goto freeret; |
| 1433 | } | ||
| 1434 | 1472 | ||
| 1435 | /* Not the same disk, or something's changed, so we need to */ | 1473 | /* If we get here it's not the same disk, or something's changed, |
| 1436 | /* deregister it, and re-register it, if it's not in use. */ | 1474 | * so we need to * deregister it, and re-register it, if it's not |
| 1437 | 1475 | * in use. | |
| 1438 | /* if the disk already exists then deregister it before proceeding */ | 1476 | * If the disk already exists then deregister it before proceeding |
| 1439 | /* (unless it's the first disk (for the controller node). */ | 1477 | * (unless it's the first disk (for the controller node). |
| 1478 | */ | ||
| 1440 | if (h->drv[drv_index].raid_level != -1 && drv_index != 0) { | 1479 | if (h->drv[drv_index].raid_level != -1 && drv_index != 0) { |
| 1441 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); | 1480 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); |
| 1442 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1481 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
| 1443 | h->drv[drv_index].busy_configuring = 1; | 1482 | h->drv[drv_index].busy_configuring = 1; |
| 1444 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1483 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
| 1445 | 1484 | ||
| 1446 | /* deregister_disk sets h->drv[drv_index].queue = NULL */ | 1485 | /* deregister_disk sets h->drv[drv_index].queue = NULL |
| 1447 | /* which keeps the interrupt handler from starting */ | 1486 | * which keeps the interrupt handler from starting |
| 1448 | /* the queue. */ | 1487 | * the queue. |
| 1488 | */ | ||
| 1449 | ret = deregister_disk(h->gendisk[drv_index], | 1489 | ret = deregister_disk(h->gendisk[drv_index], |
| 1450 | &h->drv[drv_index], 0); | 1490 | &h->drv[drv_index], 0); |
| 1451 | h->drv[drv_index].busy_configuring = 0; | 1491 | h->drv[drv_index].busy_configuring = 0; |
| @@ -1455,8 +1495,9 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
| 1455 | if (ret) | 1495 | if (ret) |
| 1456 | goto freeret; | 1496 | goto freeret; |
| 1457 | 1497 | ||
| 1458 | /* Save the new information from cciss_geometry_inquiry */ | 1498 | /* Save the new information from cciss_geometry_inquiry |
| 1459 | /* and serial number inquiry. */ | 1499 | * and serial number inquiry. |
| 1500 | */ | ||
| 1460 | h->drv[drv_index].block_size = drvinfo->block_size; | 1501 | h->drv[drv_index].block_size = drvinfo->block_size; |
| 1461 | h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; | 1502 | h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; |
| 1462 | h->drv[drv_index].heads = drvinfo->heads; | 1503 | h->drv[drv_index].heads = drvinfo->heads; |
| @@ -1469,46 +1510,20 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
| 1469 | disk = h->gendisk[drv_index]; | 1510 | disk = h->gendisk[drv_index]; |
| 1470 | set_capacity(disk, h->drv[drv_index].nr_blocks); | 1511 | set_capacity(disk, h->drv[drv_index].nr_blocks); |
| 1471 | 1512 | ||
| 1472 | /* if it's the controller (if drv_index == 0) it's already added */ | 1513 | /* If it's not disk 0 (drv_index != 0) |
| 1473 | if (drv_index) { | 1514 | * or if it was disk 0, but there was previously |
| 1474 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | 1515 | * no actual corresponding configured logical drive |
| 1475 | sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index); | 1516 | * (raid_leve == -1) then we want to update the |
| 1476 | disk->major = h->major; | 1517 | * logical drive's information. |
| 1477 | disk->first_minor = drv_index << NWD_SHIFT; | 1518 | */ |
| 1478 | disk->fops = &cciss_fops; | 1519 | if (drv_index || first_time) |
| 1479 | disk->private_data = &h->drv[drv_index]; | 1520 | cciss_add_disk(h, disk, drv_index); |
| 1480 | |||
| 1481 | /* Set up queue information */ | ||
| 1482 | blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask); | ||
| 1483 | |||
| 1484 | /* This is a hardware imposed limit. */ | ||
| 1485 | blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES); | ||
| 1486 | |||
| 1487 | /* This is a limit in the driver and could be eliminated. */ | ||
| 1488 | blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); | ||
| 1489 | |||
| 1490 | blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); | ||
| 1491 | |||
| 1492 | blk_queue_softirq_done(disk->queue, cciss_softirq_done); | ||
| 1493 | |||
| 1494 | disk->queue->queuedata = hba[ctlr]; | ||
| 1495 | |||
| 1496 | blk_queue_hardsect_size(disk->queue, | ||
| 1497 | hba[ctlr]->drv[drv_index].block_size); | ||
| 1498 | |||
| 1499 | /* Make sure all queue data is written out before */ | ||
| 1500 | /* setting h->drv[drv_index].queue, as setting this */ | ||
| 1501 | /* allows the interrupt handler to start the queue */ | ||
| 1502 | wmb(); | ||
| 1503 | h->drv[drv_index].queue = disk->queue; | ||
| 1504 | add_disk(disk); | ||
| 1505 | } | ||
| 1506 | 1521 | ||
| 1507 | freeret: | 1522 | freeret: |
| 1508 | kfree(inq_buff); | 1523 | kfree(inq_buff); |
| 1509 | kfree(drvinfo); | 1524 | kfree(drvinfo); |
| 1510 | return; | 1525 | return; |
| 1511 | mem_msg: | 1526 | mem_msg: |
| 1512 | printk(KERN_ERR "cciss: out of memory\n"); | 1527 | printk(KERN_ERR "cciss: out of memory\n"); |
| 1513 | goto freeret; | 1528 | goto freeret; |
| 1514 | } | 1529 | } |
| @@ -1533,6 +1548,73 @@ static int cciss_find_free_drive_index(int ctlr) | |||
| 1533 | return -1; | 1548 | return -1; |
| 1534 | } | 1549 | } |
| 1535 | 1550 | ||
| 1551 | /* cciss_add_gendisk finds a free hba[]->drv structure | ||
| 1552 | * and allocates a gendisk if needed, and sets the lunid | ||
| 1553 | * in the drvinfo structure. It returns the index into | ||
| 1554 | * the ->drv[] array, or -1 if none are free. | ||
| 1555 | * is_controller_node indicates whether highest_lun should | ||
| 1556 | * count this disk, or if it's only being added to provide | ||
| 1557 | * a means to talk to the controller in case no logical | ||
| 1558 | * drives have yet been configured. | ||
| 1559 | */ | ||
| 1560 | static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid) | ||
| 1561 | { | ||
| 1562 | int drv_index; | ||
| 1563 | |||
| 1564 | drv_index = cciss_find_free_drive_index(h->ctlr); | ||
| 1565 | if (drv_index == -1) | ||
| 1566 | return -1; | ||
| 1567 | /*Check if the gendisk needs to be allocated */ | ||
| 1568 | if (!h->gendisk[drv_index]) { | ||
| 1569 | h->gendisk[drv_index] = | ||
| 1570 | alloc_disk(1 << NWD_SHIFT); | ||
| 1571 | if (!h->gendisk[drv_index]) { | ||
| 1572 | printk(KERN_ERR "cciss%d: could not " | ||
| 1573 | "allocate a new disk %d\n", | ||
| 1574 | h->ctlr, drv_index); | ||
| 1575 | return -1; | ||
| 1576 | } | ||
| 1577 | } | ||
| 1578 | h->drv[drv_index].LunID = lunid; | ||
| 1579 | |||
| 1580 | /* Don't need to mark this busy because nobody */ | ||
| 1581 | /* else knows about this disk yet to contend */ | ||
| 1582 | /* for access to it. */ | ||
| 1583 | h->drv[drv_index].busy_configuring = 0; | ||
| 1584 | wmb(); | ||
| 1585 | return drv_index; | ||
| 1586 | } | ||
| 1587 | |||
| 1588 | /* This is for the special case of a controller which | ||
| 1589 | * has no logical drives. In this case, we still need | ||
| 1590 | * to register a disk so the controller can be accessed | ||
| 1591 | * by the Array Config Utility. | ||
| 1592 | */ | ||
| 1593 | static void cciss_add_controller_node(ctlr_info_t *h) | ||
| 1594 | { | ||
| 1595 | struct gendisk *disk; | ||
| 1596 | int drv_index; | ||
| 1597 | |||
| 1598 | if (h->gendisk[0] != NULL) /* already did this? Then bail. */ | ||
| 1599 | return; | ||
| 1600 | |||
| 1601 | drv_index = cciss_add_gendisk(h, 0); | ||
| 1602 | if (drv_index == -1) { | ||
| 1603 | printk(KERN_WARNING "cciss%d: could not " | ||
| 1604 | "add disk 0.\n", h->ctlr); | ||
| 1605 | return; | ||
| 1606 | } | ||
| 1607 | h->drv[drv_index].block_size = 512; | ||
| 1608 | h->drv[drv_index].nr_blocks = 0; | ||
| 1609 | h->drv[drv_index].heads = 0; | ||
| 1610 | h->drv[drv_index].sectors = 0; | ||
| 1611 | h->drv[drv_index].cylinders = 0; | ||
| 1612 | h->drv[drv_index].raid_level = -1; | ||
| 1613 | memset(h->drv[drv_index].serial_no, 0, 16); | ||
| 1614 | disk = h->gendisk[drv_index]; | ||
| 1615 | cciss_add_disk(h, disk, drv_index); | ||
| 1616 | } | ||
| 1617 | |||
| 1536 | /* This function will add and remove logical drives from the Logical | 1618 | /* This function will add and remove logical drives from the Logical |
| 1537 | * drive array of the controller and maintain persistency of ordering | 1619 | * drive array of the controller and maintain persistency of ordering |
| 1538 | * so that mount points are preserved until the next reboot. This allows | 1620 | * so that mount points are preserved until the next reboot. This allows |
| @@ -1540,10 +1622,8 @@ static int cciss_find_free_drive_index(int ctlr) | |||
| 1540 | * without a re-ordering of those drives. | 1622 | * without a re-ordering of those drives. |
| 1541 | * INPUT | 1623 | * INPUT |
| 1542 | * h = The controller to perform the operations on | 1624 | * h = The controller to perform the operations on |
| 1543 | * del_disk = The disk to remove if specified. If the value given | ||
| 1544 | * is NULL then no disk is removed. | ||
| 1545 | */ | 1625 | */ |
| 1546 | static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | 1626 | static int rebuild_lun_table(ctlr_info_t *h, int first_time) |
| 1547 | { | 1627 | { |
| 1548 | int ctlr = h->ctlr; | 1628 | int ctlr = h->ctlr; |
| 1549 | int num_luns; | 1629 | int num_luns; |
| @@ -1556,6 +1636,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
| 1556 | __u32 lunid = 0; | 1636 | __u32 lunid = 0; |
| 1557 | unsigned long flags; | 1637 | unsigned long flags; |
| 1558 | 1638 | ||
| 1639 | if (!capable(CAP_SYS_RAWIO)) | ||
| 1640 | return -EPERM; | ||
| 1641 | |||
| 1559 | /* Set busy_configuring flag for this operation */ | 1642 | /* Set busy_configuring flag for this operation */ |
| 1560 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1643 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
| 1561 | if (h->busy_configuring) { | 1644 | if (h->busy_configuring) { |
| @@ -1565,9 +1648,6 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
| 1565 | h->busy_configuring = 1; | 1648 | h->busy_configuring = 1; |
| 1566 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1649 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
| 1567 | 1650 | ||
| 1568 | if (!capable(CAP_SYS_RAWIO)) | ||
| 1569 | return -EPERM; | ||
| 1570 | |||
| 1571 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | 1651 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); |
| 1572 | if (ld_buff == NULL) | 1652 | if (ld_buff == NULL) |
| 1573 | goto mem_msg; | 1653 | goto mem_msg; |
| @@ -1593,10 +1673,14 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
| 1593 | " this driver.\n"); | 1673 | " this driver.\n"); |
| 1594 | } | 1674 | } |
| 1595 | 1675 | ||
| 1596 | /* Compare controller drive array to driver's drive array */ | 1676 | if (num_luns == 0) |
| 1597 | /* to see if any drives are missing on the controller due */ | 1677 | cciss_add_controller_node(h); |
| 1598 | /* to action of Array Config Utility (user deletes drive) */ | 1678 | |
| 1599 | /* and deregister logical drives which have disappeared. */ | 1679 | /* Compare controller drive array to driver's drive array |
| 1680 | * to see if any drives are missing on the controller due | ||
| 1681 | * to action of Array Config Utility (user deletes drive) | ||
| 1682 | * and deregister logical drives which have disappeared. | ||
| 1683 | */ | ||
| 1600 | for (i = 0; i <= h->highest_lun; i++) { | 1684 | for (i = 0; i <= h->highest_lun; i++) { |
| 1601 | int j; | 1685 | int j; |
| 1602 | drv_found = 0; | 1686 | drv_found = 0; |
| @@ -1648,34 +1732,14 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
| 1648 | 1732 | ||
| 1649 | /* check if the drive was found already in the array */ | 1733 | /* check if the drive was found already in the array */ |
| 1650 | if (!drv_found) { | 1734 | if (!drv_found) { |
| 1651 | drv_index = cciss_find_free_drive_index(ctlr); | 1735 | drv_index = cciss_add_gendisk(h, lunid); |
| 1652 | if (drv_index == -1) | 1736 | if (drv_index == -1) |
| 1653 | goto freeret; | 1737 | goto freeret; |
| 1654 | /*Check if the gendisk needs to be allocated */ | ||
| 1655 | if (!h->gendisk[drv_index]) { | ||
| 1656 | h->gendisk[drv_index] = | ||
| 1657 | alloc_disk(1 << NWD_SHIFT); | ||
| 1658 | if (!h->gendisk[drv_index]){ | ||
| 1659 | printk(KERN_ERR "cciss: could not " | ||
| 1660 | "allocate new disk %d\n", | ||
| 1661 | drv_index); | ||
| 1662 | goto mem_msg; | ||
| 1663 | } | ||
| 1664 | } | ||
| 1665 | h->drv[drv_index].LunID = lunid; | ||
| 1666 | |||
| 1667 | /* Don't need to mark this busy because nobody | ||
| 1668 | * else knows about this disk yet to contend | ||
| 1669 | * for access to it. | ||
| 1670 | */ | ||
| 1671 | h->drv[drv_index].busy_configuring = 0; | ||
| 1672 | wmb(); | ||
| 1673 | |||
| 1674 | } | 1738 | } |
| 1675 | cciss_update_drive_info(ctlr, drv_index); | 1739 | cciss_update_drive_info(ctlr, drv_index, first_time); |
| 1676 | } /* end for */ | 1740 | } /* end for */ |
| 1677 | 1741 | ||
| 1678 | freeret: | 1742 | freeret: |
| 1679 | kfree(ld_buff); | 1743 | kfree(ld_buff); |
| 1680 | h->busy_configuring = 0; | 1744 | h->busy_configuring = 0; |
| 1681 | /* We return -1 here to tell the ACU that we have registered/updated | 1745 | /* We return -1 here to tell the ACU that we have registered/updated |
| @@ -1683,7 +1747,7 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
| 1683 | * additional times. | 1747 | * additional times. |
| 1684 | */ | 1748 | */ |
| 1685 | return -1; | 1749 | return -1; |
| 1686 | mem_msg: | 1750 | mem_msg: |
| 1687 | printk(KERN_ERR "cciss: out of memory\n"); | 1751 | printk(KERN_ERR "cciss: out of memory\n"); |
| 1688 | h->busy_configuring = 0; | 1752 | h->busy_configuring = 0; |
| 1689 | goto freeret; | 1753 | goto freeret; |
| @@ -3288,139 +3352,9 @@ err_out_free_res: | |||
| 3288 | return err; | 3352 | return err; |
| 3289 | } | 3353 | } |
| 3290 | 3354 | ||
| 3291 | /* | 3355 | /* Function to find the first free pointer into our hba[] array |
| 3292 | * Gets information about the local volumes attached to the controller. | 3356 | * Returns -1 if no free entries are left. |
| 3293 | */ | 3357 | */ |
| 3294 | static void cciss_getgeometry(int cntl_num) | ||
| 3295 | { | ||
| 3296 | ReportLunData_struct *ld_buff; | ||
| 3297 | InquiryData_struct *inq_buff; | ||
| 3298 | int return_code; | ||
| 3299 | int i; | ||
| 3300 | int listlength = 0; | ||
| 3301 | __u32 lunid = 0; | ||
| 3302 | unsigned block_size; | ||
| 3303 | sector_t total_size; | ||
| 3304 | |||
| 3305 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | ||
| 3306 | if (ld_buff == NULL) { | ||
| 3307 | printk(KERN_ERR "cciss: out of memory\n"); | ||
| 3308 | return; | ||
| 3309 | } | ||
| 3310 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
| 3311 | if (inq_buff == NULL) { | ||
| 3312 | printk(KERN_ERR "cciss: out of memory\n"); | ||
| 3313 | kfree(ld_buff); | ||
| 3314 | return; | ||
| 3315 | } | ||
| 3316 | /* Get the firmware version */ | ||
| 3317 | return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, | ||
| 3318 | sizeof(InquiryData_struct), 0, 0, 0, NULL, | ||
| 3319 | TYPE_CMD); | ||
| 3320 | if (return_code == IO_OK) { | ||
| 3321 | hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32]; | ||
| 3322 | hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33]; | ||
| 3323 | hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34]; | ||
| 3324 | hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35]; | ||
| 3325 | } else { /* send command failed */ | ||
| 3326 | |||
| 3327 | printk(KERN_WARNING "cciss: unable to determine firmware" | ||
| 3328 | " version of controller\n"); | ||
| 3329 | } | ||
| 3330 | /* Get the number of logical volumes */ | ||
| 3331 | return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, | ||
| 3332 | sizeof(ReportLunData_struct), 0, 0, 0, NULL, | ||
| 3333 | TYPE_CMD); | ||
| 3334 | |||
| 3335 | if (return_code == IO_OK) { | ||
| 3336 | #ifdef CCISS_DEBUG | ||
| 3337 | printk("LUN Data\n--------------------------\n"); | ||
| 3338 | #endif /* CCISS_DEBUG */ | ||
| 3339 | |||
| 3340 | listlength |= | ||
| 3341 | (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; | ||
| 3342 | listlength |= | ||
| 3343 | (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; | ||
| 3344 | listlength |= | ||
| 3345 | (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; | ||
| 3346 | listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); | ||
| 3347 | } else { /* reading number of logical volumes failed */ | ||
| 3348 | |||
| 3349 | printk(KERN_WARNING "cciss: report logical volume" | ||
| 3350 | " command failed\n"); | ||
| 3351 | listlength = 0; | ||
| 3352 | } | ||
| 3353 | hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry | ||
| 3354 | if (hba[cntl_num]->num_luns > CISS_MAX_LUN) { | ||
| 3355 | printk(KERN_ERR | ||
| 3356 | "ciss: only %d number of logical volumes supported\n", | ||
| 3357 | CISS_MAX_LUN); | ||
| 3358 | hba[cntl_num]->num_luns = CISS_MAX_LUN; | ||
| 3359 | } | ||
| 3360 | #ifdef CCISS_DEBUG | ||
| 3361 | printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", | ||
| 3362 | ld_buff->LUNListLength[0], ld_buff->LUNListLength[1], | ||
| 3363 | ld_buff->LUNListLength[2], ld_buff->LUNListLength[3], | ||
| 3364 | hba[cntl_num]->num_luns); | ||
| 3365 | #endif /* CCISS_DEBUG */ | ||
| 3366 | |||
| 3367 | hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1; | ||
| 3368 | for (i = 0; i < CISS_MAX_LUN; i++) { | ||
| 3369 | if (i < hba[cntl_num]->num_luns) { | ||
| 3370 | lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) | ||
| 3371 | << 24; | ||
| 3372 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) | ||
| 3373 | << 16; | ||
| 3374 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) | ||
| 3375 | << 8; | ||
| 3376 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | ||
| 3377 | |||
| 3378 | hba[cntl_num]->drv[i].LunID = lunid; | ||
| 3379 | |||
| 3380 | #ifdef CCISS_DEBUG | ||
| 3381 | printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i, | ||
| 3382 | ld_buff->LUN[i][0], ld_buff->LUN[i][1], | ||
| 3383 | ld_buff->LUN[i][2], ld_buff->LUN[i][3], | ||
| 3384 | hba[cntl_num]->drv[i].LunID); | ||
| 3385 | #endif /* CCISS_DEBUG */ | ||
| 3386 | |||
| 3387 | /* testing to see if 16-byte CDBs are already being used */ | ||
| 3388 | if(hba[cntl_num]->cciss_read == CCISS_READ_16) { | ||
| 3389 | cciss_read_capacity_16(cntl_num, i, 0, | ||
| 3390 | &total_size, &block_size); | ||
| 3391 | goto geo_inq; | ||
| 3392 | } | ||
| 3393 | cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size); | ||
| 3394 | |||
| 3395 | /* If read_capacity returns all F's the logical is >2TB */ | ||
| 3396 | /* so we switch to 16-byte CDBs for all read/write ops */ | ||
| 3397 | if(total_size == 0xFFFFFFFFULL) { | ||
| 3398 | cciss_read_capacity_16(cntl_num, i, 0, | ||
| 3399 | &total_size, &block_size); | ||
| 3400 | hba[cntl_num]->cciss_read = CCISS_READ_16; | ||
| 3401 | hba[cntl_num]->cciss_write = CCISS_WRITE_16; | ||
| 3402 | } else { | ||
| 3403 | hba[cntl_num]->cciss_read = CCISS_READ_10; | ||
| 3404 | hba[cntl_num]->cciss_write = CCISS_WRITE_10; | ||
| 3405 | } | ||
| 3406 | geo_inq: | ||
| 3407 | cciss_geometry_inquiry(cntl_num, i, 0, total_size, | ||
| 3408 | block_size, inq_buff, | ||
| 3409 | &hba[cntl_num]->drv[i]); | ||
| 3410 | cciss_get_serial_no(cntl_num, i, 0, | ||
| 3411 | hba[cntl_num]->drv[i].serial_no, | ||
| 3412 | sizeof(hba[cntl_num]->drv[i].serial_no)); | ||
| 3413 | } else { | ||
| 3414 | /* initialize raid_level to indicate a free space */ | ||
| 3415 | hba[cntl_num]->drv[i].raid_level = -1; | ||
| 3416 | } | ||
| 3417 | } | ||
| 3418 | kfree(ld_buff); | ||
| 3419 | kfree(inq_buff); | ||
| 3420 | } | ||
| 3421 | |||
| 3422 | /* Function to find the first free pointer into our hba[] array */ | ||
| 3423 | /* Returns -1 if no free entries are left. */ | ||
| 3424 | static int alloc_cciss_hba(void) | 3358 | static int alloc_cciss_hba(void) |
| 3425 | { | 3359 | { |
| 3426 | int i; | 3360 | int i; |
| @@ -3432,11 +3366,6 @@ static int alloc_cciss_hba(void) | |||
| 3432 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); | 3366 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); |
| 3433 | if (!p) | 3367 | if (!p) |
| 3434 | goto Enomem; | 3368 | goto Enomem; |
| 3435 | p->gendisk[0] = alloc_disk(1 << NWD_SHIFT); | ||
| 3436 | if (!p->gendisk[0]) { | ||
| 3437 | kfree(p); | ||
| 3438 | goto Enomem; | ||
| 3439 | } | ||
| 3440 | hba[i] = p; | 3369 | hba[i] = p; |
| 3441 | return i; | 3370 | return i; |
| 3442 | } | 3371 | } |
| @@ -3564,11 +3493,13 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3564 | ((hba[i]->nr_cmds + BITS_PER_LONG - | 3493 | ((hba[i]->nr_cmds + BITS_PER_LONG - |
| 3565 | 1) / BITS_PER_LONG) * sizeof(unsigned long)); | 3494 | 1) / BITS_PER_LONG) * sizeof(unsigned long)); |
| 3566 | 3495 | ||
| 3567 | #ifdef CCISS_DEBUG | 3496 | hba[i]->num_luns = 0; |
| 3568 | printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n", i); | 3497 | hba[i]->highest_lun = -1; |
| 3569 | #endif /* CCISS_DEBUG */ | 3498 | for (j = 0; j < CISS_MAX_LUN; j++) { |
| 3570 | 3499 | hba[i]->drv[j].raid_level = -1; | |
| 3571 | cciss_getgeometry(i); | 3500 | hba[i]->drv[j].queue = NULL; |
| 3501 | hba[i]->gendisk[j] = NULL; | ||
| 3502 | } | ||
| 3572 | 3503 | ||
| 3573 | cciss_scsi_setup(i); | 3504 | cciss_scsi_setup(i); |
| 3574 | 3505 | ||
| @@ -3581,76 +3512,10 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3581 | 3512 | ||
| 3582 | hba[i]->busy_initializing = 0; | 3513 | hba[i]->busy_initializing = 0; |
| 3583 | 3514 | ||
| 3584 | do { | 3515 | rebuild_lun_table(hba[i], 1); |
| 3585 | drive_info_struct *drv = &(hba[i]->drv[j]); | ||
| 3586 | struct gendisk *disk = hba[i]->gendisk[j]; | ||
| 3587 | struct request_queue *q; | ||
| 3588 | |||
| 3589 | /* Check if the disk was allocated already */ | ||
| 3590 | if (!disk){ | ||
| 3591 | hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT); | ||
| 3592 | disk = hba[i]->gendisk[j]; | ||
| 3593 | } | ||
| 3594 | |||
| 3595 | /* Check that the disk was able to be allocated */ | ||
| 3596 | if (!disk) { | ||
| 3597 | printk(KERN_ERR "cciss: unable to allocate memory for disk %d\n", j); | ||
| 3598 | goto clean4; | ||
| 3599 | } | ||
| 3600 | |||
| 3601 | q = blk_init_queue(do_cciss_request, &hba[i]->lock); | ||
| 3602 | if (!q) { | ||
| 3603 | printk(KERN_ERR | ||
| 3604 | "cciss: unable to allocate queue for disk %d\n", | ||
| 3605 | j); | ||
| 3606 | goto clean4; | ||
| 3607 | } | ||
| 3608 | drv->queue = q; | ||
| 3609 | |||
| 3610 | blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); | ||
| 3611 | |||
| 3612 | /* This is a hardware imposed limit. */ | ||
| 3613 | blk_queue_max_hw_segments(q, MAXSGENTRIES); | ||
| 3614 | |||
| 3615 | /* This is a limit in the driver and could be eliminated. */ | ||
| 3616 | blk_queue_max_phys_segments(q, MAXSGENTRIES); | ||
| 3617 | |||
| 3618 | blk_queue_max_sectors(q, hba[i]->cciss_max_sectors); | ||
| 3619 | |||
| 3620 | blk_queue_softirq_done(q, cciss_softirq_done); | ||
| 3621 | |||
| 3622 | q->queuedata = hba[i]; | ||
| 3623 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); | ||
| 3624 | disk->major = hba[i]->major; | ||
| 3625 | disk->first_minor = j << NWD_SHIFT; | ||
| 3626 | disk->fops = &cciss_fops; | ||
| 3627 | disk->queue = q; | ||
| 3628 | disk->private_data = drv; | ||
| 3629 | disk->driverfs_dev = &pdev->dev; | ||
| 3630 | /* we must register the controller even if no disks exist */ | ||
| 3631 | /* this is for the online array utilities */ | ||
| 3632 | if (!drv->heads && j) | ||
| 3633 | continue; | ||
| 3634 | blk_queue_hardsect_size(q, drv->block_size); | ||
| 3635 | set_capacity(disk, drv->nr_blocks); | ||
| 3636 | j++; | ||
| 3637 | } while (j <= hba[i]->highest_lun); | ||
| 3638 | |||
| 3639 | /* Make sure all queue data is written out before */ | ||
| 3640 | /* interrupt handler, triggered by add_disk, */ | ||
| 3641 | /* is allowed to start them. */ | ||
| 3642 | wmb(); | ||
| 3643 | |||
| 3644 | for (j = 0; j <= hba[i]->highest_lun; j++) | ||
| 3645 | add_disk(hba[i]->gendisk[j]); | ||
| 3646 | |||
| 3647 | /* we must register the controller even if no disks exist */ | ||
| 3648 | if (hba[i]->highest_lun == -1) | ||
| 3649 | add_disk(hba[i]->gendisk[0]); | ||
| 3650 | |||
| 3651 | return 1; | 3516 | return 1; |
| 3652 | 3517 | ||
| 3653 | clean4: | 3518 | clean4: |
| 3654 | #ifdef CONFIG_CISS_SCSI_TAPE | 3519 | #ifdef CONFIG_CISS_SCSI_TAPE |
| 3655 | kfree(hba[i]->scsi_rejects.complete); | 3520 | kfree(hba[i]->scsi_rejects.complete); |
| 3656 | #endif | 3521 | #endif |
| @@ -3665,9 +3530,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
| 3665 | hba[i]->errinfo_pool, | 3530 | hba[i]->errinfo_pool, |
| 3666 | hba[i]->errinfo_pool_dhandle); | 3531 | hba[i]->errinfo_pool_dhandle); |
| 3667 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); | 3532 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); |
| 3668 | clean2: | 3533 | clean2: |
| 3669 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 3534 | unregister_blkdev(hba[i]->major, hba[i]->devname); |
| 3670 | clean1: | 3535 | clean1: |
| 3671 | hba[i]->busy_initializing = 0; | 3536 | hba[i]->busy_initializing = 0; |
| 3672 | /* cleanup any queues that may have been initialized */ | 3537 | /* cleanup any queues that may have been initialized */ |
| 3673 | for (j=0; j <= hba[i]->highest_lun; j++){ | 3538 | for (j=0; j <= hba[i]->highest_lun; j++){ |
