Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 68904
b: refs/heads/master
c: 7f9a6bc
h: refs/heads/master
v: v3
  • Loading branch information
James Bottomley authored and James Bottomley committed Oct 12, 2007
1 parent e9db60b commit 0e596d3
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 83 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d3849d512fb0ca1e369e3efcaec910a949f55f62
refs/heads/master: 7f9a6bc4e9d59e7fcf03ed23f60cd81ca5d80b65
84 changes: 37 additions & 47 deletions trunk/drivers/scsi/scsi_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1039,9 +1039,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
printk(KERN_ERR "req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors,
req->current_nr_sectors);

/* release the command and kill it */
scsi_release_buffers(cmd);
scsi_put_command(cmd);
return BLKPREP_KILL;
}

Expand Down Expand Up @@ -1078,9 +1075,13 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
scsi_io_completion(cmd, cmd->request_bufflen);
}

static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
{
struct scsi_cmnd *cmd;
int ret = scsi_prep_state_check(sdev, req);

if (ret != BLKPREP_OK)
return ret;

cmd = scsi_get_cmd_from_req(sdev, req);
if (unlikely(!cmd))
Expand Down Expand Up @@ -1126,18 +1127,20 @@ static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
cmd->done = scsi_blk_pc_done;
return BLKPREP_OK;
}
EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd);

/*
* Setup a REQ_TYPE_FS command. These are simple read/write request
* from filesystems that still need to be translated to SCSI CDBs from
* the ULD.
*/
static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
{
struct scsi_cmnd *cmd;
struct scsi_driver *drv;
int ret;
int ret = scsi_prep_state_check(sdev, req);

if (ret != BLKPREP_OK)
return ret;
/*
* Filesystem requests must transfer data.
*/
Expand All @@ -1147,26 +1150,12 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
if (unlikely(!cmd))
return BLKPREP_DEFER;

ret = scsi_init_io(cmd);
if (unlikely(ret))
return ret;

/*
* Initialize the actual SCSI command for this request.
*/
drv = *(struct scsi_driver **)req->rq_disk->private_data;
if (unlikely(!drv->init_command(cmd))) {
scsi_release_buffers(cmd);
scsi_put_command(cmd);
return BLKPREP_KILL;
}

return BLKPREP_OK;
return scsi_init_io(cmd);
}
EXPORT_SYMBOL(scsi_setup_fs_cmnd);

