diff options
author | Mike Miller <mike.miller@hp.com> | 2008-08-04 05:54:54 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-08-06 06:30:04 -0400 |
commit | 935dc8d7575e6c1292b057e39045a40f1fbe26e7 (patch) | |
tree | d4e12f66ff7d37f97db247232c0cb4d5cabfb12f /drivers/block | |
parent | f4a93bcda74edfe6977dcf296ed8c86119638871 (diff) |
cciss: add support for multi lun tape devices
This patch adds support for multi-lun devices in a SAS environment. It's
required for the support of media changers.
Signed-off-by: Stephen M. Cameron <scameron@beardog.cca.cpqcorp.net>
Signed-off-by: Mike Miller <mike.miller@hp.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/cciss_scsi.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index c673ff14126a..e1233aabda77 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
@@ -371,16 +371,50 @@ cciss_scsi_add_entry(int ctlr, int hostno, | |||
371 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ | 371 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ |
372 | int n = ccissscsi[ctlr].ndevices; | 372 | int n = ccissscsi[ctlr].ndevices; |
373 | 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]; | ||
374 | 376 | ||
375 | if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { | 377 | if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { |
376 | printk("cciss%d: Too many devices, " | 378 | printk("cciss%d: Too many devices, " |
377 | "some will be inaccessible.\n", ctlr); | 379 | "some will be inaccessible.\n", ctlr); |
378 | return -1; | 380 | return -1; |
379 | } | 381 | } |
380 | sd = &ccissscsi[ctlr].dev[n]; | ||
381 | if (find_bus_target_lun(ctlr, &sd->bus, &sd->target, &sd->lun) != 0) | ||
382 | return -1; | ||
383 | 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 | |||
408 | sd = &ccissscsi[ctlr].dev[n]; | ||
409 | if (lun == 0) { | ||
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 | } | ||
384 | added[*nadded].bus = sd->bus; | 418 | added[*nadded].bus = sd->bus; |
385 | added[*nadded].target = sd->target; | 419 | added[*nadded].target = sd->target; |
386 | added[*nadded].lun = sd->lun; | 420 | added[*nadded].lun = sd->lun; |