return -EINVAL;
if (check_set(&lun, s3))
return -EINVAL;
- res = scsi_scan_host_selected(shost, channel, id, lun, 1);
+ if (shost->transportt->user_scan)
+ res = shost->transportt->user_scan(shost, channel, id, lun);
+ else
+ res = scsi_scan_host_selected(shost, channel, id, lun, 1);
return res;
}
put_device(&sdev->sdev_gendev);
}
-static void scsi_device_dev_release(struct device *dev)
+static void scsi_device_dev_release_usercontext(void *data)
{
+ struct device *dev = data;
struct scsi_device *sdev;
struct device *parent;
struct scsi_target *starget;
if (sdev->request_queue) {
sdev->request_queue->queuedata = NULL;
+ /* user context needed to free queue */
scsi_free_queue(sdev->request_queue);
/* temporary expedient, try to catch use of queue lock
* after free of sdev */
put_device(parent);
}
+static void scsi_device_dev_release(struct device *dev)
+{
+ scsi_execute_in_process_context(scsi_device_dev_release_usercontext, dev);
+}
+
static struct class sdev_class = {
.name = "scsi_device",
.release = scsi_device_cls_release,
{
struct Scsi_Host *shost = sdev->host;
- down(&shost->scan_mutex);
+ mutex_lock(&shost->scan_mutex);
__scsi_remove_device(sdev);
- up(&shost->scan_mutex);
+ mutex_unlock(&shost->scan_mutex);
}
EXPORT_SYMBOL(scsi_remove_device);