Skip to content

Commit 7f9a6bc

Browse files
James BottomleyJames Bottomley
authored andcommitted
[SCSI] move ULD attachment into the prep function
One of the intents of the block prep function was to allow ULDs to use it for preprocessing. The original SCSI model was to have a single prep function and add a pointer indirect filter to build the necessary commands. This patch reverses that, does away with the init_command field of the scsi_driver structure and makes ULDs attach directly to the prep function instead. The value is really that it allows us to begin to separate the ULDs from the SCSI mid layer (as long as they don't use any core functions---which is hard at the moment---a ULD doesn't even need SCSI to bind). Acked-by: Jens Axboe <[email protected]> Signed-off-by: James Bottomley <[email protected]>
1 parent d3849d5 commit 7f9a6bc

File tree

5 files changed

+119
-82
lines changed

5 files changed

+119
-82
lines changed

drivers/scsi/scsi_lib.c

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,9 +1039,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
10391039
printk(KERN_ERR "req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors,
10401040
req->current_nr_sectors);
10411041

1042-
/* release the command and kill it */
1043-
scsi_release_buffers(cmd);
1044-
scsi_put_command(cmd);
10451042
return BLKPREP_KILL;
10461043
}
10471044

@@ -1078,9 +1075,13 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd)
10781075
scsi_io_completion(cmd, cmd->request_bufflen);
10791076
}
10801077

1081-
static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
1078+
int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
10821079
{
10831080
struct scsi_cmnd *cmd;
1081+
int ret = scsi_prep_state_check(sdev, req);
1082+
1083+
if (ret != BLKPREP_OK)
1084+
return ret;
10841085

10851086
cmd = scsi_get_cmd_from_req(sdev, req);
10861087
if (unlikely(!cmd))
@@ -1126,18 +1127,20 @@ static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
11261127
cmd->done = scsi_blk_pc_done;
11271128
return BLKPREP_OK;
11281129
}
1130+
EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd);
11291131

11301132
/*
11311133
* Setup a REQ_TYPE_FS command. These are simple read/write request
11321134
* from filesystems that still need to be translated to SCSI CDBs from
11331135
* the ULD.
11341136
*/
1135-
static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
1137+
int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
11361138
{
11371139
struct scsi_cmnd *cmd;
1138-
struct scsi_driver *drv;
1139-
int ret;
1140+
int ret = scsi_prep_state_check(sdev, req);
11401141

1142+
if (ret != BLKPREP_OK)
1143+
return ret;
11411144
/*
11421145
* Filesystem requests must transfer data.
11431146
*/
@@ -1147,26 +1150,12 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)
11471150
if (unlikely(!cmd))
11481151
return BLKPREP_DEFER;
11491152

1150-
ret = scsi_init_io(cmd);
1151-
if (unlikely(ret))
1152-
return ret;
1153-
1154-
/*
1155-
* Initialize the actual SCSI command for this request.
1156-
*/
1157-
drv = *(struct scsi_driver **)req->rq_disk->private_data;
1158-
if (unlikely(!drv->init_command(cmd))) {
1159-
scsi_release_buffers(cmd);
1160-
scsi_put_command(cmd);
1161-
return BLKPREP_KILL;
1162-
}
1163-
1164-
return BLKPREP_OK;
1153+
return scsi_init_io(cmd);
11651154
}
1155+
EXPORT_SYMBOL(scsi_setup_fs_cmnd);
11661156