static int scsi_prep_fn(struct request_queue *q, struct request *req)
int scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
{
struct scsi_device *sdev = q->queuedata;
int ret = BLKPREP_OK;

/*
Expand Down Expand Up @@ -1212,35 +1201,25 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
ret = BLKPREP_KILL;
break;
}

if (ret != BLKPREP_OK)
goto out;
}
return ret;
}
EXPORT_SYMBOL(scsi_prep_state_check);

switch (req->cmd_type) {
case REQ_TYPE_BLOCK_PC:
ret = scsi_setup_blk_pc_cmnd(sdev, req);
break;
case REQ_TYPE_FS:
ret = scsi_setup_fs_cmnd(sdev, req);
break;
default:
/*
* All other command types are not supported.
*
* Note that these days the SCSI subsystem does not use
* REQ_TYPE_SPECIAL requests anymore. These are only used
* (directly or via blk_insert_request) by non-SCSI drivers.
*/
blk_dump_rq_flags(req, "SCSI bad req");
ret = BLKPREP_KILL;
break;
}
int scsi_prep_return(struct request_queue *q, struct request *req, int ret)
{
struct scsi_device *sdev = q->queuedata;

out:
switch (ret) {
case BLKPREP_KILL:
req->errors = DID_NO_CONNECT << 16;
/* release the command and kill it */
if (req->special) {
struct scsi_cmnd *cmd = req->special;
scsi_release_buffers(cmd);
scsi_put_command(cmd);
req->special = NULL;
}
break;
case BLKPREP_DEFER:
/*
Expand All @@ -1257,6 +1236,17 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)

return ret;
}
EXPORT_SYMBOL(scsi_prep_return);

static int scsi_prep_fn(struct request_queue *q, struct request *req)
{
struct scsi_device *sdev = q->queuedata;
int ret = BLKPREP_KILL;

if (req->cmd_type == REQ_TYPE_BLOCK_PC)
ret = scsi_setup_blk_pc_cmnd(sdev, req);
return scsi_prep_return(q, req, ret);
}

/*
* scsi_dev_queue_ready: if we can send requests to sdev, return 1 else
Expand Down
48 changes: 34 additions & 14 deletions trunk/drivers/scsi/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@ static struct scsi_driver sd_template = {
.shutdown = sd_shutdown,
},
.rescan = sd_rescan,
.init_command = sd_init_command,
};

/*
Expand Down Expand Up @@ -331,14 +330,31 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
*
* Returns 1 if successful and 0 if error (or cannot be done now).
**/
static int sd_init_command(struct scsi_cmnd * SCpnt)
static int sd_prep_fn(struct request_queue *q, struct request *rq)
{
struct scsi_device *sdp = SCpnt->device;
struct request *rq = SCpnt->request;
struct scsi_cmnd *SCpnt;
struct scsi_device *sdp = q->queuedata;
struct gendisk *disk = rq->rq_disk;
sector_t block = rq->sector;
unsigned int this_count = SCpnt->request_bufflen >> 9;
unsigned int this_count = rq->nr_sectors;
unsigned int timeout = sdp->timeout;
int ret;

if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
ret = scsi_setup_blk_pc_cmnd(sdp, rq);
goto out;
} else if (rq->cmd_type != REQ_TYPE_FS) {
ret = BLKPREP_KILL;
goto out;
}
ret = scsi_setup_fs_cmnd(sdp, rq);
if (ret != BLKPREP_OK)
goto out;
SCpnt = rq->special;

/* from here on until we're complete, any goto out
* is used for a killable error condition */
ret = BLKPREP_KILL;

SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt,
"sd_init_command: block=%llu, "
Expand All @@ -353,7 +369,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
rq->nr_sectors));
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
"Retry with 0x%p\n", SCpnt));
return 0;
goto out;
}

if (sdp->changed) {
Expand All @@ -362,8 +378,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
* the changed bit has been reset
*/
/* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */
return 0;
goto out;
}

SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n",
(unsigned long long)block));

Expand All @@ -382,7 +399,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
if ((block & 1) || (rq->nr_sectors & 1)) {
scmd_printk(KERN_ERR, SCpnt,
"Bad block number requested\n");
return 0;
goto out;
} else {
block = block >> 1;
this_count = this_count >> 1;
Expand All @@ -392,7 +409,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
if ((block & 3) || (rq->nr_sectors & 3)) {
scmd_printk(KERN_ERR, SCpnt,
"Bad block number requested\n");
return 0;
goto out;
} else {
block = block >> 2;
this_count = this_count >> 2;
Expand All @@ -402,15 +419,15 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
if ((block & 7) || (rq->nr_sectors & 7)) {
scmd_printk(KERN_ERR, SCpnt,
"Bad block number requested\n");
return 0;
goto out;
} else {
block = block >> 3;
this_count = this_count >> 3;
}
}
if (rq_data_dir(rq) == WRITE) {
if (!sdp->writeable) {
return 0;
goto out;
}
SCpnt->cmnd[0] = WRITE_6;
SCpnt->sc_data_direction = DMA_TO_DEVICE;
Expand All @@ -419,7 +436,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
SCpnt->sc_data_direction = DMA_FROM_DEVICE;
} else {
scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags);
return 0;
goto out;
}

SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
Expand Down Expand Up @@ -470,7 +487,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
*/
scmd_printk(KERN_ERR, SCpnt,
"FUA write on READ/WRITE(6) drive\n");
return 0;
goto out;
}

SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f);
Expand Down Expand Up @@ -501,7 +518,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
* This indicates that the command is ready from our end to be
* queued.
*/
return 1;
ret = BLKPREP_OK;
out:
return scsi_prep_return(q, rq, ret);
}

/**
Expand Down Expand Up @@ -1669,6 +1688,7 @@ static int sd_probe(struct device *dev)

sd_revalidate_disk(gd);

blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush);

gd->driverfs_dev = &sdp->sdev_gendev;
Expand Down
Loading

0 comments on commit 0e596d3

Please sign in to comment.