11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * scsi_scan.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 2000 Eric Youngdale, 51da177e4SLinus Torvalds * Copyright (C) 2002 Patrick Mansfield 61da177e4SLinus Torvalds * 71da177e4SLinus Torvalds * The general scanning/probing algorithm is as follows, exceptions are 81da177e4SLinus Torvalds * made to it depending on device specific flags, compilation options, and 91da177e4SLinus Torvalds * global variable (boot or module load time) settings. 101da177e4SLinus Torvalds * 111da177e4SLinus Torvalds * A specific LUN is scanned via an INQUIRY command; if the LUN has a 121da177e4SLinus Torvalds * device attached, a Scsi_Device is allocated and setup for it. 131da177e4SLinus Torvalds * 141da177e4SLinus Torvalds * For every id of every channel on the given host: 151da177e4SLinus Torvalds * 161da177e4SLinus Torvalds * Scan LUN 0; if the target responds to LUN 0 (even if there is no 171da177e4SLinus Torvalds * device or storage attached to LUN 0): 181da177e4SLinus Torvalds * 191da177e4SLinus Torvalds * If LUN 0 has a device attached, allocate and setup a 201da177e4SLinus Torvalds * Scsi_Device for it. 211da177e4SLinus Torvalds * 221da177e4SLinus Torvalds * If target is SCSI-3 or up, issue a REPORT LUN, and scan 231da177e4SLinus Torvalds * all of the LUNs returned by the REPORT LUN; else, 241da177e4SLinus Torvalds * sequentially scan LUNs up until some maximum is reached, 251da177e4SLinus Torvalds * or a LUN is seen that cannot have a device attached to it. 261da177e4SLinus Torvalds */ 271da177e4SLinus Torvalds 281da177e4SLinus Torvalds #include <linux/config.h> 291da177e4SLinus Torvalds #include <linux/module.h> 301da177e4SLinus Torvalds #include <linux/moduleparam.h> 311da177e4SLinus Torvalds #include <linux/init.h> 321da177e4SLinus Torvalds #include <linux/blkdev.h> 331da177e4SLinus Torvalds #include <asm/semaphore.h> 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds #include <scsi/scsi.h> 361da177e4SLinus Torvalds #include <scsi/scsi_device.h> 371da177e4SLinus Torvalds #include <scsi/scsi_driver.h> 381da177e4SLinus Torvalds #include <scsi/scsi_devinfo.h> 391da177e4SLinus Torvalds #include <scsi/scsi_host.h> 401da177e4SLinus Torvalds #include <scsi/scsi_request.h> 411da177e4SLinus Torvalds #include <scsi/scsi_transport.h> 421da177e4SLinus Torvalds #include <scsi/scsi_eh.h> 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds #include "scsi_priv.h" 451da177e4SLinus Torvalds #include "scsi_logging.h" 461da177e4SLinus Torvalds 471da177e4SLinus Torvalds #define ALLOC_FAILURE_MSG KERN_ERR "%s: Allocation failure during" \ 481da177e4SLinus Torvalds " SCSI scanning, some SCSI devices might not be configured\n" 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds /* 511da177e4SLinus Torvalds * Default timeout 521da177e4SLinus Torvalds */ 531da177e4SLinus Torvalds #define SCSI_TIMEOUT (2*HZ) 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds /* 561da177e4SLinus Torvalds * Prefix values for the SCSI id's (stored in driverfs name field) 571da177e4SLinus Torvalds */ 581da177e4SLinus Torvalds #define SCSI_UID_SER_NUM 'S' 591da177e4SLinus Torvalds #define SCSI_UID_UNKNOWN 'Z' 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds /* 621da177e4SLinus Torvalds * Return values of some of the scanning functions. 631da177e4SLinus Torvalds * 641da177e4SLinus Torvalds * SCSI_SCAN_NO_RESPONSE: no valid response received from the target, this 651da177e4SLinus Torvalds * includes allocation or general failures preventing IO from being sent. 661da177e4SLinus Torvalds * 671da177e4SLinus Torvalds * SCSI_SCAN_TARGET_PRESENT: target responded, but no device is available 681da177e4SLinus Torvalds * on the given LUN. 691da177e4SLinus Torvalds * 701da177e4SLinus Torvalds * SCSI_SCAN_LUN_PRESENT: target responded, and a device is available on a 711da177e4SLinus Torvalds * given LUN. 721da177e4SLinus Torvalds */ 731da177e4SLinus Torvalds #define SCSI_SCAN_NO_RESPONSE 0 741da177e4SLinus Torvalds #define SCSI_SCAN_TARGET_PRESENT 1 751da177e4SLinus Torvalds #define SCSI_SCAN_LUN_PRESENT 2 761da177e4SLinus Torvalds 771da177e4SLinus Torvalds static char *scsi_null_device_strs = "nullnullnullnull"; 781da177e4SLinus Torvalds 791da177e4SLinus Torvalds #define MAX_SCSI_LUNS 512 801da177e4SLinus Torvalds 811da177e4SLinus Torvalds #ifdef CONFIG_SCSI_MULTI_LUN 821da177e4SLinus Torvalds static unsigned int max_scsi_luns = MAX_SCSI_LUNS; 831da177e4SLinus Torvalds #else 841da177e4SLinus Torvalds static unsigned int max_scsi_luns = 1; 851da177e4SLinus Torvalds #endif 861da177e4SLinus Torvalds 871da177e4SLinus Torvalds module_param_named(max_luns, max_scsi_luns, int, S_IRUGO|S_IWUSR); 881da177e4SLinus Torvalds MODULE_PARM_DESC(max_luns, 891da177e4SLinus Torvalds "last scsi LUN (should be between 1 and 2^32-1)"); 901da177e4SLinus Torvalds 911da177e4SLinus Torvalds /* 921da177e4SLinus Torvalds * max_scsi_report_luns: the maximum number of LUNS that will be 931da177e4SLinus Torvalds * returned from the REPORT LUNS command. 8 times this value must 941da177e4SLinus Torvalds * be allocated. In theory this could be up to an 8 byte value, but 951da177e4SLinus Torvalds * in practice, the maximum number of LUNs suppored by any device 961da177e4SLinus Torvalds * is about 16k. 971da177e4SLinus Torvalds */ 981da177e4SLinus Torvalds static unsigned int max_scsi_report_luns = 511; 991da177e4SLinus Torvalds 1001da177e4SLinus Torvalds module_param_named(max_report_luns, max_scsi_report_luns, int, S_IRUGO|S_IWUSR); 1011da177e4SLinus Torvalds MODULE_PARM_DESC(max_report_luns, 1021da177e4SLinus Torvalds "REPORT LUNS maximum number of LUNS received (should be" 1031da177e4SLinus Torvalds " between 1 and 16384)"); 1041da177e4SLinus Torvalds 1051da177e4SLinus Torvalds static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ+3; 1061da177e4SLinus Torvalds 1071da177e4SLinus Torvalds module_param_named(inq_timeout, scsi_inq_timeout, int, S_IRUGO|S_IWUSR); 1081da177e4SLinus Torvalds MODULE_PARM_DESC(inq_timeout, 1091da177e4SLinus Torvalds "Timeout (in seconds) waiting for devices to answer INQUIRY." 1101da177e4SLinus Torvalds " Default is 5. Some non-compliant devices need more."); 1111da177e4SLinus Torvalds 1121da177e4SLinus Torvalds /** 1131da177e4SLinus Torvalds * scsi_unlock_floptical - unlock device via a special MODE SENSE command 1141da177e4SLinus Torvalds * @sreq: used to send the command 1151da177e4SLinus Torvalds * @result: area to store the result of the MODE SENSE 1161da177e4SLinus Torvalds * 1171da177e4SLinus Torvalds * Description: 1181da177e4SLinus Torvalds * Send a vendor specific MODE SENSE (not a MODE SELECT) command using 1191da177e4SLinus Torvalds * @sreq to unlock a device, storing the (unused) results into result. 1201da177e4SLinus Torvalds * Called for BLIST_KEY devices. 1211da177e4SLinus Torvalds **/ 1221da177e4SLinus Torvalds static void scsi_unlock_floptical(struct scsi_request *sreq, 1231da177e4SLinus Torvalds unsigned char *result) 1241da177e4SLinus Torvalds { 1251da177e4SLinus Torvalds unsigned char scsi_cmd[MAX_COMMAND_SIZE]; 1261da177e4SLinus Torvalds 1271da177e4SLinus Torvalds printk(KERN_NOTICE "scsi: unlocking floptical drive\n"); 1281da177e4SLinus Torvalds scsi_cmd[0] = MODE_SENSE; 1291da177e4SLinus Torvalds scsi_cmd[1] = 0; 1301da177e4SLinus Torvalds scsi_cmd[2] = 0x2e; 1311da177e4SLinus Torvalds scsi_cmd[3] = 0; 1321da177e4SLinus Torvalds scsi_cmd[4] = 0x2a; /* size */ 1331da177e4SLinus Torvalds scsi_cmd[5] = 0; 1341da177e4SLinus Torvalds sreq->sr_cmd_len = 0; 1351da177e4SLinus Torvalds sreq->sr_data_direction = DMA_FROM_DEVICE; 1361da177e4SLinus Torvalds scsi_wait_req(sreq, scsi_cmd, result, 0x2a /* size */, SCSI_TIMEOUT, 3); 1371da177e4SLinus Torvalds } 1381da177e4SLinus Torvalds 1391da177e4SLinus Torvalds /** 1401da177e4SLinus Torvalds * print_inquiry - printk the inquiry information 1411da177e4SLinus Torvalds * @inq_result: printk this SCSI INQUIRY 1421da177e4SLinus Torvalds * 1431da177e4SLinus Torvalds * Description: 1441da177e4SLinus Torvalds * printk the vendor, model, and other information found in the 1451da177e4SLinus Torvalds * INQUIRY data in @inq_result. 1461da177e4SLinus Torvalds * 1471da177e4SLinus Torvalds * Notes: 1481da177e4SLinus Torvalds * Remove this, and replace with a hotplug event that logs any 1491da177e4SLinus Torvalds * relevant information. 1501da177e4SLinus Torvalds **/ 1511da177e4SLinus Torvalds static void print_inquiry(unsigned char *inq_result) 1521da177e4SLinus Torvalds { 1531da177e4SLinus Torvalds int i; 1541da177e4SLinus Torvalds 1551da177e4SLinus Torvalds printk(KERN_NOTICE " Vendor: "); 1561da177e4SLinus Torvalds for (i = 8; i < 16; i++) 1571da177e4SLinus Torvalds if (inq_result[i] >= 0x20 && i < inq_result[4] + 5) 1581da177e4SLinus Torvalds printk("%c", inq_result[i]); 1591da177e4SLinus Torvalds else 1601da177e4SLinus Torvalds printk(" "); 1611da177e4SLinus Torvalds 1621da177e4SLinus Torvalds printk(" Model: "); 1631da177e4SLinus Torvalds for (i = 16; i < 32; i++) 1641da177e4SLinus Torvalds if (inq_result[i] >= 0x20 && i < inq_result[4] + 5) 1651da177e4SLinus Torvalds printk("%c", inq_result[i]); 1661da177e4SLinus Torvalds else 1671da177e4SLinus Torvalds printk(" "); 1681da177e4SLinus Torvalds 1691da177e4SLinus Torvalds printk(" Rev: "); 1701da177e4SLinus Torvalds for (i = 32; i < 36; i++) 1711da177e4SLinus Torvalds if (inq_result[i] >= 0x20 && i < inq_result[4] + 5) 1721da177e4SLinus Torvalds printk("%c", inq_result[i]); 1731da177e4SLinus Torvalds else 1741da177e4SLinus Torvalds printk(" "); 1751da177e4SLinus Torvalds 1761da177e4SLinus Torvalds printk("\n"); 1771da177e4SLinus Torvalds 1781da177e4SLinus Torvalds i = inq_result[0] & 0x1f; 1791da177e4SLinus Torvalds 1801da177e4SLinus Torvalds printk(KERN_NOTICE " Type: %s ", 1811da177e4SLinus Torvalds i < 1821da177e4SLinus Torvalds MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] : 1831da177e4SLinus Torvalds "Unknown "); 1841da177e4SLinus Torvalds printk(" ANSI SCSI revision: %02x", 1851da177e4SLinus Torvalds inq_result[2] & 0x07); 1861da177e4SLinus Torvalds if ((inq_result[2] & 0x07) == 1 && (inq_result[3] & 0x0f) == 1) 1871da177e4SLinus Torvalds printk(" CCS\n"); 1881da177e4SLinus Torvalds else 1891da177e4SLinus Torvalds printk("\n"); 1901da177e4SLinus Torvalds } 1911da177e4SLinus Torvalds 1921da177e4SLinus Torvalds /** 1931da177e4SLinus Torvalds * scsi_alloc_sdev - allocate and setup a scsi_Device 1941da177e4SLinus Torvalds * 1951da177e4SLinus Torvalds * Description: 1961da177e4SLinus Torvalds * Allocate, initialize for io, and return a pointer to a scsi_Device. 1971da177e4SLinus Torvalds * Stores the @shost, @channel, @id, and @lun in the scsi_Device, and 1981da177e4SLinus Torvalds * adds scsi_Device to the appropriate list. 1991da177e4SLinus Torvalds * 2001da177e4SLinus Torvalds * Return value: 2011da177e4SLinus Torvalds * scsi_Device pointer, or NULL on failure. 2021da177e4SLinus Torvalds **/ 2031da177e4SLinus Torvalds static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, 2041da177e4SLinus Torvalds unsigned int lun, void *hostdata) 2051da177e4SLinus Torvalds { 2061da177e4SLinus Torvalds struct scsi_device *sdev; 2071da177e4SLinus Torvalds int display_failure_msg = 1, ret; 2081da177e4SLinus Torvalds struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 2091da177e4SLinus Torvalds 2101da177e4SLinus Torvalds sdev = kmalloc(sizeof(*sdev) + shost->transportt->device_size, 2111da177e4SLinus Torvalds GFP_ATOMIC); 2121da177e4SLinus Torvalds if (!sdev) 2131da177e4SLinus Torvalds goto out; 2141da177e4SLinus Torvalds 2151da177e4SLinus Torvalds memset(sdev, 0, sizeof(*sdev)); 2161da177e4SLinus Torvalds sdev->vendor = scsi_null_device_strs; 2171da177e4SLinus Torvalds sdev->model = scsi_null_device_strs; 2181da177e4SLinus Torvalds sdev->rev = scsi_null_device_strs; 2191da177e4SLinus Torvalds sdev->host = shost; 2201da177e4SLinus Torvalds sdev->id = starget->id; 2211da177e4SLinus Torvalds sdev->lun = lun; 2221da177e4SLinus Torvalds sdev->channel = starget->channel; 2231da177e4SLinus Torvalds sdev->sdev_state = SDEV_CREATED; 2241da177e4SLinus Torvalds INIT_LIST_HEAD(&sdev->siblings); 2251da177e4SLinus Torvalds INIT_LIST_HEAD(&sdev->same_target_siblings); 2261da177e4SLinus Torvalds INIT_LIST_HEAD(&sdev->cmd_list); 2271da177e4SLinus Torvalds INIT_LIST_HEAD(&sdev->starved_entry); 2281da177e4SLinus Torvalds spin_lock_init(&sdev->list_lock); 2291da177e4SLinus Torvalds 2301da177e4SLinus Torvalds sdev->sdev_gendev.parent = get_device(&starget->dev); 2311da177e4SLinus Torvalds sdev->sdev_target = starget; 2321da177e4SLinus Torvalds 2331da177e4SLinus Torvalds /* usually NULL and set by ->slave_alloc instead */ 2341da177e4SLinus Torvalds sdev->hostdata = hostdata; 2351da177e4SLinus Torvalds 2361da177e4SLinus Torvalds /* if the device needs this changing, it may do so in the 2371da177e4SLinus Torvalds * slave_configure function */ 2381da177e4SLinus Torvalds sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED; 2391da177e4SLinus Torvalds 2401da177e4SLinus Torvalds /* 2411da177e4SLinus Torvalds * Some low level driver could use device->type 2421da177e4SLinus Torvalds */ 2431da177e4SLinus Torvalds sdev->type = -1; 2441da177e4SLinus Torvalds 2451da177e4SLinus Torvalds /* 2461da177e4SLinus Torvalds * Assume that the device will have handshaking problems, 2471da177e4SLinus Torvalds * and then fix this field later if it turns out it 2481da177e4SLinus Torvalds * doesn't 2491da177e4SLinus Torvalds */ 2501da177e4SLinus Torvalds sdev->borken = 1; 2511da177e4SLinus Torvalds 2521da177e4SLinus Torvalds sdev->request_queue = scsi_alloc_queue(sdev); 2531da177e4SLinus Torvalds if (!sdev->request_queue) { 2541da177e4SLinus Torvalds /* release fn is set up in scsi_sysfs_device_initialise, so 2551da177e4SLinus Torvalds * have to free and put manually here */ 2561da177e4SLinus Torvalds put_device(&starget->dev); 2571da177e4SLinus Torvalds goto out; 2581da177e4SLinus Torvalds } 2591da177e4SLinus Torvalds 2601da177e4SLinus Torvalds sdev->request_queue->queuedata = sdev; 2611da177e4SLinus Torvalds scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); 2621da177e4SLinus Torvalds 2631da177e4SLinus Torvalds scsi_sysfs_device_initialize(sdev); 2641da177e4SLinus Torvalds 2651da177e4SLinus Torvalds if (shost->hostt->slave_alloc) { 2661da177e4SLinus Torvalds ret = shost->hostt->slave_alloc(sdev); 2671da177e4SLinus Torvalds if (ret) { 2681da177e4SLinus Torvalds /* 2691da177e4SLinus Torvalds * if LLDD reports slave not present, don't clutter 2701da177e4SLinus Torvalds * console with alloc failure messages 2711da177e4SLinus Torvalds 2721da177e4SLinus Torvalds 2731da177e4SLinus Torvalds */ 2741da177e4SLinus Torvalds if (ret == -ENXIO) 2751da177e4SLinus Torvalds display_failure_msg = 0; 2761da177e4SLinus Torvalds goto out_device_destroy; 2771da177e4SLinus Torvalds } 2781da177e4SLinus Torvalds } 2791da177e4SLinus Torvalds 2801da177e4SLinus Torvalds return sdev; 2811da177e4SLinus Torvalds 2821da177e4SLinus Torvalds out_device_destroy: 2831da177e4SLinus Torvalds transport_destroy_device(&sdev->sdev_gendev); 2841da177e4SLinus Torvalds scsi_free_queue(sdev->request_queue); 2851da177e4SLinus Torvalds put_device(&sdev->sdev_gendev); 2861da177e4SLinus Torvalds out: 2871da177e4SLinus Torvalds if (display_failure_msg) 2881da177e4SLinus Torvalds printk(ALLOC_FAILURE_MSG, __FUNCTION__); 2891da177e4SLinus Torvalds return NULL; 2901da177e4SLinus Torvalds } 2911da177e4SLinus Torvalds 2921da177e4SLinus Torvalds static void scsi_target_dev_release(struct device *dev) 2931da177e4SLinus Torvalds { 2941da177e4SLinus Torvalds struct device *parent = dev->parent; 2951da177e4SLinus Torvalds struct scsi_target *starget = to_scsi_target(dev); 2961da177e4SLinus Torvalds kfree(starget); 2971da177e4SLinus Torvalds put_device(parent); 2981da177e4SLinus Torvalds } 2991da177e4SLinus Torvalds 3001da177e4SLinus Torvalds int scsi_is_target_device(const struct device *dev) 3011da177e4SLinus Torvalds { 3021da177e4SLinus Torvalds return dev->release == scsi_target_dev_release; 3031da177e4SLinus Torvalds } 3041da177e4SLinus Torvalds EXPORT_SYMBOL(scsi_is_target_device); 3051da177e4SLinus Torvalds 3061da177e4SLinus Torvalds static struct scsi_target *__scsi_find_target(struct device *parent, 3071da177e4SLinus Torvalds int channel, uint id) 3081da177e4SLinus Torvalds { 3091da177e4SLinus Torvalds struct scsi_target *starget, *found_starget = NULL; 3101da177e4SLinus Torvalds struct Scsi_Host *shost = dev_to_shost(parent); 3111da177e4SLinus Torvalds /* 3121da177e4SLinus Torvalds * Search for an existing target for this sdev. 3131da177e4SLinus Torvalds */ 3141da177e4SLinus Torvalds list_for_each_entry(starget, &shost->__targets, siblings) { 3151da177e4SLinus Torvalds if (starget->id == id && 3161da177e4SLinus Torvalds starget->channel == channel) { 3171da177e4SLinus Torvalds found_starget = starget; 3181da177e4SLinus Torvalds break; 3191da177e4SLinus Torvalds } 3201da177e4SLinus Torvalds } 3211da177e4SLinus Torvalds if (found_starget) 3221da177e4SLinus Torvalds get_device(&found_starget->dev); 3231da177e4SLinus Torvalds 3241da177e4SLinus Torvalds return found_starget; 3251da177e4SLinus Torvalds } 3261da177e4SLinus Torvalds 3271da177e4SLinus Torvalds static struct scsi_target *scsi_alloc_target(struct device *parent, 3281da177e4SLinus Torvalds int channel, uint id) 3291da177e4SLinus Torvalds { 3301da177e4SLinus Torvalds struct Scsi_Host *shost = dev_to_shost(parent); 3311da177e4SLinus Torvalds struct device *dev = NULL; 3321da177e4SLinus Torvalds unsigned long flags; 3331da177e4SLinus Torvalds const int size = sizeof(struct scsi_target) 3341da177e4SLinus Torvalds + shost->transportt->target_size; 3351da177e4SLinus Torvalds struct scsi_target *starget = kmalloc(size, GFP_ATOMIC); 3361da177e4SLinus Torvalds struct scsi_target *found_target; 3371da177e4SLinus Torvalds 3381da177e4SLinus Torvalds if (!starget) { 3391da177e4SLinus Torvalds printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); 3401da177e4SLinus Torvalds return NULL; 3411da177e4SLinus Torvalds } 3421da177e4SLinus Torvalds memset(starget, 0, size); 3431da177e4SLinus Torvalds dev = &starget->dev; 3441da177e4SLinus Torvalds device_initialize(dev); 3451da177e4SLinus Torvalds starget->reap_ref = 1; 3461da177e4SLinus Torvalds dev->parent = get_device(parent); 3471da177e4SLinus Torvalds dev->release = scsi_target_dev_release; 3481da177e4SLinus Torvalds sprintf(dev->bus_id, "target%d:%d:%d", 3491da177e4SLinus Torvalds shost->host_no, channel, id); 3501da177e4SLinus Torvalds starget->id = id; 3511da177e4SLinus Torvalds starget->channel = channel; 3521da177e4SLinus Torvalds INIT_LIST_HEAD(&starget->siblings); 3531da177e4SLinus Torvalds INIT_LIST_HEAD(&starget->devices); 3541da177e4SLinus Torvalds spin_lock_irqsave(shost->host_lock, flags); 3551da177e4SLinus Torvalds 3561da177e4SLinus Torvalds found_target = __scsi_find_target(parent, channel, id); 3571da177e4SLinus Torvalds if (found_target) 3581da177e4SLinus Torvalds goto found; 3591da177e4SLinus Torvalds 3601da177e4SLinus Torvalds list_add_tail(&starget->siblings, &shost->__targets); 3611da177e4SLinus Torvalds spin_unlock_irqrestore(shost->host_lock, flags); 3621da177e4SLinus Torvalds /* allocate and add */ 3631da177e4SLinus Torvalds transport_setup_device(&starget->dev); 3641da177e4SLinus Torvalds device_add(&starget->dev); 3651da177e4SLinus Torvalds transport_add_device(&starget->dev); 3661da177e4SLinus Torvalds return starget; 3671da177e4SLinus Torvalds 3681da177e4SLinus Torvalds found: 3691da177e4SLinus Torvalds found_target->reap_ref++; 3701da177e4SLinus Torvalds spin_unlock_irqrestore(shost->host_lock, flags); 3711da177e4SLinus Torvalds put_device(parent); 3721da177e4SLinus Torvalds kfree(starget); 3731da177e4SLinus Torvalds return found_target; 3741da177e4SLinus Torvalds } 3751da177e4SLinus Torvalds 3761da177e4SLinus Torvalds /** 3771da177e4SLinus Torvalds * scsi_target_reap - check to see if target is in use and destroy if not 3781da177e4SLinus Torvalds * 3791da177e4SLinus Torvalds * @starget: target to be checked 3801da177e4SLinus Torvalds * 3811da177e4SLinus Torvalds * This is used after removing a LUN or doing a last put of the target 3821da177e4SLinus Torvalds * it checks atomically that nothing is using the target and removes 3831da177e4SLinus Torvalds * it if so. 3841da177e4SLinus Torvalds */ 3851da177e4SLinus Torvalds void scsi_target_reap(struct scsi_target *starget) 3861da177e4SLinus Torvalds { 3871da177e4SLinus Torvalds struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 3881da177e4SLinus Torvalds unsigned long flags; 3891da177e4SLinus Torvalds spin_lock_irqsave(shost->host_lock, flags); 3901da177e4SLinus Torvalds 3911da177e4SLinus Torvalds if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { 3921da177e4SLinus Torvalds list_del_init(&starget->siblings); 3931da177e4SLinus Torvalds spin_unlock_irqrestore(shost->host_lock, flags); 3941da177e4SLinus Torvalds device_del(&starget->dev); 3951da177e4SLinus Torvalds transport_unregister_device(&starget->dev); 3961da177e4SLinus Torvalds put_device(&starget->dev); 3971da177e4SLinus Torvalds return; 3981da177e4SLinus Torvalds } 3991da177e4SLinus Torvalds spin_unlock_irqrestore(shost->host_lock, flags); 4001da177e4SLinus Torvalds } 4011da177e4SLinus Torvalds 4021da177e4SLinus Torvalds /** 4031da177e4SLinus Torvalds * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY 4041da177e4SLinus Torvalds * @sreq: used to send the INQUIRY 4051da177e4SLinus Torvalds * @inq_result: area to store the INQUIRY result 4061da177e4SLinus Torvalds * @bflags: store any bflags found here 4071da177e4SLinus Torvalds * 4081da177e4SLinus Torvalds * Description: 4091da177e4SLinus Torvalds * Probe the lun associated with @sreq using a standard SCSI INQUIRY; 4101da177e4SLinus Torvalds * 4111da177e4SLinus Torvalds * If the INQUIRY is successful, sreq->sr_result is zero and: the 4121da177e4SLinus Torvalds * INQUIRY data is in @inq_result; the scsi_level and INQUIRY length 4131da177e4SLinus Torvalds * are copied to the Scsi_Device at @sreq->sr_device (sdev); 4141da177e4SLinus Torvalds * any flags value is stored in *@bflags. 4151da177e4SLinus Torvalds **/ 4161da177e4SLinus Torvalds static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result, 4171da177e4SLinus Torvalds int *bflags) 4181da177e4SLinus Torvalds { 4191da177e4SLinus Torvalds struct scsi_device *sdev = sreq->sr_device; /* a bit ugly */ 4201da177e4SLinus Torvalds unsigned char scsi_cmd[MAX_COMMAND_SIZE]; 4211da177e4SLinus Torvalds int first_inquiry_len, try_inquiry_len, next_inquiry_len; 4221da177e4SLinus Torvalds int response_len = 0; 4231da177e4SLinus Torvalds int pass, count; 4241da177e4SLinus Torvalds struct scsi_sense_hdr sshdr; 4251da177e4SLinus Torvalds 4261da177e4SLinus Torvalds *bflags = 0; 4271da177e4SLinus Torvalds 4281da177e4SLinus Torvalds /* Perform up to 3 passes. The first pass uses a conservative 4291da177e4SLinus Torvalds * transfer length of 36 unless sdev->inquiry_len specifies a 4301da177e4SLinus Torvalds * different value. */ 4311da177e4SLinus Torvalds first_inquiry_len = sdev->inquiry_len ? sdev->inquiry_len : 36; 4321da177e4SLinus Torvalds try_inquiry_len = first_inquiry_len; 4331da177e4SLinus Torvalds pass = 1; 4341da177e4SLinus Torvalds 4351da177e4SLinus Torvalds next_pass: 4361da177e4SLinus Torvalds SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY pass %d " 4371da177e4SLinus Torvalds "to host %d channel %d id %d lun %d, length %d\n", 4381da177e4SLinus Torvalds pass, sdev->host->host_no, sdev->channel, 4391da177e4SLinus Torvalds sdev->id, sdev->lun, try_inquiry_len)); 4401da177e4SLinus Torvalds 4411da177e4SLinus Torvalds /* Each pass gets up to three chances to ignore Unit Attention */ 4421da177e4SLinus Torvalds for (count = 0; count < 3; ++count) { 4431da177e4SLinus Torvalds memset(scsi_cmd, 0, 6); 4441da177e4SLinus Torvalds scsi_cmd[0] = INQUIRY; 4451da177e4SLinus Torvalds scsi_cmd[4] = (unsigned char) try_inquiry_len; 4461da177e4SLinus Torvalds sreq->sr_cmd_len = 0; 4471da177e4SLinus Torvalds sreq->sr_data_direction = DMA_FROM_DEVICE; 4481da177e4SLinus Torvalds 4491da177e4SLinus Torvalds memset(inq_result, 0, try_inquiry_len); 4501da177e4SLinus Torvalds scsi_wait_req(sreq, (void *) scsi_cmd, (void *) inq_result, 4511da177e4SLinus Torvalds try_inquiry_len, 4521da177e4SLinus Torvalds HZ/2 + HZ*scsi_inq_timeout, 3); 4531da177e4SLinus Torvalds 4541da177e4SLinus Torvalds SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s " 4551da177e4SLinus Torvalds "with code 0x%x\n", 4561da177e4SLinus Torvalds sreq->sr_result ? "failed" : "successful", 4571da177e4SLinus Torvalds sreq->sr_result)); 4581da177e4SLinus Torvalds 4591da177e4SLinus Torvalds if (sreq->sr_result) { 4601da177e4SLinus Torvalds /* 4611da177e4SLinus Torvalds * not-ready to ready transition [asc/ascq=0x28/0x0] 4621da177e4SLinus Torvalds * or power-on, reset [asc/ascq=0x29/0x0], continue. 4631da177e4SLinus Torvalds * INQUIRY should not yield UNIT_ATTENTION 4641da177e4SLinus Torvalds * but many buggy devices do so anyway. 4651da177e4SLinus Torvalds */ 4661da177e4SLinus Torvalds if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) && 4671da177e4SLinus Torvalds scsi_request_normalize_sense(sreq, &sshdr)) { 4681da177e4SLinus Torvalds if ((sshdr.sense_key == UNIT_ATTENTION) && 4691da177e4SLinus Torvalds ((sshdr.asc == 0x28) || 4701da177e4SLinus Torvalds (sshdr.asc == 0x29)) && 4711da177e4SLinus Torvalds (sshdr.ascq == 0)) 4721da177e4SLinus Torvalds continue; 4731da177e4SLinus Torvalds } 4741da177e4SLinus Torvalds } 4751da177e4SLinus Torvalds break; 4761da177e4SLinus Torvalds } 4771da177e4SLinus Torvalds 4781da177e4SLinus Torvalds if (sreq->sr_result == 0) { 4791da177e4SLinus Torvalds response_len = (unsigned char) inq_result[4] + 5; 4801da177e4SLinus Torvalds if (response_len > 255) 4811da177e4SLinus Torvalds response_len = first_inquiry_len; /* sanity */ 4821da177e4SLinus Torvalds 4831da177e4SLinus Torvalds /* 4841da177e4SLinus Torvalds * Get any flags for this device. 4851da177e4SLinus Torvalds * 4861da177e4SLinus Torvalds * XXX add a bflags to Scsi_Device, and replace the 4871da177e4SLinus Torvalds * corresponding bit fields in Scsi_Device, so bflags 4881da177e4SLinus Torvalds * need not be passed as an argument. 4891da177e4SLinus Torvalds */ 4901da177e4SLinus Torvalds *bflags = scsi_get_device_flags(sdev, &inq_result[8], 4911da177e4SLinus Torvalds &inq_result[16]); 4921da177e4SLinus Torvalds 4931da177e4SLinus Torvalds /* When the first pass succeeds we gain information about 4941da177e4SLinus Torvalds * what larger transfer lengths might work. */ 4951da177e4SLinus Torvalds if (pass == 1) { 4961da177e4SLinus Torvalds if (BLIST_INQUIRY_36 & *bflags) 4971da177e4SLinus Torvalds next_inquiry_len = 36; 4981da177e4SLinus Torvalds else if (BLIST_INQUIRY_58 & *bflags) 4991da177e4SLinus Torvalds next_inquiry_len = 58; 5001da177e4SLinus Torvalds else if (sdev->inquiry_len) 5011da177e4SLinus Torvalds next_inquiry_len = sdev->inquiry_len; 5021da177e4SLinus Torvalds else 5031da177e4SLinus Torvalds next_inquiry_len = response_len; 5041da177e4SLinus Torvalds 5051da177e4SLinus Torvalds /* If more data is available perform the second pass */ 5061da177e4SLinus Torvalds if (next_inquiry_len > try_inquiry_len) { 5071da177e4SLinus Torvalds try_inquiry_len = next_inquiry_len; 5081da177e4SLinus Torvalds pass = 2; 5091da177e4SLinus Torvalds goto next_pass; 5101da177e4SLinus Torvalds } 5111da177e4SLinus Torvalds } 5121da177e4SLinus Torvalds 5131da177e4SLinus Torvalds } else if (pass == 2) { 5141da177e4SLinus Torvalds printk(KERN_INFO "scsi scan: %d byte inquiry failed. " 5151da177e4SLinus Torvalds "Consider BLIST_INQUIRY_36 for this device\n", 5161da177e4SLinus Torvalds try_inquiry_len); 5171da177e4SLinus Torvalds 5181da177e4SLinus Torvalds /* If this pass failed, the third pass goes back and transfers 5191da177e4SLinus Torvalds * the same amount as we successfully got in the first pass. */ 5201da177e4SLinus Torvalds try_inquiry_len = first_inquiry_len; 5211da177e4SLinus Torvalds pass = 3; 5221da177e4SLinus Torvalds goto next_pass; 5231da177e4SLinus Torvalds } 5241da177e4SLinus Torvalds 5251da177e4SLinus Torvalds /* If the last transfer attempt got an error, assume the 5261da177e4SLinus Torvalds * peripheral doesn't exist or is dead. */ 5271da177e4SLinus Torvalds if (sreq->sr_result) 5281da177e4SLinus Torvalds return; 5291da177e4SLinus Torvalds 5301da177e4SLinus Torvalds /* Don't report any more data than the device says is valid */ 5311da177e4SLinus Torvalds sdev->inquiry_len = min(try_inquiry_len, response_len); 5321da177e4SLinus Torvalds 5331da177e4SLinus Torvalds /* 5341da177e4SLinus Torvalds * XXX Abort if the response length is less than 36? If less than 5351da177e4SLinus Torvalds * 32, the lookup of the device flags (above) could be invalid, 5361da177e4SLinus Torvalds * and it would be possible to take an incorrect action - we do 5371da177e4SLinus Torvalds * not want to hang because of a short INQUIRY. On the flip side, 5381da177e4SLinus Torvalds * if the device is spun down or becoming ready (and so it gives a 5391da177e4SLinus Torvalds * short INQUIRY), an abort here prevents any further use of the 5401da177e4SLinus Torvalds * device, including spin up. 5411da177e4SLinus Torvalds * 5421da177e4SLinus Torvalds * Related to the above issue: 5431da177e4SLinus Torvalds * 5441da177e4SLinus Torvalds * XXX Devices (disk or all?) should be sent a TEST UNIT READY, 5451da177e4SLinus Torvalds * and if not ready, sent a START_STOP to start (maybe spin up) and 5461da177e4SLinus Torvalds * then send the INQUIRY again, since the INQUIRY can change after 5471da177e4SLinus Torvalds * a device is initialized. 5481da177e4SLinus Torvalds * 5491da177e4SLinus Torvalds * Ideally, start a device if explicitly asked to do so. This 5501da177e4SLinus Torvalds * assumes that a device is spun up on power on, spun down on 5511da177e4SLinus Torvalds * request, and then spun up on request. 5521da177e4SLinus Torvalds */ 5531da177e4SLinus Torvalds 5541da177e4SLinus Torvalds /* 5551da177e4SLinus Torvalds * The scanning code needs to know the scsi_level, even if no 5561da177e4SLinus Torvalds * device is attached at LUN 0 (SCSI_SCAN_TARGET_PRESENT) so 5571da177e4SLinus Torvalds * non-zero LUNs can be scanned. 5581da177e4SLinus Torvalds */ 5591da177e4SLinus Torvalds sdev->scsi_level = inq_result[2] & 0x07; 5601da177e4SLinus Torvalds if (sdev->scsi_level >= 2 || 5611da177e4SLinus Torvalds (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1)) 5621da177e4SLinus Torvalds sdev->scsi_level++; 5631da177e4SLinus Torvalds 5641da177e4SLinus Torvalds return; 5651da177e4SLinus Torvalds } 5661da177e4SLinus Torvalds 5671da177e4SLinus Torvalds /** 5681da177e4SLinus Torvalds * scsi_add_lun - allocate and fully initialze a Scsi_Device 5691da177e4SLinus Torvalds * @sdevscan: holds information to be stored in the new Scsi_Device 5701da177e4SLinus Torvalds * @sdevnew: store the address of the newly allocated Scsi_Device 5711da177e4SLinus Torvalds * @inq_result: holds the result of a previous INQUIRY to the LUN 5721da177e4SLinus Torvalds * @bflags: black/white list flag 5731da177e4SLinus Torvalds * 5741da177e4SLinus Torvalds * Description: 5751da177e4SLinus Torvalds * Allocate and initialize a Scsi_Device matching sdevscan. Optionally 5761da177e4SLinus Torvalds * set fields based on values in *@bflags. If @sdevnew is not 5771da177e4SLinus Torvalds * NULL, store the address of the new Scsi_Device in *@sdevnew (needed 5781da177e4SLinus Torvalds * when scanning a particular LUN). 5791da177e4SLinus Torvalds * 5801da177e4SLinus Torvalds * Return: 5811da177e4SLinus Torvalds * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a Scsi_Device 5821da177e4SLinus Torvalds * SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized 5831da177e4SLinus Torvalds **/ 5841da177e4SLinus Torvalds static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) 5851da177e4SLinus Torvalds { 5861da177e4SLinus Torvalds /* 5871da177e4SLinus Torvalds * XXX do not save the inquiry, since it can change underneath us, 5881da177e4SLinus Torvalds * save just vendor/model/rev. 5891da177e4SLinus Torvalds * 5901da177e4SLinus Torvalds * Rather than save it and have an ioctl that retrieves the saved 5911da177e4SLinus Torvalds * value, have an ioctl that executes the same INQUIRY code used 5921da177e4SLinus Torvalds * in scsi_probe_lun, let user level programs doing INQUIRY 5931da177e4SLinus Torvalds * scanning run at their own risk, or supply a user level program 5941da177e4SLinus Torvalds * that can correctly scan. 5951da177e4SLinus Torvalds */ 5961da177e4SLinus Torvalds sdev->inquiry = kmalloc(sdev->inquiry_len, GFP_ATOMIC); 5971da177e4SLinus Torvalds if (sdev->inquiry == NULL) { 5981da177e4SLinus Torvalds return SCSI_SCAN_NO_RESPONSE; 5991da177e4SLinus Torvalds } 6001da177e4SLinus Torvalds 6011da177e4SLinus Torvalds memcpy(sdev->inquiry, inq_result, sdev->inquiry_len); 6021da177e4SLinus Torvalds sdev->vendor = (char *) (sdev->inquiry + 8); 6031da177e4SLinus Torvalds sdev->model = (char *) (sdev->inquiry + 16); 6041da177e4SLinus Torvalds sdev->rev = (char *) (sdev->inquiry + 32); 6051da177e4SLinus Torvalds 6061da177e4SLinus Torvalds if (*bflags & BLIST_ISROM) { 6071da177e4SLinus Torvalds /* 6081da177e4SLinus Torvalds * It would be better to modify sdev->type, and set 6091da177e4SLinus Torvalds * sdev->removable, but then the print_inquiry() output 6101da177e4SLinus Torvalds * would not show TYPE_ROM; if print_inquiry() is removed 6111da177e4SLinus Torvalds * the issue goes away. 6121da177e4SLinus Torvalds */ 6131da177e4SLinus Torvalds inq_result[0] = TYPE_ROM; 6141da177e4SLinus Torvalds inq_result[1] |= 0x80; /* removable */ 6151da177e4SLinus Torvalds } else if (*bflags & BLIST_NO_ULD_ATTACH) 6161da177e4SLinus Torvalds sdev->no_uld_attach = 1; 6171da177e4SLinus Torvalds 6181da177e4SLinus Torvalds switch (sdev->type = (inq_result[0] & 0x1f)) { 6191da177e4SLinus Torvalds case TYPE_TAPE: 6201da177e4SLinus Torvalds case TYPE_DISK: 6211da177e4SLinus Torvalds case TYPE_PRINTER: 6221da177e4SLinus Torvalds case TYPE_MOD: 6231da177e4SLinus Torvalds case TYPE_PROCESSOR: 6241da177e4SLinus Torvalds case TYPE_SCANNER: 6251da177e4SLinus Torvalds case TYPE_MEDIUM_CHANGER: 6261da177e4SLinus Torvalds case TYPE_ENCLOSURE: 6271da177e4SLinus Torvalds case TYPE_COMM: 6281da177e4SLinus Torvalds sdev->writeable = 1; 6291da177e4SLinus Torvalds break; 6301da177e4SLinus Torvalds case TYPE_WORM: 6311da177e4SLinus Torvalds case TYPE_ROM: 6321da177e4SLinus Torvalds sdev->writeable = 0; 6331da177e4SLinus Torvalds break; 6341da177e4SLinus Torvalds default: 6351da177e4SLinus Torvalds printk(KERN_INFO "scsi: unknown device type %d\n", sdev->type); 6361da177e4SLinus Torvalds } 6371da177e4SLinus Torvalds 6381da177e4SLinus Torvalds print_inquiry(inq_result); 6391da177e4SLinus Torvalds 6401da177e4SLinus Torvalds /* 6411da177e4SLinus Torvalds * For a peripheral qualifier (PQ) value of 1 (001b), the SCSI 6421da177e4SLinus Torvalds * spec says: The device server is capable of supporting the 6431da177e4SLinus Torvalds * specified peripheral device type on this logical unit. However, 6441da177e4SLinus Torvalds * the physical device is not currently connected to this logical 6451da177e4SLinus Torvalds * unit. 6461da177e4SLinus Torvalds * 6471da177e4SLinus Torvalds * The above is vague, as it implies that we could treat 001 and 6481da177e4SLinus Torvalds * 011 the same. Stay compatible with previous code, and create a 6491da177e4SLinus Torvalds * Scsi_Device for a PQ of 1 6501da177e4SLinus Torvalds * 6511da177e4SLinus Torvalds * Don't set the device offline here; rather let the upper 6521da177e4SLinus Torvalds * level drivers eval the PQ to decide whether they should 6531da177e4SLinus Torvalds * attach. So remove ((inq_result[0] >> 5) & 7) == 1 check. 6541da177e4SLinus Torvalds */ 6551da177e4SLinus Torvalds 6561da177e4SLinus Torvalds sdev->inq_periph_qual = (inq_result[0] >> 5) & 7; 6571da177e4SLinus Torvalds sdev->removable = (0x80 & inq_result[1]) >> 7; 6581da177e4SLinus Torvalds sdev->lockable = sdev->removable; 6591da177e4SLinus Torvalds sdev->soft_reset = (inq_result[7] & 1) && ((inq_result[3] & 7) == 2); 6601da177e4SLinus Torvalds 6611da177e4SLinus Torvalds if (sdev->scsi_level >= SCSI_3 || (sdev->inquiry_len > 56 && 6621da177e4SLinus Torvalds inq_result[56] & 0x04)) 6631da177e4SLinus Torvalds sdev->ppr = 1; 6641da177e4SLinus Torvalds if (inq_result[7] & 0x60) 6651da177e4SLinus Torvalds sdev->wdtr = 1; 6661da177e4SLinus Torvalds if (inq_result[7] & 0x10) 6671da177e4SLinus Torvalds sdev->sdtr = 1; 6681da177e4SLinus Torvalds 6691da177e4SLinus Torvalds sprintf(sdev->devfs_name, "scsi/host%d/bus%d/target%d/lun%d", 6701da177e4SLinus Torvalds sdev->host->host_no, sdev->channel, 6711da177e4SLinus Torvalds sdev->id, sdev->lun); 6721da177e4SLinus Torvalds 6731da177e4SLinus Torvalds /* 6741da177e4SLinus Torvalds * End driverfs/devfs code. 6751da177e4SLinus Torvalds */ 6761da177e4SLinus Torvalds 6771da177e4SLinus Torvalds if ((sdev->scsi_level >= SCSI_2) && (inq_result[7] & 2) && 6781da177e4SLinus Torvalds !(*bflags & BLIST_NOTQ)) 6791da177e4SLinus Torvalds sdev->tagged_supported = 1; 6801da177e4SLinus Torvalds /* 6811da177e4SLinus Torvalds * Some devices (Texel CD ROM drives) have handshaking problems 6821da177e4SLinus Torvalds * when used with the Seagate controllers. borken is initialized 6831da177e4SLinus Torvalds * to 1, and then set it to 0 here. 6841da177e4SLinus Torvalds */ 6851da177e4SLinus Torvalds if ((*bflags & BLIST_BORKEN) == 0) 6861da177e4SLinus Torvalds sdev->borken = 0; 6871da177e4SLinus Torvalds 6881da177e4SLinus Torvalds /* 6891da177e4SLinus Torvalds * Apparently some really broken devices (contrary to the SCSI 6901da177e4SLinus Torvalds * standards) need to be selected without asserting ATN 6911da177e4SLinus Torvalds */ 6921da177e4SLinus Torvalds if (*bflags & BLIST_SELECT_NO_ATN) 6931da177e4SLinus Torvalds sdev->select_no_atn = 1; 6941da177e4SLinus Torvalds 6951da177e4SLinus Torvalds /* 6961da177e4SLinus Torvalds * Some devices may not want to have a start command automatically 6971da177e4SLinus Torvalds * issued when a device is added. 6981da177e4SLinus Torvalds */ 6991da177e4SLinus Torvalds if (*bflags & BLIST_NOSTARTONADD) 7001da177e4SLinus Torvalds sdev->no_start_on_add = 1; 7011da177e4SLinus Torvalds 7021da177e4SLinus Torvalds if (*bflags & BLIST_SINGLELUN) 7031da177e4SLinus Torvalds sdev->single_lun = 1; 7041da177e4SLinus Torvalds 7051da177e4SLinus Torvalds 7061da177e4SLinus Torvalds sdev->use_10_for_rw = 1; 7071da177e4SLinus Torvalds 7081da177e4SLinus Torvalds if (*bflags & BLIST_MS_SKIP_PAGE_08) 7091da177e4SLinus Torvalds sdev->skip_ms_page_8 = 1; 7101da177e4SLinus Torvalds 7111da177e4SLinus Torvalds if (*bflags & BLIST_MS_SKIP_PAGE_3F) 7121da177e4SLinus Torvalds sdev->skip_ms_page_3f = 1; 7131da177e4SLinus Torvalds 7141da177e4SLinus Torvalds if (*bflags & BLIST_USE_10_BYTE_MS) 7151da177e4SLinus Torvalds sdev->use_10_for_ms = 1; 7161da177e4SLinus Torvalds 7171da177e4SLinus Torvalds /* set the device running here so that slave configure 7181da177e4SLinus Torvalds * may do I/O */ 7191da177e4SLinus Torvalds scsi_device_set_state(sdev, SDEV_RUNNING); 7201da177e4SLinus Torvalds 7211da177e4SLinus Torvalds if (*bflags & BLIST_MS_192_BYTES_FOR_3F) 7221da177e4SLinus Torvalds sdev->use_192_bytes_for_3f = 1; 7231da177e4SLinus Torvalds 7241da177e4SLinus Torvalds if (*bflags & BLIST_NOT_LOCKABLE) 7251da177e4SLinus Torvalds sdev->lockable = 0; 7261da177e4SLinus Torvalds 7271da177e4SLinus Torvalds if (*bflags & BLIST_RETRY_HWERROR) 7281da177e4SLinus Torvalds sdev->retry_hwerror = 1; 7291da177e4SLinus Torvalds 7301da177e4SLinus Torvalds transport_configure_device(&sdev->sdev_gendev); 7311da177e4SLinus Torvalds 7321da177e4SLinus Torvalds if (sdev->host->hostt->slave_configure) 7331da177e4SLinus Torvalds sdev->host->hostt->slave_configure(sdev); 7341da177e4SLinus Torvalds 7351da177e4SLinus Torvalds /* 7361da177e4SLinus Torvalds * Ok, the device is now all set up, we can 7371da177e4SLinus Torvalds * register it and tell the rest of the kernel 7381da177e4SLinus Torvalds * about it. 7391da177e4SLinus Torvalds */ 7401da177e4SLinus Torvalds scsi_sysfs_add_sdev(sdev); 7411da177e4SLinus Torvalds 7421da177e4SLinus Torvalds return SCSI_SCAN_LUN_PRESENT; 7431da177e4SLinus Torvalds } 7441da177e4SLinus Torvalds 7451da177e4SLinus Torvalds /** 7461da177e4SLinus Torvalds * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it 7471da177e4SLinus Torvalds * @starget: pointer to target device structure 7481da177e4SLinus Torvalds * @lun: LUN of target device 7491da177e4SLinus Torvalds * @sdevscan: probe the LUN corresponding to this Scsi_Device 7501da177e4SLinus Torvalds * @sdevnew: store the value of any new Scsi_Device allocated 7511da177e4SLinus Torvalds * @bflagsp: store bflags here if not NULL 7521da177e4SLinus Torvalds * 7531da177e4SLinus Torvalds * Description: 7541da177e4SLinus Torvalds * Call scsi_probe_lun, if a LUN with an attached device is found, 7551da177e4SLinus Torvalds * allocate and set it up by calling scsi_add_lun. 7561da177e4SLinus Torvalds * 7571da177e4SLinus Torvalds * Return: 7581da177e4SLinus Torvalds * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a Scsi_Device 7591da177e4SLinus Torvalds * SCSI_SCAN_TARGET_PRESENT: target responded, but no device is 7601da177e4SLinus Torvalds * attached at the LUN 7611da177e4SLinus Torvalds * SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized 7621da177e4SLinus Torvalds **/ 7631da177e4SLinus Torvalds static int scsi_probe_and_add_lun(struct scsi_target *starget, 7641da177e4SLinus Torvalds uint lun, int *bflagsp, 7651da177e4SLinus Torvalds struct scsi_device **sdevp, int rescan, 7661da177e4SLinus Torvalds void *hostdata) 7671da177e4SLinus Torvalds { 7681da177e4SLinus Torvalds struct scsi_device *sdev; 7691da177e4SLinus Torvalds struct scsi_request *sreq; 7701da177e4SLinus Torvalds unsigned char *result; 7711da177e4SLinus Torvalds int bflags, res = SCSI_SCAN_NO_RESPONSE; 7721da177e4SLinus Torvalds struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 7731da177e4SLinus Torvalds 7741da177e4SLinus Torvalds /* 7751da177e4SLinus Torvalds * The rescan flag is used as an optimization, the first scan of a 7761da177e4SLinus Torvalds * host adapter calls into here with rescan == 0. 7771da177e4SLinus Torvalds */ 7781da177e4SLinus Torvalds if (rescan) { 7791da177e4SLinus Torvalds sdev = scsi_device_lookup_by_target(starget, lun); 7801da177e4SLinus Torvalds if (sdev) { 7811da177e4SLinus Torvalds SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO 7821da177e4SLinus Torvalds "scsi scan: device exists on %s\n", 7831da177e4SLinus Torvalds sdev->sdev_gendev.bus_id)); 7841da177e4SLinus Torvalds if (sdevp) 7851da177e4SLinus Torvalds *sdevp = sdev; 7861da177e4SLinus Torvalds else 7871da177e4SLinus Torvalds scsi_device_put(sdev); 7881da177e4SLinus Torvalds 7891da177e4SLinus Torvalds if (bflagsp) 7901da177e4SLinus Torvalds *bflagsp = scsi_get_device_flags(sdev, 7911da177e4SLinus Torvalds sdev->vendor, 7921da177e4SLinus Torvalds sdev->model); 7931da177e4SLinus Torvalds return SCSI_SCAN_LUN_PRESENT; 7941da177e4SLinus Torvalds } 7951da177e4SLinus Torvalds } 7961da177e4SLinus Torvalds 7971da177e4SLinus Torvalds sdev = scsi_alloc_sdev(starget, lun, hostdata); 7981da177e4SLinus Torvalds if (!sdev) 7991da177e4SLinus Torvalds goto out; 8001da177e4SLinus Torvalds sreq = scsi_allocate_request(sdev, GFP_ATOMIC); 8011da177e4SLinus Torvalds if (!sreq) 8021da177e4SLinus Torvalds goto out_free_sdev; 8031da177e4SLinus Torvalds result = kmalloc(256, GFP_ATOMIC | 804bc86120aSAl Viro ((shost->unchecked_isa_dma) ? __GFP_DMA : 0)); 8051da177e4SLinus Torvalds if (!result) 8061da177e4SLinus Torvalds goto out_free_sreq; 8071da177e4SLinus Torvalds 8081da177e4SLinus Torvalds scsi_probe_lun(sreq, result, &bflags); 8091da177e4SLinus Torvalds if (sreq->sr_result) 8101da177e4SLinus Torvalds goto out_free_result; 8111da177e4SLinus Torvalds 8121da177e4SLinus Torvalds /* 8131da177e4SLinus Torvalds * result contains valid SCSI INQUIRY data. 8141da177e4SLinus Torvalds */ 8151da177e4SLinus Torvalds if ((result[0] >> 5) == 3) { 8161da177e4SLinus Torvalds /* 8171da177e4SLinus Torvalds * For a Peripheral qualifier 3 (011b), the SCSI 8181da177e4SLinus Torvalds * spec says: The device server is not capable of 8191da177e4SLinus Torvalds * supporting a physical device on this logical 8201da177e4SLinus Torvalds * unit. 8211da177e4SLinus Torvalds * 8221da177e4SLinus Torvalds * For disks, this implies that there is no 8231da177e4SLinus Torvalds * logical disk configured at sdev->lun, but there 8241da177e4SLinus Torvalds * is a target id responding. 8251da177e4SLinus Torvalds */ 8261da177e4SLinus Torvalds SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO 8271da177e4SLinus Torvalds "scsi scan: peripheral qualifier of 3," 8281da177e4SLinus Torvalds " no device added\n")); 8291da177e4SLinus Torvalds res = SCSI_SCAN_TARGET_PRESENT; 8301da177e4SLinus Torvalds goto out_free_result; 8311da177e4SLinus Torvalds } 8321da177e4SLinus Torvalds 8331da177e4SLinus Torvalds res = scsi_add_lun(sdev, result, &bflags); 8341da177e4SLinus Torvalds if (res == SCSI_SCAN_LUN_PRESENT) { 8351da177e4SLinus Torvalds if (bflags & BLIST_KEY) { 8361da177e4SLinus Torvalds sdev->lockable = 0; 8371da177e4SLinus Torvalds scsi_unlock_floptical(sreq, result); 8381da177e4SLinus Torvalds } 8391da177e4SLinus Torvalds if (bflagsp) 8401da177e4SLinus Torvalds *bflagsp = bflags; 8411da177e4SLinus Torvalds } 8421da177e4SLinus Torvalds 8431da177e4SLinus Torvalds out_free_result: 8441da177e4SLinus Torvalds kfree(result); 8451da177e4SLinus Torvalds out_free_sreq: 8461da177e4SLinus Torvalds scsi_release_request(sreq); 8471da177e4SLinus Torvalds out_free_sdev: 8481da177e4SLinus Torvalds if (res == SCSI_SCAN_LUN_PRESENT) { 8491da177e4SLinus Torvalds if (sdevp) { 8501da177e4SLinus Torvalds scsi_device_get(sdev); 8511da177e4SLinus Torvalds *sdevp = sdev; 8521da177e4SLinus Torvalds } 8531da177e4SLinus Torvalds } else { 8541da177e4SLinus Torvalds if (sdev->host->hostt->slave_destroy) 8551da177e4SLinus Torvalds sdev->host->hostt->slave_destroy(sdev); 8561da177e4SLinus Torvalds transport_destroy_device(&sdev->sdev_gendev); 8571da177e4SLinus Torvalds put_device(&sdev->sdev_gendev); 8581da177e4SLinus Torvalds } 8591da177e4SLinus Torvalds out: 8601da177e4SLinus Torvalds return res; 8611da177e4SLinus Torvalds } 8621da177e4SLinus Torvalds 8631da177e4SLinus Torvalds /** 8641da177e4SLinus Torvalds * scsi_sequential_lun_scan - sequentially scan a SCSI target 8651da177e4SLinus Torvalds * @starget: pointer to target structure to scan 8661da177e4SLinus Torvalds * @bflags: black/white list flag for LUN 0 8671da177e4SLinus Torvalds * @lun0_res: result of scanning LUN 0 8681da177e4SLinus Torvalds * 8691da177e4SLinus Torvalds * Description: 8701da177e4SLinus Torvalds * Generally, scan from LUN 1 (LUN 0 is assumed to already have been 8711da177e4SLinus Torvalds * scanned) to some maximum lun until a LUN is found with no device 8721da177e4SLinus Torvalds * attached. Use the bflags to figure out any oddities. 8731da177e4SLinus Torvalds * 8741da177e4SLinus Torvalds * Modifies sdevscan->lun. 8751da177e4SLinus Torvalds **/ 8761da177e4SLinus Torvalds static void scsi_sequential_lun_scan(struct scsi_target *starget, 8771da177e4SLinus Torvalds int bflags, int lun0_res, int scsi_level, 8781da177e4SLinus Torvalds int rescan) 8791da177e4SLinus Torvalds { 8801da177e4SLinus Torvalds unsigned int sparse_lun, lun, max_dev_lun; 8811da177e4SLinus Torvalds struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 8821da177e4SLinus Torvalds 8831da177e4SLinus Torvalds SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: Sequential scan of" 8841da177e4SLinus Torvalds "%s\n", starget->dev.bus_id)); 8851da177e4SLinus Torvalds 8861da177e4SLinus Torvalds max_dev_lun = min(max_scsi_luns, shost->max_lun); 8871da177e4SLinus Torvalds /* 8881da177e4SLinus Torvalds * If this device is known to support sparse multiple units, 8891da177e4SLinus Torvalds * override the other settings, and scan all of them. Normally, 8901da177e4SLinus Torvalds * SCSI-3 devices should be scanned via the REPORT LUNS. 8911da177e4SLinus Torvalds */ 8921da177e4SLinus Torvalds if (bflags & BLIST_SPARSELUN) { 8931da177e4SLinus Torvalds max_dev_lun = shost->max_lun; 8941da177e4SLinus Torvalds sparse_lun = 1; 8951da177e4SLinus Torvalds } else 8961da177e4SLinus Torvalds sparse_lun = 0; 8971da177e4SLinus Torvalds 8981da177e4SLinus Torvalds /* 8991da177e4SLinus Torvalds * If not sparse lun and no device attached at LUN 0 do not scan 9001da177e4SLinus Torvalds * any further. 9011da177e4SLinus Torvalds */ 9021da177e4SLinus Torvalds if (!sparse_lun && (lun0_res != SCSI_SCAN_LUN_PRESENT)) 9031da177e4SLinus Torvalds return; 9041da177e4SLinus Torvalds 9051da177e4SLinus Torvalds /* 9061da177e4SLinus Torvalds * If less than SCSI_1_CSS, and no special lun scaning, stop 9071da177e4SLinus Torvalds * scanning; this matches 2.4 behaviour, but could just be a bug 9081da177e4SLinus Torvalds * (to continue scanning a SCSI_1_CSS device). 9091da177e4SLinus Torvalds * 9101da177e4SLinus Torvalds * This test is broken. We might not have any device on lun0 for 9111da177e4SLinus Torvalds * a sparselun device, and if that's the case then how would we 9121da177e4SLinus Torvalds * know the real scsi_level, eh? It might make sense to just not 9131da177e4SLinus Torvalds * scan any SCSI_1 device for non-0 luns, but that check would best 9141da177e4SLinus Torvalds * go into scsi_alloc_sdev() and just have it return null when asked 9151da177e4SLinus Torvalds * to alloc an sdev for lun > 0 on an already found SCSI_1 device. 9161da177e4SLinus Torvalds * 9171da177e4SLinus Torvalds if ((sdevscan->scsi_level < SCSI_1_CCS) && 9181da177e4SLinus Torvalds ((bflags & (BLIST_FORCELUN | BLIST_SPARSELUN | BLIST_MAX5LUN)) 9191da177e4SLinus Torvalds == 0)) 9201da177e4SLinus Torvalds return; 9211da177e4SLinus Torvalds */ 9221da177e4SLinus Torvalds /* 9231da177e4SLinus Torvalds * If this device is known to support multiple units, override 9241da177e4SLinus Torvalds * the other settings, and scan all of them. 9251da177e4SLinus Torvalds */ 9261da177e4SLinus Torvalds if (bflags & BLIST_FORCELUN) 9271da177e4SLinus Torvalds max_dev_lun = shost->max_lun; 9281da177e4SLinus Torvalds /* 9291da177e4SLinus Torvalds * REGAL CDC-4X: avoid hang after LUN 4 9301da177e4SLinus Torvalds */ 9311da177e4SLinus Torvalds if (bflags & BLIST_MAX5LUN) 9321da177e4SLinus Torvalds max_dev_lun = min(5U, max_dev_lun); 9331da177e4SLinus Torvalds /* 9341da177e4SLinus Torvalds * Do not scan SCSI-2 or lower device past LUN 7, unless 9351da177e4SLinus Torvalds * BLIST_LARGELUN. 9361da177e4SLinus Torvalds */ 9371da177e4SLinus Torvalds if (scsi_level < SCSI_3 && !(bflags & BLIST_LARGELUN)) 9381da177e4SLinus Torvalds max_dev_lun = min(8U, max_dev_lun); 9391da177e4SLinus Torvalds 9401da177e4SLinus Torvalds /* 9411da177e4SLinus Torvalds * We have already scanned LUN 0, so start at LUN 1. Keep scanning 9421da177e4SLinus Torvalds * until we reach the max, or no LUN is found and we are not 9431da177e4SLinus Torvalds * sparse_lun. 9441da177e4SLinus Torvalds */ 9451da177e4SLinus Torvalds for (lun = 1; lun < max_dev_lun; ++lun) 9461da177e4SLinus Torvalds if ((scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan, 9471da177e4SLinus Torvalds NULL) != SCSI_SCAN_LUN_PRESENT) && 9481da177e4SLinus Torvalds !sparse_lun) 9491da177e4SLinus Torvalds return; 9501da177e4SLinus Torvalds } 9511da177e4SLinus Torvalds 9521da177e4SLinus Torvalds /** 9531da177e4SLinus Torvalds * scsilun_to_int: convert a scsi_lun to an int 9541da177e4SLinus Torvalds * @scsilun: struct scsi_lun to be converted. 9551da177e4SLinus Torvalds * 9561da177e4SLinus Torvalds * Description: 9571da177e4SLinus Torvalds * Convert @scsilun from a struct scsi_lun to a four byte host byte-ordered 9581da177e4SLinus Torvalds * integer, and return the result. The caller must check for 9591da177e4SLinus Torvalds * truncation before using this function. 9601da177e4SLinus Torvalds * 9611da177e4SLinus Torvalds * Notes: 9621da177e4SLinus Torvalds * The struct scsi_lun is assumed to be four levels, with each level 9631da177e4SLinus Torvalds * effectively containing a SCSI byte-ordered (big endian) short; the 9641da177e4SLinus Torvalds * addressing bits of each level are ignored (the highest two bits). 9651da177e4SLinus Torvalds * For a description of the LUN format, post SCSI-3 see the SCSI 9661da177e4SLinus Torvalds * Architecture Model, for SCSI-3 see the SCSI Controller Commands. 9671da177e4SLinus Torvalds * 9681da177e4SLinus Torvalds * Given a struct scsi_lun of: 0a 04 0b 03 00 00 00 00, this function returns 9691da177e4SLinus Torvalds * the integer: 0x0b030a04 9701da177e4SLinus Torvalds **/ 9711da177e4SLinus Torvalds static int scsilun_to_int(struct scsi_lun *scsilun) 9721da177e4SLinus Torvalds { 9731da177e4SLinus Torvalds int i; 9741da177e4SLinus Torvalds unsigned int lun; 9751da177e4SLinus Torvalds 9761da177e4SLinus Torvalds lun = 0; 9771da177e4SLinus Torvalds for (i = 0; i < sizeof(lun); i += 2) 9781da177e4SLinus Torvalds lun = lun | (((scsilun->scsi_lun[i] << 8) | 9791da177e4SLinus Torvalds scsilun->scsi_lun[i + 1]) << (i * 8)); 9801da177e4SLinus Torvalds return lun; 9811da177e4SLinus Torvalds } 9821da177e4SLinus Torvalds 9831da177e4SLinus Torvalds /** 9841da177e4SLinus Torvalds * scsi_report_lun_scan - Scan using SCSI REPORT LUN results 9851da177e4SLinus Torvalds * @sdevscan: scan the host, channel, and id of this Scsi_Device 9861da177e4SLinus Torvalds * 9871da177e4SLinus Torvalds * Description: 9881da177e4SLinus Torvalds * If @sdevscan is for a SCSI-3 or up device, send a REPORT LUN 9891da177e4SLinus Torvalds * command, and scan the resulting list of LUNs by calling 9901da177e4SLinus Torvalds * scsi_probe_and_add_lun. 9911da177e4SLinus Torvalds * 9921da177e4SLinus Torvalds * Modifies sdevscan->lun. 9931da177e4SLinus Torvalds * 9941da177e4SLinus Torvalds * Return: 9951da177e4SLinus Torvalds * 0: scan completed (or no memory, so further scanning is futile) 9961da177e4SLinus Torvalds * 1: no report lun scan, or not configured 9971da177e4SLinus Torvalds **/ 9981da177e4SLinus Torvalds static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, 9991da177e4SLinus Torvalds int rescan) 10001da177e4SLinus Torvalds { 10011da177e4SLinus Torvalds char devname[64]; 10021da177e4SLinus Torvalds unsigned char scsi_cmd[MAX_COMMAND_SIZE]; 10031da177e4SLinus Torvalds unsigned int length; 10041da177e4SLinus Torvalds unsigned int lun; 10051da177e4SLinus Torvalds unsigned int num_luns; 10061da177e4SLinus Torvalds unsigned int retries; 10071da177e4SLinus Torvalds struct scsi_lun *lunp, *lun_data; 10081da177e4SLinus Torvalds struct scsi_request *sreq; 10091da177e4SLinus Torvalds u8 *data; 10101da177e4SLinus Torvalds struct scsi_sense_hdr sshdr; 10111da177e4SLinus Torvalds struct scsi_target *starget = scsi_target(sdev); 10121da177e4SLinus Torvalds 10131da177e4SLinus Torvalds /* 10141da177e4SLinus Torvalds * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set. 10151da177e4SLinus Torvalds * Also allow SCSI-2 if BLIST_REPORTLUN2 is set and host adapter does 10161da177e4SLinus Torvalds * support more than 8 LUNs. 10171da177e4SLinus Torvalds */ 10181da177e4SLinus Torvalds if ((bflags & BLIST_NOREPORTLUN) || 10191da177e4SLinus Torvalds sdev->scsi_level < SCSI_2 || 10201da177e4SLinus Torvalds (sdev->scsi_level < SCSI_3 && 10211da177e4SLinus Torvalds (!(bflags & BLIST_REPORTLUN2) || sdev->host->max_lun <= 8)) ) 10221da177e4SLinus Torvalds return 1; 10231da177e4SLinus Torvalds if (bflags & BLIST_NOLUN) 10241da177e4SLinus Torvalds return 0; 10251da177e4SLinus Torvalds 10261da177e4SLinus Torvalds sreq = scsi_allocate_request(sdev, GFP_ATOMIC); 10271da177e4SLinus Torvalds if (!sreq) 10281da177e4SLinus Torvalds goto out; 10291da177e4SLinus Torvalds 10301da177e4SLinus Torvalds sprintf(devname, "host %d channel %d id %d", 10311da177e4SLinus Torvalds sdev->host->host_no, sdev->channel, sdev->id); 10321da177e4SLinus Torvalds 10331da177e4SLinus Torvalds /* 10341da177e4SLinus Torvalds * Allocate enough to hold the header (the same size as one scsi_lun) 10351da177e4SLinus Torvalds * plus the max number of luns we are requesting. 10361da177e4SLinus Torvalds * 10371da177e4SLinus Torvalds * Reallocating and trying again (with the exact amount we need) 10381da177e4SLinus Torvalds * would be nice, but then we need to somehow limit the size 10391da177e4SLinus Torvalds * allocated based on the available memory and the limits of 10401da177e4SLinus Torvalds * kmalloc - we don't want a kmalloc() failure of a huge value to 10411da177e4SLinus Torvalds * prevent us from finding any LUNs on this target. 10421da177e4SLinus Torvalds */ 10431da177e4SLinus Torvalds length = (max_scsi_report_luns + 1) * sizeof(struct scsi_lun); 10441da177e4SLinus Torvalds lun_data = kmalloc(length, GFP_ATOMIC | 10451da177e4SLinus Torvalds (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0)); 10461da177e4SLinus Torvalds if (!lun_data) 10471da177e4SLinus Torvalds goto out_release_request; 10481da177e4SLinus Torvalds 10491da177e4SLinus Torvalds scsi_cmd[0] = REPORT_LUNS; 10501da177e4SLinus Torvalds 10511da177e4SLinus Torvalds /* 10521da177e4SLinus Torvalds * bytes 1 - 5: reserved, set to zero. 10531da177e4SLinus Torvalds */ 10541da177e4SLinus Torvalds memset(&scsi_cmd[1], 0, 5); 10551da177e4SLinus Torvalds 10561da177e4SLinus Torvalds /* 10571da177e4SLinus Torvalds * bytes 6 - 9: length of the command. 10581da177e4SLinus Torvalds */ 10591da177e4SLinus Torvalds scsi_cmd[6] = (unsigned char) (length >> 24) & 0xff; 10601da177e4SLinus Torvalds scsi_cmd[7] = (unsigned char) (length >> 16) & 0xff; 10611da177e4SLinus Torvalds scsi_cmd[8] = (unsigned char) (length >> 8) & 0xff; 10621da177e4SLinus Torvalds scsi_cmd[9] = (unsigned char) length & 0xff; 10631da177e4SLinus Torvalds 10641da177e4SLinus Torvalds scsi_cmd[10] = 0; /* reserved */ 10651da177e4SLinus Torvalds scsi_cmd[11] = 0; /* control */ 10661da177e4SLinus Torvalds sreq->sr_cmd_len = 0; 10671da177e4SLinus Torvalds sreq->sr_data_direction = DMA_FROM_DEVICE; 10681da177e4SLinus Torvalds 10691da177e4SLinus Torvalds /* 10701da177e4SLinus Torvalds * We can get a UNIT ATTENTION, for example a power on/reset, so 10711da177e4SLinus Torvalds * retry a few times (like sd.c does for TEST UNIT READY). 10721da177e4SLinus Torvalds * Experience shows some combinations of adapter/devices get at 10731da177e4SLinus Torvalds * least two power on/resets. 10741da177e4SLinus Torvalds * 10751da177e4SLinus Torvalds * Illegal requests (for devices that do not support REPORT LUNS) 10761da177e4SLinus Torvalds * should come through as a check condition, and will not generate 10771da177e4SLinus Torvalds * a retry. 10781da177e4SLinus Torvalds */ 10791da177e4SLinus Torvalds for (retries = 0; retries < 3; retries++) { 10801da177e4SLinus Torvalds SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: Sending" 10811da177e4SLinus Torvalds " REPORT LUNS to %s (try %d)\n", devname, 10821da177e4SLinus Torvalds retries)); 10831da177e4SLinus Torvalds scsi_wait_req(sreq, scsi_cmd, lun_data, length, 10841da177e4SLinus Torvalds SCSI_TIMEOUT + 4*HZ, 3); 10851da177e4SLinus Torvalds SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS" 10861da177e4SLinus Torvalds " %s (try %d) result 0x%x\n", sreq->sr_result 10871da177e4SLinus Torvalds ? "failed" : "successful", retries, 10881da177e4SLinus Torvalds sreq->sr_result)); 10891da177e4SLinus Torvalds if (sreq->sr_result == 0) 10901da177e4SLinus Torvalds break; 10911da177e4SLinus Torvalds else if (scsi_request_normalize_sense(sreq, &sshdr)) { 10921da177e4SLinus Torvalds if (sshdr.sense_key != UNIT_ATTENTION) 10931da177e4SLinus Torvalds break; 10941da177e4SLinus Torvalds } 10951da177e4SLinus Torvalds } 10961da177e4SLinus Torvalds 10971da177e4SLinus Torvalds if (sreq->sr_result) { 10981da177e4SLinus Torvalds /* 10991da177e4SLinus Torvalds * The device probably does not support a REPORT LUN command 11001da177e4SLinus Torvalds */ 11011da177e4SLinus Torvalds kfree(lun_data); 11021da177e4SLinus Torvalds scsi_release_request(sreq); 11031da177e4SLinus Torvalds return 1; 11041da177e4SLinus Torvalds } 11051da177e4SLinus Torvalds scsi_release_request(sreq); 11061da177e4SLinus Torvalds 11071da177e4SLinus Torvalds /* 11081da177e4SLinus Torvalds * Get the length from the first four bytes of lun_data. 11091da177e4SLinus Torvalds */ 11101da177e4SLinus Torvalds data = (u8 *) lun_data->scsi_lun; 11111da177e4SLinus Torvalds length = ((data[0] << 24) | (data[1] << 16) | 11121da177e4SLinus Torvalds (data[2] << 8) | (data[3] << 0)); 11131da177e4SLinus Torvalds 11141da177e4SLinus Torvalds num_luns = (length / sizeof(struct scsi_lun)); 11151da177e4SLinus Torvalds if (num_luns > max_scsi_report_luns) { 11161da177e4SLinus Torvalds printk(KERN_WARNING "scsi: On %s only %d (max_scsi_report_luns)" 11171da177e4SLinus Torvalds " of %d luns reported, try increasing" 11181da177e4SLinus Torvalds " max_scsi_report_luns.\n", devname, 11191da177e4SLinus Torvalds max_scsi_report_luns, num_luns); 11201da177e4SLinus Torvalds num_luns = max_scsi_report_luns; 11211da177e4SLinus Torvalds } 11221da177e4SLinus Torvalds 11231da177e4SLinus Torvalds SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUN scan of" 11241da177e4SLinus Torvalds " host %d channel %d id %d\n", sdev->host->host_no, 11251da177e4SLinus Torvalds sdev->channel, sdev->id)); 11261da177e4SLinus Torvalds 11271da177e4SLinus Torvalds /* 11281da177e4SLinus Torvalds * Scan the luns in lun_data. The entry at offset 0 is really 11291da177e4SLinus Torvalds * the header, so start at 1 and go up to and including num_luns. 11301da177e4SLinus Torvalds */ 11311da177e4SLinus Torvalds for (lunp = &lun_data[1]; lunp <= &lun_data[num_luns]; lunp++) { 11321da177e4SLinus Torvalds lun = scsilun_to_int(lunp); 11331da177e4SLinus Torvalds 11341da177e4SLinus Torvalds /* 11351da177e4SLinus Torvalds * Check if the unused part of lunp is non-zero, and so 11361da177e4SLinus Torvalds * does not fit in lun. 11371da177e4SLinus Torvalds */ 11381da177e4SLinus Torvalds if (memcmp(&lunp->scsi_lun[sizeof(lun)], "\0\0\0\0", 4)) { 11391da177e4SLinus Torvalds int i; 11401da177e4SLinus Torvalds 11411da177e4SLinus Torvalds /* 11421da177e4SLinus Torvalds * Output an error displaying the LUN in byte order, 11431da177e4SLinus Torvalds * this differs from what linux would print for the 11441da177e4SLinus Torvalds * integer LUN value. 11451da177e4SLinus Torvalds */ 11461da177e4SLinus Torvalds printk(KERN_WARNING "scsi: %s lun 0x", devname); 11471da177e4SLinus Torvalds data = (char *)lunp->scsi_lun; 11481da177e4SLinus Torvalds for (i = 0; i < sizeof(struct scsi_lun); i++) 11491da177e4SLinus Torvalds printk("%02x", data[i]); 11501da177e4SLinus Torvalds printk(" has a LUN larger than currently supported.\n"); 11511da177e4SLinus Torvalds } else if (lun == 0) { 11521da177e4SLinus Torvalds /* 11531da177e4SLinus Torvalds * LUN 0 has already been scanned. 11541da177e4SLinus Torvalds */ 11551da177e4SLinus Torvalds } else if (lun > sdev->host->max_lun) { 11561da177e4SLinus Torvalds printk(KERN_WARNING "scsi: %s lun%d has a LUN larger" 11571da177e4SLinus Torvalds " than allowed by the host adapter\n", 11581da177e4SLinus Torvalds devname, lun); 11591da177e4SLinus Torvalds } else { 11601da177e4SLinus Torvalds int res; 11611da177e4SLinus Torvalds 11621da177e4SLinus Torvalds res = scsi_probe_and_add_lun(starget, 11631da177e4SLinus Torvalds lun, NULL, NULL, rescan, NULL); 11641da177e4SLinus Torvalds if (res == SCSI_SCAN_NO_RESPONSE) { 11651da177e4SLinus Torvalds /* 11661da177e4SLinus Torvalds * Got some results, but now none, abort. 11671da177e4SLinus Torvalds */ 11681da177e4SLinus Torvalds printk(KERN_ERR "scsi: Unexpected response" 11691da177e4SLinus Torvalds " from %s lun %d while scanning, scan" 11701da177e4SLinus Torvalds " aborted\n", devname, lun); 11711da177e4SLinus Torvalds break; 11721da177e4SLinus Torvalds } 11731da177e4SLinus Torvalds } 11741da177e4SLinus Torvalds } 11751da177e4SLinus Torvalds 11761da177e4SLinus Torvalds kfree(lun_data); 11771da177e4SLinus Torvalds return 0; 11781da177e4SLinus Torvalds 11791da177e4SLinus Torvalds out_release_request: 11801da177e4SLinus Torvalds scsi_release_request(sreq); 11811da177e4SLinus Torvalds out: 11821da177e4SLinus Torvalds /* 11831da177e4SLinus Torvalds * We are out of memory, don't try scanning any further. 11841da177e4SLinus Torvalds */ 11851da177e4SLinus Torvalds printk(ALLOC_FAILURE_MSG, __FUNCTION__); 11861da177e4SLinus Torvalds return 0; 11871da177e4SLinus Torvalds } 11881da177e4SLinus Torvalds 11891da177e4SLinus Torvalds struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, 11901da177e4SLinus Torvalds uint id, uint lun, void *hostdata) 11911da177e4SLinus Torvalds { 11921da177e4SLinus Torvalds struct scsi_device *sdev; 11931da177e4SLinus Torvalds struct device *parent = &shost->shost_gendev; 11941da177e4SLinus Torvalds int res; 11951da177e4SLinus Torvalds struct scsi_target *starget = scsi_alloc_target(parent, channel, id); 11961da177e4SLinus Torvalds 11971da177e4SLinus Torvalds if (!starget) 11981da177e4SLinus Torvalds return ERR_PTR(-ENOMEM); 11991da177e4SLinus Torvalds 1200*c92715b3SNathan Lynch get_device(&starget->dev); 12011da177e4SLinus Torvalds down(&shost->scan_mutex); 12021da177e4SLinus Torvalds res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); 12031da177e4SLinus Torvalds if (res != SCSI_SCAN_LUN_PRESENT) 12041da177e4SLinus Torvalds sdev = ERR_PTR(-ENODEV); 12051da177e4SLinus Torvalds up(&shost->scan_mutex); 12061da177e4SLinus Torvalds scsi_target_reap(starget); 12071da177e4SLinus Torvalds put_device(&starget->dev); 12081da177e4SLinus Torvalds 12091da177e4SLinus Torvalds return sdev; 12101da177e4SLinus Torvalds } 12111da177e4SLinus Torvalds EXPORT_SYMBOL(__scsi_add_device); 12121da177e4SLinus Torvalds 12131da177e4SLinus Torvalds void scsi_rescan_device(struct device *dev) 12141da177e4SLinus Torvalds { 12151da177e4SLinus Torvalds struct scsi_driver *drv; 12161da177e4SLinus Torvalds 12171da177e4SLinus Torvalds if (!dev->driver) 12181da177e4SLinus Torvalds return; 12191da177e4SLinus Torvalds 12201da177e4SLinus Torvalds drv = to_scsi_driver(dev->driver); 12211da177e4SLinus Torvalds if (try_module_get(drv->owner)) { 12221da177e4SLinus Torvalds if (drv->rescan) 12231da177e4SLinus Torvalds drv->rescan(dev); 12241da177e4SLinus Torvalds module_put(drv->owner); 12251da177e4SLinus Torvalds } 12261da177e4SLinus Torvalds } 12271da177e4SLinus Torvalds EXPORT_SYMBOL(scsi_rescan_device); 12281da177e4SLinus Torvalds 12291da177e4SLinus Torvalds /** 12301da177e4SLinus Torvalds * scsi_scan_target - scan a target id, possibly including all LUNs on the 12311da177e4SLinus Torvalds * target. 12321da177e4SLinus Torvalds * @sdevsca: Scsi_Device handle for scanning 12331da177e4SLinus Torvalds * @shost: host to scan 12341da177e4SLinus Torvalds * @channel: channel to scan 12351da177e4SLinus Torvalds * @id: target id to scan 12361da177e4SLinus Torvalds * 12371da177e4SLinus Torvalds * Description: 12381da177e4SLinus Torvalds * Scan the target id on @shost, @channel, and @id. Scan at least LUN 12391da177e4SLinus Torvalds * 0, and possibly all LUNs on the target id. 12401da177e4SLinus Torvalds * 12411da177e4SLinus Torvalds * Use the pre-allocated @sdevscan as a handle for the scanning. This 12421da177e4SLinus Torvalds * function sets sdevscan->host, sdevscan->id and sdevscan->lun; the 12431da177e4SLinus Torvalds * scanning functions modify sdevscan->lun. 12441da177e4SLinus Torvalds * 12451da177e4SLinus Torvalds * First try a REPORT LUN scan, if that does not scan the target, do a 12461da177e4SLinus Torvalds * sequential scan of LUNs on the target id. 12471da177e4SLinus Torvalds **/ 12481da177e4SLinus Torvalds void scsi_scan_target(struct device *parent, unsigned int channel, 12491da177e4SLinus Torvalds unsigned int id, unsigned int lun, int rescan) 12501da177e4SLinus Torvalds { 12511da177e4SLinus Torvalds struct Scsi_Host *shost = dev_to_shost(parent); 12521da177e4SLinus Torvalds int bflags = 0; 12531da177e4SLinus Torvalds int res; 12541da177e4SLinus Torvalds struct scsi_device *sdev = NULL; 12551da177e4SLinus Torvalds struct scsi_target *starget; 12561da177e4SLinus Torvalds 12571da177e4SLinus Torvalds if (shost->this_id == id) 12581da177e4SLinus Torvalds /* 12591da177e4SLinus Torvalds * Don't scan the host adapter 12601da177e4SLinus Torvalds */ 12611da177e4SLinus Torvalds return; 12621da177e4SLinus Torvalds 12631da177e4SLinus Torvalds 12641da177e4SLinus Torvalds starget = scsi_alloc_target(parent, channel, id); 12651da177e4SLinus Torvalds 12661da177e4SLinus Torvalds if (!starget) 12671da177e4SLinus Torvalds return; 12681da177e4SLinus Torvalds 12691da177e4SLinus Torvalds get_device(&starget->dev); 12701da177e4SLinus Torvalds if (lun != SCAN_WILD_CARD) { 12711da177e4SLinus Torvalds /* 12721da177e4SLinus Torvalds * Scan for a specific host/chan/id/lun. 12731da177e4SLinus Torvalds */ 12741da177e4SLinus Torvalds scsi_probe_and_add_lun(starget, lun, NULL, NULL, rescan, NULL); 12751da177e4SLinus Torvalds goto out_reap; 12761da177e4SLinus Torvalds } 12771da177e4SLinus Torvalds 12781da177e4SLinus Torvalds /* 12791da177e4SLinus Torvalds * Scan LUN 0, if there is some response, scan further. Ideally, we 12801da177e4SLinus Torvalds * would not configure LUN 0 until all LUNs are scanned. 12811da177e4SLinus Torvalds */ 12821da177e4SLinus Torvalds res = scsi_probe_and_add_lun(starget, 0, &bflags, &sdev, rescan, NULL); 12831da177e4SLinus Torvalds if (res == SCSI_SCAN_LUN_PRESENT) { 12841da177e4SLinus Torvalds if (scsi_report_lun_scan(sdev, bflags, rescan) != 0) 12851da177e4SLinus Torvalds /* 12861da177e4SLinus Torvalds * The REPORT LUN did not scan the target, 12871da177e4SLinus Torvalds * do a sequential scan. 12881da177e4SLinus Torvalds */ 12891da177e4SLinus Torvalds scsi_sequential_lun_scan(starget, bflags, 12901da177e4SLinus Torvalds res, sdev->scsi_level, rescan); 12911da177e4SLinus Torvalds } else if (res == SCSI_SCAN_TARGET_PRESENT) { 12921da177e4SLinus Torvalds /* 12931da177e4SLinus Torvalds * There's a target here, but lun 0 is offline so we 12941da177e4SLinus Torvalds * can't use the report_lun scan. Fall back to a 12951da177e4SLinus Torvalds * sequential lun scan with a bflags of SPARSELUN and 12961da177e4SLinus Torvalds * a default scsi level of SCSI_2 12971da177e4SLinus Torvalds */ 12981da177e4SLinus Torvalds scsi_sequential_lun_scan(starget, BLIST_SPARSELUN, 12991da177e4SLinus Torvalds SCSI_SCAN_TARGET_PRESENT, SCSI_2, rescan); 13001da177e4SLinus Torvalds } 13011da177e4SLinus Torvalds if (sdev) 13021da177e4SLinus Torvalds scsi_device_put(sdev); 13031da177e4SLinus Torvalds 13041da177e4SLinus Torvalds out_reap: 13051da177e4SLinus Torvalds /* now determine if the target has any children at all 13061da177e4SLinus Torvalds * and if not, nuke it */ 13071da177e4SLinus Torvalds scsi_target_reap(starget); 13081da177e4SLinus Torvalds 13091da177e4SLinus Torvalds put_device(&starget->dev); 13101da177e4SLinus Torvalds } 13111da177e4SLinus Torvalds EXPORT_SYMBOL(scsi_scan_target); 13121da177e4SLinus Torvalds 13131da177e4SLinus Torvalds static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel, 13141da177e4SLinus Torvalds unsigned int id, unsigned int lun, int rescan) 13151da177e4SLinus Torvalds { 13161da177e4SLinus Torvalds uint order_id; 13171da177e4SLinus Torvalds 13181da177e4SLinus Torvalds if (id == SCAN_WILD_CARD) 13191da177e4SLinus Torvalds for (id = 0; id < shost->max_id; ++id) { 13201da177e4SLinus Torvalds /* 13211da177e4SLinus Torvalds * XXX adapter drivers when possible (FCP, iSCSI) 13221da177e4SLinus Torvalds * could modify max_id to match the current max, 13231da177e4SLinus Torvalds * not the absolute max. 13241da177e4SLinus Torvalds * 13251da177e4SLinus Torvalds * XXX add a shost id iterator, so for example, 13261da177e4SLinus Torvalds * the FC ID can be the same as a target id 13271da177e4SLinus Torvalds * without a huge overhead of sparse id's. 13281da177e4SLinus Torvalds */ 13291da177e4SLinus Torvalds if (shost->reverse_ordering) 13301da177e4SLinus Torvalds /* 13311da177e4SLinus Torvalds * Scan from high to low id. 13321da177e4SLinus Torvalds */ 13331da177e4SLinus Torvalds order_id = shost->max_id - id - 1; 13341da177e4SLinus Torvalds else 13351da177e4SLinus Torvalds order_id = id; 13361da177e4SLinus Torvalds scsi_scan_target(&shost->shost_gendev, channel, order_id, lun, rescan); 13371da177e4SLinus Torvalds } 13381da177e4SLinus Torvalds else 13391da177e4SLinus Torvalds scsi_scan_target(&shost->shost_gendev, channel, id, lun, rescan); 13401da177e4SLinus Torvalds } 13411da177e4SLinus Torvalds 13421da177e4SLinus Torvalds int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, 13431da177e4SLinus Torvalds unsigned int id, unsigned int lun, int rescan) 13441da177e4SLinus Torvalds { 13451da177e4SLinus Torvalds SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "%s: <%u:%u:%u:%u>\n", 13461da177e4SLinus Torvalds __FUNCTION__, shost->host_no, channel, id, lun)); 13471da177e4SLinus Torvalds 13481da177e4SLinus Torvalds if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || 13491da177e4SLinus Torvalds ((id != SCAN_WILD_CARD) && (id > shost->max_id)) || 13501da177e4SLinus Torvalds ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) 13511da177e4SLinus Torvalds return -EINVAL; 13521da177e4SLinus Torvalds 13531da177e4SLinus Torvalds down(&shost->scan_mutex); 13541da177e4SLinus Torvalds if (channel == SCAN_WILD_CARD) 13551da177e4SLinus Torvalds for (channel = 0; channel <= shost->max_channel; channel++) 13561da177e4SLinus Torvalds scsi_scan_channel(shost, channel, id, lun, rescan); 13571da177e4SLinus Torvalds else 13581da177e4SLinus Torvalds scsi_scan_channel(shost, channel, id, lun, rescan); 13591da177e4SLinus Torvalds up(&shost->scan_mutex); 13601da177e4SLinus Torvalds 13611da177e4SLinus Torvalds return 0; 13621da177e4SLinus Torvalds } 13631da177e4SLinus Torvalds 13641da177e4SLinus Torvalds /** 13651da177e4SLinus Torvalds * scsi_scan_host - scan the given adapter 13661da177e4SLinus Torvalds * @shost: adapter to scan 13671da177e4SLinus Torvalds **/ 13681da177e4SLinus Torvalds void scsi_scan_host(struct Scsi_Host *shost) 13691da177e4SLinus Torvalds { 13701da177e4SLinus Torvalds scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD, 13711da177e4SLinus Torvalds SCAN_WILD_CARD, 0); 13721da177e4SLinus Torvalds } 13731da177e4SLinus Torvalds EXPORT_SYMBOL(scsi_scan_host); 13741da177e4SLinus Torvalds 13751da177e4SLinus Torvalds /** 13761da177e4SLinus Torvalds * scsi_scan_single_target - scan the given SCSI target 13771da177e4SLinus Torvalds * @shost: adapter to scan 13781da177e4SLinus Torvalds * @chan: channel to scan 13791da177e4SLinus Torvalds * @id: target id to scan 13801da177e4SLinus Torvalds **/ 13811da177e4SLinus Torvalds void scsi_scan_single_target(struct Scsi_Host *shost, 13821da177e4SLinus Torvalds unsigned int chan, unsigned int id) 13831da177e4SLinus Torvalds { 13841da177e4SLinus Torvalds scsi_scan_host_selected(shost, chan, id, SCAN_WILD_CARD, 1); 13851da177e4SLinus Torvalds } 13861da177e4SLinus Torvalds EXPORT_SYMBOL(scsi_scan_single_target); 13871da177e4SLinus Torvalds 13881da177e4SLinus Torvalds void scsi_forget_host(struct Scsi_Host *shost) 13891da177e4SLinus Torvalds { 13901da177e4SLinus Torvalds struct scsi_target *starget, *tmp; 13911da177e4SLinus Torvalds unsigned long flags; 13921da177e4SLinus Torvalds 13931da177e4SLinus Torvalds /* 13941da177e4SLinus Torvalds * Ok, this look a bit strange. We always look for the first device 13951da177e4SLinus Torvalds * on the list as scsi_remove_device removes them from it - thus we 13961da177e4SLinus Torvalds * also have to release the lock. 13971da177e4SLinus Torvalds * We don't need to get another reference to the device before 13981da177e4SLinus Torvalds * releasing the lock as we already own the reference from 13991da177e4SLinus Torvalds * scsi_register_device that's release in scsi_remove_device. And 14001da177e4SLinus Torvalds * after that we don't look at sdev anymore. 14011da177e4SLinus Torvalds */ 14021da177e4SLinus Torvalds spin_lock_irqsave(shost->host_lock, flags); 14031da177e4SLinus Torvalds list_for_each_entry_safe(starget, tmp, &shost->__targets, siblings) { 14041da177e4SLinus Torvalds spin_unlock_irqrestore(shost->host_lock, flags); 14051da177e4SLinus Torvalds scsi_remove_target(&starget->dev); 14061da177e4SLinus Torvalds spin_lock_irqsave(shost->host_lock, flags); 14071da177e4SLinus Torvalds } 14081da177e4SLinus Torvalds spin_unlock_irqrestore(shost->host_lock, flags); 14091da177e4SLinus Torvalds } 14101da177e4SLinus Torvalds 14111da177e4SLinus Torvalds /* 14121da177e4SLinus Torvalds * Function: scsi_get_host_dev() 14131da177e4SLinus Torvalds * 14141da177e4SLinus Torvalds * Purpose: Create a Scsi_Device that points to the host adapter itself. 14151da177e4SLinus Torvalds * 14161da177e4SLinus Torvalds * Arguments: SHpnt - Host that needs a Scsi_Device 14171da177e4SLinus Torvalds * 14181da177e4SLinus Torvalds * Lock status: None assumed. 14191da177e4SLinus Torvalds * 14201da177e4SLinus Torvalds * Returns: The Scsi_Device or NULL 14211da177e4SLinus Torvalds * 14221da177e4SLinus Torvalds * Notes: 14231da177e4SLinus Torvalds * Attach a single Scsi_Device to the Scsi_Host - this should 14241da177e4SLinus Torvalds * be made to look like a "pseudo-device" that points to the 14251da177e4SLinus Torvalds * HA itself. 14261da177e4SLinus Torvalds * 14271da177e4SLinus Torvalds * Note - this device is not accessible from any high-level 14281da177e4SLinus Torvalds * drivers (including generics), which is probably not 14291da177e4SLinus Torvalds * optimal. We can add hooks later to attach 14301da177e4SLinus Torvalds */ 14311da177e4SLinus Torvalds struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) 14321da177e4SLinus Torvalds { 14331da177e4SLinus Torvalds struct scsi_device *sdev; 14341da177e4SLinus Torvalds struct scsi_target *starget; 14351da177e4SLinus Torvalds 14361da177e4SLinus Torvalds starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id); 14371da177e4SLinus Torvalds if (!starget) 14381da177e4SLinus Torvalds return NULL; 14391da177e4SLinus Torvalds 14401da177e4SLinus Torvalds sdev = scsi_alloc_sdev(starget, 0, NULL); 14411da177e4SLinus Torvalds if (sdev) { 14421da177e4SLinus Torvalds sdev->sdev_gendev.parent = get_device(&starget->dev); 14431da177e4SLinus Torvalds sdev->borken = 0; 14441da177e4SLinus Torvalds } 14451da177e4SLinus Torvalds put_device(&starget->dev); 14461da177e4SLinus Torvalds return sdev; 14471da177e4SLinus Torvalds } 14481da177e4SLinus Torvalds EXPORT_SYMBOL(scsi_get_host_dev); 14491da177e4SLinus Torvalds 14501da177e4SLinus Torvalds /* 14511da177e4SLinus Torvalds * Function: scsi_free_host_dev() 14521da177e4SLinus Torvalds * 14531da177e4SLinus Torvalds * Purpose: Free a scsi_device that points to the host adapter itself. 14541da177e4SLinus Torvalds * 14551da177e4SLinus Torvalds * Arguments: SHpnt - Host that needs a Scsi_Device 14561da177e4SLinus Torvalds * 14571da177e4SLinus Torvalds * Lock status: None assumed. 14581da177e4SLinus Torvalds * 14591da177e4SLinus Torvalds * Returns: Nothing 14601da177e4SLinus Torvalds * 14611da177e4SLinus Torvalds * Notes: 14621da177e4SLinus Torvalds */ 14631da177e4SLinus Torvalds void scsi_free_host_dev(struct scsi_device *sdev) 14641da177e4SLinus Torvalds { 14651da177e4SLinus Torvalds BUG_ON(sdev->id != sdev->host->this_id); 14661da177e4SLinus Torvalds 14671da177e4SLinus Torvalds if (sdev->host->hostt->slave_destroy) 14681da177e4SLinus Torvalds sdev->host->hostt->slave_destroy(sdev); 14691da177e4SLinus Torvalds transport_destroy_device(&sdev->sdev_gendev); 14701da177e4SLinus Torvalds put_device(&sdev->sdev_gendev); 14711da177e4SLinus Torvalds } 14721da177e4SLinus Torvalds EXPORT_SYMBOL(scsi_free_host_dev); 14731da177e4SLinus Torvalds 1474