diff options
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r-- | drivers/scsi/scsi_scan.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 9fa209097e3b..48edd67982a5 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -336,9 +336,23 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, unsigned long flags; const int size = sizeof(struct scsi_target) + shost->transportt->target_size; - struct scsi_target *starget = kmalloc(size, GFP_ATOMIC); + struct scsi_target *starget; struct scsi_target *found_target; + /* + * Obtain the real parent from the transport. The transport + * is allowed to fail (no error) if there is nothing at that + * target id. + */ + if (shost->transportt->target_parent) { + spin_lock_irqsave(shost->host_lock, flags); + parent = shost->transportt->target_parent(shost, channel, id); + spin_unlock_irqrestore(shost->host_lock, flags); + if (!parent) + return NULL; + } + + starget = kmalloc(size, GFP_KERNEL); if (!starget) { printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); return NULL; @@ -756,7 +770,8 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) * register it and tell the rest of the kernel * about it. */ - scsi_sysfs_add_sdev(sdev); + if (scsi_sysfs_add_sdev(sdev) != 0) + return SCSI_SCAN_NO_RESPONSE; return SCSI_SCAN_LUN_PRESENT; } @@ -1000,6 +1015,38 @@ static int scsilun_to_int(struct scsi_lun *scsilun) } /** + * int_to_scsilun: reverts an int into a scsi_lun + * @int: integer to be reverted + * @scsilun: struct scsi_lun to be set. + * + * Description: + * Reverts the functionality of the scsilun_to_int, which packed + * an 8-byte lun value into an int. This routine unpacks the int + * back into the lun value. + * Note: the scsilun_to_int() routine does not truly handle all + * 8bytes of the lun value. This functions restores only as much + * as was set by the routine. + * + * Notes: + * Given an integer : 0x0b030a04, this function returns a + * scsi_lun of : struct scsi_lun of: 0a 04 0b 03 00 00 00 00 + * + **/ +void int_to_scsilun(unsigned int lun, struct scsi_lun *scsilun) +{ + int i; + + memset(scsilun->scsi_lun, 0, sizeof(scsilun->scsi_lun)); + + for (i = 0; i < sizeof(lun); i += 2) { + scsilun->scsi_lun[i] = (lun >> 8) & 0xFF; + scsilun->scsi_lun[i+1] = lun & 0xFF; + lun = lun >> 16; + } +} +EXPORT_SYMBOL(int_to_scsilun); + +/** * scsi_report_lun_scan - Scan using SCSI REPORT LUN results * @sdevscan: scan the host, channel, and id of this Scsi_Device * |