1167-
static int scsi_prep_fn(struct request_queue *q, struct request *req)
1157+
int scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
11681158
{
1169-
struct scsi_device *sdev = q->queuedata;
11701159
int ret = BLKPREP_OK;
11711160

11721161
/*
@@ -1212,35 +1201,25 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
12121201
ret = BLKPREP_KILL;
12131202
break;
12141203
}
1215-
1216-
if (ret != BLKPREP_OK)
1217-
goto out;
12181204
}
1205+
return ret;
1206+
}
1207+
EXPORT_SYMBOL(scsi_prep_state_check);
12191208

1220-
switch (req->cmd_type) {
1221-
case REQ_TYPE_BLOCK_PC:
1222-
ret = scsi_setup_blk_pc_cmnd(sdev, req);
1223-
break;
1224-
case REQ_TYPE_FS:
1225-
ret = scsi_setup_fs_cmnd(sdev, req);
1226-
break;
1227-
default:
1228-
/*
1229-
* All other command types are not supported.
1230-
*
1231-
* Note that these days the SCSI subsystem does not use
1232-
* REQ_TYPE_SPECIAL requests anymore. These are only used
1233-
* (directly or via blk_insert_request) by non-SCSI drivers.
1234-
*/
1235-
blk_dump_rq_flags(req, "SCSI bad req");
1236-
ret = BLKPREP_KILL;
1237-
break;
1238-
}
1209+
int scsi_prep_return(struct request_queue *q, struct request *req, int ret)
1210+
{
1211+
struct scsi_device *sdev = q->queuedata;
12391212

1240-
out:
12411213
switch (ret) {
12421214
case BLKPREP_KILL:
12431215
req->errors = DID_NO_CONNECT << 16;
1216+
/* release the command and kill it */
1217+
if (req->special) {
1218+
struct scsi_cmnd *cmd = req->special;
1219+
scsi_release_buffers(cmd);
1220+
scsi_put_command(cmd);
1221+
req->special = NULL;
1222+
}
12441223
break;
12451224
case BLKPREP_DEFER:
12461225
/*
@@ -1257,6 +1236,17 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req)
12571236

12581237
return ret;
12591238
}
1239+
EXPORT_SYMBOL(scsi_prep_return);
1240+
1241+
static int scsi_prep_fn(struct request_queue *q, struct request *req)
1242+
{
1243+
struct scsi_device *sdev = q->queuedata;
1244+
int ret = BLKPREP_KILL;
1245+
1246+
if (req->cmd_type == REQ_TYPE_BLOCK_PC)
1247+
ret = scsi_setup_blk_pc_cmnd(sdev, req);
1248+
return scsi_prep_return(q, req, ret);
1249+
}
12601250

12611251
/*
12621252
* scsi_dev_queue_ready: if we can send requests to sdev, return 1 else

drivers/scsi/sd.c

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ static struct scsi_driver sd_template = {
240240
.shutdown = sd_shutdown,
241241
},
242242
.rescan = sd_rescan,
243-
.init_command = sd_init_command,
244243
};
245244

246245
/*
@@ -331,14 +330,31 @@ static void scsi_disk_put(struct scsi_disk *sdkp)
331330
*
332331
* Returns 1 if successful and 0 if error (or cannot be done now).
333332
**/
334-
static int sd_init_command(struct scsi_cmnd * SCpnt)
333+
static int sd_prep_fn(struct request_queue *q, struct request *rq)
335334
{
336-
struct scsi_device *sdp = SCpnt->device;
337-
struct request *rq = SCpnt->request;
335+
struct scsi_cmnd *SCpnt;
336+
struct scsi_device *sdp = q->queuedata;
338337
struct gendisk *disk = rq->rq_disk;
339338
sector_t block = rq->sector;
340-
unsigned int this_count = SCpnt->request_bufflen >> 9;
339+
unsigned int this_count = rq->nr_sectors;
341340
unsigned int timeout = sdp->timeout;
341+
int ret;
342+
343+
if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
344+
ret = scsi_setup_blk_pc_cmnd(sdp, rq);
345+
goto out;
346+
} else if (rq->cmd_type != REQ_TYPE_FS) {
347+
ret = BLKPREP_KILL;
348+
goto out;
349+
}
350+
ret = scsi_setup_fs_cmnd(sdp, rq);
351+
if (ret != BLKPREP_OK)
352+
goto out;
353+
SCpnt = rq->special;
354+
355+
/* from here on until we're complete, any goto out
356+
* is used for a killable error condition */
357+
ret = BLKPREP_KILL;
342358

343359
SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt,
344360
"sd_init_command: block=%llu, "
@@ -353,7 +369,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
353369
rq->nr_sectors));
354370
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
355371
"Retry with 0x%p\n", SCpnt));
356-
return 0;
372+
goto out;
357373
}
358374

359375
if (sdp->changed) {
@@ -362,8 +378,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
362378
* the changed bit has been reset
363379
*/
364380
/* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */
365-
return 0;
381+
goto out;
366382
}
383+
367384
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n",
368385
(unsigned long long)block));
369386

@@ -382,7 +399,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
382399
if ((block & 1) || (rq->nr_sectors & 1)) {
383400
scmd_printk(KERN_ERR, SCpnt,
384401
"Bad block number requested\n");
385-
return 0;
402+
goto out;
386403
} else {
387404
block = block >> 1;
388405
this_count = this_count >> 1;
@@ -392,7 +409,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
392409
if ((block & 3) || (rq->nr_sectors & 3)) {
393410
scmd_printk(KERN_ERR, SCpnt,
394411
"Bad block number requested\n");
395-
return 0;
412+
goto out;
396413
} else {
397414
block = block >> 2;
398415
this_count = this_count >> 2;
@@ -402,15 +419,15 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
402419
if ((block & 7) || (rq->nr_sectors & 7)) {
403420
scmd_printk(KERN_ERR, SCpnt,
404421
"Bad block number requested\n");
405-
return 0;
422+
goto out;
406423
} else {
407424
block = block >> 3;
408425
this_count = this_count >> 3;
409426
}
410427
}
411428
if (rq_data_dir(rq) == WRITE) {
412429
if (!sdp->writeable) {
413-
return 0;
430+
goto out;
414431
}
415432
SCpnt->cmnd[0] = WRITE_6;
416433
SCpnt->sc_data_direction = DMA_TO_DEVICE;
@@ -419,7 +436,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
419436
SCpnt->sc_data_direction = DMA_FROM_DEVICE;
420437
} else {
421438
scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags);
422-
return 0;
439+
goto out;
423440
}
424441

425442
SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt,
@@ -470,7 +487,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
470487
*/
471488
scmd_printk(KERN_ERR, SCpnt,
472489
"FUA write on READ/WRITE(6) drive\n");
473-
return 0;
490+
goto out;
474491
}
475492

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

507526
/**
@@ -1669,6 +1688,7 @@ static int sd_probe(struct device *dev)
16691688

16701689
sd_revalidate_disk(gd);
16711690

1691+
blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
16721692
blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush);
16731693

16741694
gd->driverfs_dev = &sdp->sdev_gendev;

0 commit comments

Comments
 (0)