};
#undef SP
-static struct kmem_cache *scsi_bidi_sdb_cache;
+static struct kmem_cache *scsi_sdb_cache;
static void scsi_run_queue(struct request_queue *q);
scsi_set_resid(cmd, 0);
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
if (cmd->cmd_len == 0)
- cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
+ cmd->cmd_len = scsi_command_size(cmd->cmnd);
}
void scsi_device_unbusy(struct scsi_device *sdev)
!shost->host_blocked && !shost->host_self_blocked &&
!((shost->can_queue > 0) &&
(shost->host_busy >= shost->can_queue))) {
+
+ int flagset;
+
/*
* As long as shost is accepting commands and we have
* starved queues, call blk_run_queue. scsi_request_fn
sdev = list_entry(shost->starved_list.next,
struct scsi_device, starved_entry);
list_del_init(&sdev->starved_entry);
- spin_unlock_irqrestore(shost->host_lock, flags);
-
+ spin_unlock(shost->host_lock);
+
+ spin_lock(sdev->request_queue->queue_lock);
+ flagset = test_bit(QUEUE_FLAG_REENTER, &q->queue_flags) &&
+ !test_bit(QUEUE_FLAG_REENTER,
+ &sdev->request_queue->queue_flags);
+ if (flagset)
+ queue_flag_set(QUEUE_FLAG_REENTER, sdev->request_queue);
+ __blk_run_queue(sdev->request_queue);
+ if (flagset)
+ queue_flag_clear(QUEUE_FLAG_REENTER, sdev->request_queue);
+ spin_unlock(sdev->request_queue->queue_lock);
- if (test_bit(QUEUE_FLAG_REENTER, &q->queue_flags) &&
- !test_and_set_bit(QUEUE_FLAG_REENTER,
- &sdev->request_queue->queue_flags)) {
- blk_run_queue(sdev->request_queue);
- clear_bit(QUEUE_FLAG_REENTER,
- &sdev->request_queue->queue_flags);
- } else
- blk_run_queue(sdev->request_queue);
-
- spin_lock_irqsave(shost->host_lock, flags);
+ spin_lock(shost->host_lock);
if (unlikely(!list_empty(&sdev->starved_entry)))
/*
* sdev lost a race, and was put back on the
struct scsi_data_buffer *bidi_sdb =
cmd->request->next_rq->special;
scsi_free_sgtable(bidi_sdb);
- kmem_cache_free(scsi_bidi_sdb_cache, bidi_sdb);
+ kmem_cache_free(scsi_sdb_cache, bidi_sdb);
cmd->request->next_rq->special = NULL;
}
}
if (blk_bidi_rq(cmd->request)) {
struct scsi_data_buffer *bidi_sdb = kmem_cache_zalloc(
- scsi_bidi_sdb_cache, GFP_ATOMIC);
+ scsi_sdb_cache, GFP_ATOMIC);
if (!bidi_sdb) {
error = BLKPREP_DEFER;
goto err_exit;
cmd->tag = req->tag;
cmd->request = req;
+ cmd->cmnd = req->cmd;
+
return cmd;
}
req->buffer = NULL;
}
- BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd));
- memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));
cmd->cmd_len = req->cmd_len;
if (!req->data_len)
cmd->sc_data_direction = DMA_NONE;
if (ret != BLKPREP_OK)
return ret;
+
+ if (unlikely(sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh
+ && sdev->scsi_dh_data->scsi_dh->prep_fn)) {
+ ret = sdev->scsi_dh_data->scsi_dh->prep_fn(sdev, req);
+ if (ret != BLKPREP_OK)
+ return ret;
+ }
+
/*
* Filesystem requests must transfer data.
*/
if (unlikely(!cmd))
return BLKPREP_DEFER;
+ memset(cmd->cmnd, 0, BLK_MAX_CDB);
return scsi_init_io(cmd, GFP_ATOMIC);
}
EXPORT_SYMBOL(scsi_setup_fs_cmnd);
printk("scsi%d unblocking host at zero depth\n",
shost->host_no));
} else {
- blk_plug_device(q);
return 0;
}
}
blk_queue_max_segment_size(q, dma_get_max_seg_size(dev));
+ /* New queue, no concurrency on queue_flags */
if (!shost->use_clustering)
- clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
+ queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q);
/*
* set a reasonable default alignment on word boundaries: the
return -ENOMEM;
}
- scsi_bidi_sdb_cache = kmem_cache_create("scsi_bidi_sdb",
- sizeof(struct scsi_data_buffer),
- 0, 0, NULL);
- if (!scsi_bidi_sdb_cache) {
- printk(KERN_ERR "SCSI: can't init scsi bidi sdb cache\n");
+ scsi_sdb_cache = kmem_cache_create("scsi_data_buffer",
+ sizeof(struct scsi_data_buffer),
+ 0, 0, NULL);
+ if (!scsi_sdb_cache) {
+ printk(KERN_ERR "SCSI: can't init scsi sdb cache\n");
goto cleanup_io_context;
}
if (!sgp->slab) {
printk(KERN_ERR "SCSI: can't init sg slab %s\n",
sgp->name);
- goto cleanup_bidi_sdb;
+ goto cleanup_sdb;
}
sgp->pool = mempool_create_slab_pool(SG_MEMPOOL_SIZE,
if (!sgp->pool) {
printk(KERN_ERR "SCSI: can't init sg mempool %s\n",
sgp->name);
- goto cleanup_bidi_sdb;
+ goto cleanup_sdb;
}
}
return 0;
-cleanup_bidi_sdb:
+cleanup_sdb:
for (i = 0; i < SG_MEMPOOL_NR; i++) {
struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
if (sgp->pool)
if (sgp->slab)
kmem_cache_destroy(sgp->slab);
}
- kmem_cache_destroy(scsi_bidi_sdb_cache);
+ kmem_cache_destroy(scsi_sdb_cache);
cleanup_io_context:
kmem_cache_destroy(scsi_io_context_cache);
int i;
kmem_cache_destroy(scsi_io_context_cache);
- kmem_cache_destroy(scsi_bidi_sdb_cache);
+ kmem_cache_destroy(scsi_sdb_cache);
for (i = 0; i < SG_MEMPOOL_NR; i++) {
struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;