aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/cciss_scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/cciss_scsi.c')
-rw-r--r--drivers/block/cciss_scsi.c195
1 files changed, 154 insertions, 41 deletions
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}
361struct scsi2map {
362 char scsi3addr[8];
363 int bus, target, lun;
364};
361 365
362static int 366static int
363cciss_scsi_add_entry(int ctlr, int hostno, 367cciss_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
392static void 437static void
393cciss_scsi_remove_entry(int ctlr, int hostno, int entry) 438cciss_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
470static 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
420static int 490static int
421adjust_cciss_scsi_table(int ctlr, int hostno, 491adjust_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
645free_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
1357static int 1498static int
1358cciss_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
1383static int
1384cciss_engage_scsi(int ctlr) 1499cciss_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 */