* After the system is up, you may enable logging via the /proc interface.
*/
unsigned int scsi_logging_level;
+#if defined(CONFIG_SCSI_LOGGING)
+EXPORT_SYMBOL(scsi_logging_level);
+#endif
const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = {
"Direct-Access ",
"RAID ",
"Enclosure ",
};
+EXPORT_SYMBOL(scsi_device_types);
/*
* Function: scsi_allocate_request
return sreq;
}
+EXPORT_SYMBOL(scsi_allocate_request);
void __scsi_release_request(struct scsi_request *sreq)
{
__scsi_release_request(sreq);
kfree(sreq);
}
+EXPORT_SYMBOL(scsi_release_request);
struct scsi_host_cmd_pool {
kmem_cache_t *slab;
*/
struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int gfp_mask)
{
- struct scsi_cmnd *cmd = __scsi_get_command(dev->host, gfp_mask);
+ struct scsi_cmnd *cmd;
+
+ /* Bail if we can't get a reference to the device */
+ if (!get_device(&dev->sdev_gendev))
+ return NULL;
+
+ cmd = __scsi_get_command(dev->host, gfp_mask);
if (likely(cmd != NULL)) {
unsigned long flags;
spin_lock_irqsave(&dev->list_lock, flags);
list_add_tail(&cmd->list, &dev->cmd_list);
spin_unlock_irqrestore(&dev->list_lock, flags);
- }
+ } else
+ put_device(&dev->sdev_gendev);
return cmd;
}
+EXPORT_SYMBOL(scsi_get_command);
/*
* Function: scsi_put_command()
*/
void scsi_put_command(struct scsi_cmnd *cmd)
{
- struct Scsi_Host *shost = cmd->device->host;
+ struct scsi_device *sdev = cmd->device;
+ struct Scsi_Host *shost = sdev->host;
unsigned long flags;
/* serious error if the command hasn't come from a device list */
if (likely(cmd != NULL))
kmem_cache_free(shost->cmd_pool->slab, cmd);
+
+ put_device(&sdev->sdev_gendev);
}
+EXPORT_SYMBOL(scsi_put_command);
/*
* Function: scsi_setup_command_freelist()
/* return 0 (because the command has been processed) */
goto out;
}
+
+ /* Check to see if the scsi lld put this device into state SDEV_BLOCK. */
+ if (unlikely(cmd->device->sdev_state == SDEV_BLOCK)) {
+ /*
+ * in SDEV_BLOCK, the command is just put back on the device
+ * queue. The suspend state has already blocked the queue so
+ * future requests should not occur until the device
+ * transitions out of the suspend state.
+ */
+ scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
+
+ SCSI_LOG_MLQUEUE(3, printk("queuecommand : device blocked \n"));
+
+ /*
+ * NOTE: rtn is still zero here because we don't need the
+ * queue to be plugged on return (it's already stopped)
+ */
+ goto out;
+ }
+
/* Assign a unique nonzero serial_number. */
/* XXX(hch): this is racy */
if (++serial_number == 0)
printk("queuecommand : command too long.\n"));
cmd->result = (DID_ABORT << 16);
- spin_lock_irqsave(host->host_lock, flags);
scsi_done(cmd);
- spin_unlock_irqrestore(host->host_lock, flags);
goto out;
}
*/
void scsi_adjust_queue_depth(struct scsi_device *sdev, int tagged, int tags)
{
- static spinlock_t device_request_lock = SPIN_LOCK_UNLOCKED;
+ static DEFINE_SPINLOCK(device_request_lock);
unsigned long flags;
/*
spin_unlock(sdev->request_queue->queue_lock);
spin_unlock_irqrestore(&device_request_lock, flags);
}
+EXPORT_SYMBOL(scsi_adjust_queue_depth);
/*
* Function: scsi_track_queue_full()
scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth);
return depth;
}
+EXPORT_SYMBOL(scsi_track_queue_full);
/**
* scsi_device_get - get an addition reference to a scsi_device
/* skip devices that we can't get a reference to */
if (!scsi_device_get(next))
break;
+ next = NULL;
list = list->next;
}
spin_unlock_irqrestore(shost->host_lock, flags);
}
EXPORT_SYMBOL(__scsi_iterate_devices);
+/**
+ * starget_for_each_device - helper to walk all devices of a target
+ * @starget: target whose devices we want to iterate over.
+ *
+ * This traverses over each devices of @shost. The devices have
+ * a reference that must be released by scsi_host_put when breaking
+ * out of the loop.
+ */
+void starget_for_each_device(struct scsi_target *starget, void * data,
+ void (*fn)(struct scsi_device *, void *))
+{
+ struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct scsi_device *sdev;
+
+ shost_for_each_device(sdev, shost) {
+ if ((sdev->channel == starget->channel) &&
+ (sdev->id == starget->id))
+ fn(sdev, data);
+ }
+}
+EXPORT_SYMBOL(starget_for_each_device);
+
/**
* scsi_device_lookup - find a device given the host (UNLOCKED)
* @shost: SCSI host pointer
/**
* scsi_device_cancel - cancel outstanding IO to this device
- * @sdev: pointer to struct scsi_device
- * @data: pointer to cancel value.
+ * @sdev: Pointer to struct scsi_device
+ * @recovery: Boolean instructing function to recover device or not.
*
**/
int scsi_device_cancel(struct scsi_device *sdev, int recovery)
return 0;
}
+EXPORT_SYMBOL(scsi_device_cancel);
#ifdef CONFIG_HOTPLUG_CPU
static int scsi_cpu_notify(struct notifier_block *self,