Commit 414633a6 authored by Jens Axboe's avatar Jens Axboe

[PATCH] make SCSI understand REQ_BLOCK_PC

Make SCSI layer understand REQ_BLOCK_PC requests
parent 5a7728c6
......@@ -857,7 +857,7 @@ void scsi_request_fn(request_queue_t * q)
scsi_init_cmd_from_req(SCpnt, SRpnt);
}
} else if (req->flags & REQ_CMD) {
} else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
SRpnt = NULL;
STpnt = scsi_get_request_dev(req);
if (!STpnt) {
......@@ -919,7 +919,7 @@ void scsi_request_fn(request_queue_t * q)
req = NULL;
spin_unlock_irq(q->queue_lock);
if (SCpnt->request->flags & REQ_CMD) {
if (SCpnt->request->flags & (REQ_CMD | REQ_BLOCK_PC)) {
/*
* This will do a couple of things:
* 1) Fill in the actual SCSI command.
......
......@@ -62,16 +62,28 @@ int scsi_init_io(Scsi_Cmnd *SCpnt)
int count, gfp_mask;
/*
* First we need to know how many scatter gather segments are needed.
* non-sg block request. FIXME: check bouncing for isa hosts!
*/
count = req->nr_phys_segments;
if ((req->flags & REQ_BLOCK_PC) && !req->bio) {
/*
* FIXME: isa bouncing
*/
if (SCpnt->host->unchecked_isa_dma)
goto fail;
SCpnt->request_bufflen = req->data_len;
SCpnt->request_buffer = req->data;
req->buffer = req->data;
SCpnt->use_sg = 0;
return 1;
}
/*
* we used to not use scatter-gather for single segment request,
* but now we do (it makes highmem I/O easier to support without
* kmapping pages)
*/
SCpnt->use_sg = count;
SCpnt->use_sg = req->nr_phys_segments;
gfp_mask = GFP_NOIO;
if (in_interrupt()) {
......@@ -111,6 +123,7 @@ int scsi_init_io(Scsi_Cmnd *SCpnt)
/*
* kill it. there should be no leftover blocks in this request
*/
fail:
SCpnt = scsi_end_request(SCpnt, 0, req->nr_sectors);
BUG_ON(SCpnt);
return 0;
......
......@@ -193,6 +193,7 @@ static int sd_ioctl(struct inode * inode, struct file * filp,
Scsi_Device * sdp;
int diskinfo[4];
int dsk_nr = DEVICE_NR(dev);
int error;
SCSI_LOG_IOCTL(1, printk("sd_ioctl: dsk_nr=%d, cmd=0x%x\n",
dsk_nr, cmd));
......@@ -209,6 +210,10 @@ static int sd_ioctl(struct inode * inode, struct file * filp,
if( !scsi_block_when_processing_errors(sdp) )
return -ENODEV;
error = scsi_cmd_ioctl(inode->i_bdev, cmd, arg);
if (error != -ENOTTY)
return error;
switch (cmd)
{
case HDIO_GETGEO: /* Return BIOS disk parameters */
......@@ -299,14 +304,43 @@ static struct gendisk **sd_disks;
**/
static int sd_init_command(Scsi_Cmnd * SCpnt)
{
int dsk_nr, part_nr, this_count;
int dsk_nr, part_nr, this_count, timeout;
sector_t block;
Scsi_Device *sdp;
Scsi_Device *sdp = SCpnt->device;
#if CONFIG_SCSI_LOGGING
char nbuff[6];
#endif
timeout = SD_TIMEOUT;
if (SCpnt->device->type != TYPE_DISK)
timeout = SD_MOD_TIMEOUT;
/*
* these are already setup, just copy cdb basically
*/
if (SCpnt->request->flags & REQ_BLOCK_PC) {
struct request *rq = SCpnt->request;
if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
return 0;
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
if (rq_data_dir(rq) == WRITE)
SCpnt->sc_data_direction = SCSI_DATA_WRITE;
else if (rq->data_len)
SCpnt->sc_data_direction = SCSI_DATA_READ;
else
SCpnt->sc_data_direction = SCSI_DATA_NONE;
this_count = rq->data_len;
if (rq->timeout)
timeout = rq->timeout;
goto queue;
}
/*
* don't support specials for nwo
* we only do REQ_CMD and REQ_BLOCK_PC
*/
if (!(SCpnt->request->flags & REQ_CMD))
return 0;
......@@ -320,7 +354,6 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
SCSI_LOG_HLQUEUE(1, printk("sd_command_init: dsk_nr=%d, block=%llu, "
"count=%d\n", dsk_nr, (unsigned long long)block, this_count));
sdp = SCpnt->device;
/* >>>>> the "(part_nr & 0xf)" excludes 15th partition, why?? */
/* >>>>> this change is not in the lk 2.5 series */
if (part_nr >= (sd_template.dev_max << 4) || (part_nr & 0xf) ||
......@@ -433,12 +466,12 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
* host adapter, it's safe to assume that we can at least transfer
* this many bytes between each connect / disconnect.
*/
queue:
SCpnt->transfersize = sdp->sector_size;
SCpnt->underflow = this_count << 9;
SCpnt->allowed = MAX_RETRIES;
SCpnt->timeout_per_command = (SCpnt->device->type == TYPE_DISK ?
SD_TIMEOUT : SD_MOD_TIMEOUT);
SCpnt->timeout_per_command = timeout;
/*
* This is the completion routine we use. This is matched in terms
......
......@@ -262,7 +262,7 @@ static request_queue_t *sr_find_queue(kdev_t dev)
static int sr_init_command(Scsi_Cmnd * SCpnt)
{
int dev, devm, block=0, this_count, s_size;
int dev, devm, block=0, this_count, s_size, timeout = SR_TIMEOUT;
Scsi_CD *cd;
devm = minor(SCpnt->request->rq_dev);
......@@ -285,6 +285,30 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
return 0;
}
/*
* these are already setup, just copy cdb basically
*/
if (SCpnt->request->flags & REQ_BLOCK_PC) {
struct request *rq = SCpnt->request;
if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd))
return 0;
memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));
if (rq_data_dir(rq) == WRITE)
SCpnt->sc_data_direction = SCSI_DATA_WRITE;
else if (rq->data_len)
SCpnt->sc_data_direction = SCSI_DATA_READ;
else
SCpnt->sc_data_direction = SCSI_DATA_NONE;
this_count = rq->data_len;
if (rq->timeout)
timeout = rq->timeout;
goto queue;
}
if (!(SCpnt->request->flags & REQ_CMD)) {
blk_dump_rq_flags(SCpnt->request, "sr unsup command");
return 0;
......@@ -357,11 +381,12 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
* host adapter, it's safe to assume that we can at least transfer
* this many bytes between each connect / disconnect.
*/
queue:
SCpnt->transfersize = cd->device->sector_size;
SCpnt->underflow = this_count << 9;
SCpnt->allowed = MAX_RETRIES;
SCpnt->timeout_per_command = SR_TIMEOUT;
SCpnt->timeout_per_command = timeout;
/*
* This is the completion routine we use. This is matched in terms
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment