summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r--drivers/scsi/scsi_lib.c49
1 files changed, 26 insertions, 23 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 1646fe7cbd4b..eafeeda6e194 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -85,7 +85,7 @@ static void scsi_unprep_request(struct request *req)
{
struct scsi_cmnd *cmd = req->special;
- req->cmd_flags &= ~REQ_DONTPREP;
+ blk_unprep_request(req);
req->special = NULL;
scsi_put_command(cmd);
@@ -722,7 +722,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
sense_deferred = scsi_sense_is_deferred(&sshdr);
}
- if (blk_pc_request(req)) { /* SG_IO ioctl from block level */
+ if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */
req->errors = result;
if (result) {
if (sense_valid && req->sense) {
@@ -757,7 +757,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
}
}
- BUG_ON(blk_bidi_rq(req)); /* bidi not support for !blk_pc_request yet */
+ /* no bidi support for !REQ_TYPE_BLOCK_PC yet */
+ BUG_ON(blk_bidi_rq(req));
/*
* Next deal with any sectors which we were able to correctly
@@ -967,11 +968,13 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb,
*/
int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask)
{
- int error = scsi_init_sgtable(cmd->request, &cmd->sdb, gfp_mask);
+ struct request *rq = cmd->request;
+
+ int error = scsi_init_sgtable(rq, &cmd->sdb, gfp_mask);
if (error)
goto err_exit;
- if (blk_bidi_rq(cmd->request)) {
+ if (blk_bidi_rq(rq)) {
struct scsi_data_buffer *bidi_sdb = kmem_cache_zalloc(
scsi_sdb_cache, GFP_ATOMIC);
if (!bidi_sdb) {
@@ -979,28 +982,28 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask)
goto err_exit;
}
- cmd->request->next_rq->special = bidi_sdb;
- error = scsi_init_sgtable(cmd->request->next_rq, bidi_sdb,
- GFP_ATOMIC);
+ rq->next_rq->special = bidi_sdb;
+ error = scsi_init_sgtable(rq->next_rq, bidi_sdb, GFP_ATOMIC);
if (error)
goto err_exit;
}
- if (blk_integrity_rq(cmd->request)) {
+ if (blk_integrity_rq(rq)) {
struct scsi_data_buffer *prot_sdb = cmd->prot_sdb;
int ivecs, count;
BUG_ON(prot_sdb == NULL);
- ivecs = blk_rq_count_integrity_sg(cmd->request);
+ ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio);
if (scsi_alloc_sgtable(prot_sdb, ivecs, gfp_mask)) {
error = BLKPREP_DEFER;
goto err_exit;
}
- count = blk_rq_map_integrity_sg(cmd->request,
+ count = blk_rq_map_integrity_sg(rq->q, rq->bio,
prot_sdb->table.sgl);
BUG_ON(unlikely(count > ivecs));
+ BUG_ON(unlikely(count > queue_max_integrity_segments(rq->q)));
cmd->prot_sdb = prot_sdb;
cmd->prot_sdb->table.nents = count;
@@ -1010,11 +1013,8 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask)
err_exit:
scsi_release_buffers(cmd);
- if (error == BLKPREP_KILL)
- scsi_put_command(cmd);
- else /* BLKPREP_DEFER */
- scsi_unprep_request(cmd->request);
-
+ cmd->request->special = NULL;
+ scsi_put_command(cmd);
return error;
}
EXPORT_SYMBOL(scsi_init_io);
@@ -1372,12 +1372,6 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
blk_start_request(req);
- if (unlikely(cmd == NULL)) {
- printk(KERN_CRIT "impossible request in %s.\n",
- __func__);
- BUG();
- }
-
sdev = cmd->device;
starget = scsi_target(sdev);
shost = sdev->host;
@@ -1633,6 +1627,14 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
blk_queue_max_segments(q, min_t(unsigned short, shost->sg_tablesize,
SCSI_MAX_SG_CHAIN_SEGMENTS));
+ if (scsi_host_prot_dma(shost)) {
+ shost->sg_prot_tablesize =
+ min_not_zero(shost->sg_prot_tablesize,
+ (unsigned short)SCSI_MAX_PROT_SG_SEGMENTS);
+ BUG_ON(shost->sg_prot_tablesize < shost->sg_tablesize);
+ blk_queue_max_integrity_segments(q, shost->sg_prot_tablesize);
+ }
+
blk_queue_max_hw_sectors(q, shost->max_sectors);
blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
blk_queue_segment_boundary(q, shost->dma_boundary);
@@ -2436,7 +2438,8 @@ scsi_internal_device_unblock(struct scsi_device *sdev)
sdev->sdev_state = SDEV_RUNNING;
else if (sdev->sdev_state == SDEV_CREATED_BLOCK)
sdev->sdev_state = SDEV_CREATED;
- else
+ else if (sdev->sdev_state != SDEV_CANCEL &&
+ sdev->sdev_state != SDEV_OFFLINE)
return -EINVAL;
spin_lock_irqsave(q->queue_lock, flags);