mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-07 23:28:55 +00:00
[SCSI] convert sr to scsi_execute_req
This follows almost the identical model to sd, except that there's one ioctl which returns raw sense data, so it had to use scsi_execute() instead. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
parent
ea73a9f239
commit
820732b501
2 changed files with 37 additions and 74 deletions
|
@ -50,10 +50,10 @@
|
||||||
#include <scsi/scsi_dbg.h>
|
#include <scsi/scsi_dbg.h>
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
#include <scsi/scsi_driver.h>
|
#include <scsi/scsi_driver.h>
|
||||||
|
#include <scsi/scsi_cmnd.h>
|
||||||
#include <scsi/scsi_eh.h>
|
#include <scsi/scsi_eh.h>
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
#include <scsi/scsi_ioctl.h> /* For the door lock/unlock commands */
|
#include <scsi/scsi_ioctl.h> /* For the door lock/unlock commands */
|
||||||
#include <scsi/scsi_request.h>
|
|
||||||
|
|
||||||
#include "scsi_logging.h"
|
#include "scsi_logging.h"
|
||||||
#include "sr.h"
|
#include "sr.h"
|
||||||
|
@ -658,39 +658,27 @@ static void get_sectorsize(struct scsi_cd *cd)
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
int the_result, retries = 3;
|
int the_result, retries = 3;
|
||||||
int sector_size;
|
int sector_size;
|
||||||
struct scsi_request *SRpnt = NULL;
|
|
||||||
request_queue_t *queue;
|
request_queue_t *queue;
|
||||||
|
|
||||||
buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
|
buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
goto Enomem;
|
goto Enomem;
|
||||||
SRpnt = scsi_allocate_request(cd->device, GFP_KERNEL);
|
|
||||||
if (!SRpnt)
|
|
||||||
goto Enomem;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
cmd[0] = READ_CAPACITY;
|
cmd[0] = READ_CAPACITY;
|
||||||
memset((void *) &cmd[1], 0, 9);
|
memset((void *) &cmd[1], 0, 9);
|
||||||
/* Mark as really busy */
|
|
||||||
SRpnt->sr_request->rq_status = RQ_SCSI_BUSY;
|
|
||||||
SRpnt->sr_cmd_len = 0;
|
|
||||||
|
|
||||||
memset(buffer, 0, 8);
|
memset(buffer, 0, 8);
|
||||||
|
|
||||||
/* Do the command and wait.. */
|
/* Do the command and wait.. */
|
||||||
SRpnt->sr_data_direction = DMA_FROM_DEVICE;
|
the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE,
|
||||||
scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
|
buffer, 8, NULL, SR_TIMEOUT,
|
||||||
8, SR_TIMEOUT, MAX_RETRIES);
|
MAX_RETRIES);
|
||||||
|
|
||||||
the_result = SRpnt->sr_result;
|
|
||||||
retries--;
|
retries--;
|
||||||
|
|
||||||
} while (the_result && retries);
|
} while (the_result && retries);
|
||||||
|
|
||||||
|
|
||||||
scsi_release_request(SRpnt);
|
|
||||||
SRpnt = NULL;
|
|
||||||
|
|
||||||
if (the_result) {
|
if (the_result) {
|
||||||
cd->capacity = 0x1fffff;
|
cd->capacity = 0x1fffff;
|
||||||
sector_size = 2048; /* A guess, just in case */
|
sector_size = 2048; /* A guess, just in case */
|
||||||
|
@ -750,8 +738,6 @@ Enomem:
|
||||||
cd->capacity = 0x1fffff;
|
cd->capacity = 0x1fffff;
|
||||||
sector_size = 2048; /* A guess, just in case */
|
sector_size = 2048; /* A guess, just in case */
|
||||||
cd->needs_sector_size = 1;
|
cd->needs_sector_size = 1;
|
||||||
if (SRpnt)
|
|
||||||
scsi_release_request(SRpnt);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,8 +745,8 @@ static void get_capabilities(struct scsi_cd *cd)
|
||||||
{
|
{
|
||||||
unsigned char *buffer;
|
unsigned char *buffer;
|
||||||
struct scsi_mode_data data;
|
struct scsi_mode_data data;
|
||||||
struct scsi_request *SRpnt;
|
|
||||||
unsigned char cmd[MAX_COMMAND_SIZE];
|
unsigned char cmd[MAX_COMMAND_SIZE];
|
||||||
|
struct scsi_sense_hdr sshdr;
|
||||||
unsigned int the_result;
|
unsigned int the_result;
|
||||||
int retries, rc, n;
|
int retries, rc, n;
|
||||||
|
|
||||||
|
@ -776,19 +762,11 @@ static void get_capabilities(struct scsi_cd *cd)
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
/* allocate a request for the TEST_UNIT_READY */
|
|
||||||
SRpnt = scsi_allocate_request(cd->device, GFP_KERNEL);
|
|
||||||
if (!SRpnt) {
|
|
||||||
printk(KERN_WARNING "(get_capabilities:) Request allocation "
|
|
||||||
"failure.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate transfer buffer */
|
/* allocate transfer buffer */
|
||||||
buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
|
buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
printk(KERN_ERR "sr: out of memory.\n");
|
printk(KERN_ERR "sr: out of memory.\n");
|
||||||
scsi_release_request(SRpnt);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -800,20 +778,15 @@ static void get_capabilities(struct scsi_cd *cd)
|
||||||
memset((void *)cmd, 0, MAX_COMMAND_SIZE);
|
memset((void *)cmd, 0, MAX_COMMAND_SIZE);
|
||||||
cmd[0] = TEST_UNIT_READY;
|
cmd[0] = TEST_UNIT_READY;
|
||||||
|
|
||||||
SRpnt->sr_cmd_len = 0;
|
the_result = scsi_execute_req (cd->device, cmd, DMA_NONE, NULL,
|
||||||
SRpnt->sr_sense_buffer[0] = 0;
|
0, &sshdr, SR_TIMEOUT,
|
||||||
SRpnt->sr_sense_buffer[2] = 0;
|
MAX_RETRIES);
|
||||||
SRpnt->sr_data_direction = DMA_NONE;
|
|
||||||
|
|
||||||
scsi_wait_req (SRpnt, (void *) cmd, buffer,
|
|
||||||
0, SR_TIMEOUT, MAX_RETRIES);
|
|
||||||
|
|
||||||
the_result = SRpnt->sr_result;
|
|
||||||
retries++;
|
retries++;
|
||||||
} while (retries < 5 &&
|
} while (retries < 5 &&
|
||||||
(!scsi_status_is_good(the_result) ||
|
(!scsi_status_is_good(the_result) ||
|
||||||
((driver_byte(the_result) & DRIVER_SENSE) &&
|
(scsi_sense_valid(&sshdr) &&
|
||||||
SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION)));
|
sshdr.sense_key == UNIT_ATTENTION)));
|
||||||
|
|
||||||
/* ask for mode page 0x2a */
|
/* ask for mode page 0x2a */
|
||||||
rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
|
rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
|
||||||
|
@ -825,7 +798,6 @@ static void get_capabilities(struct scsi_cd *cd)
|
||||||
cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
|
cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
|
||||||
CDC_DVD | CDC_DVD_RAM |
|
CDC_DVD | CDC_DVD_RAM |
|
||||||
CDC_SELECT_DISC | CDC_SELECT_SPEED);
|
CDC_SELECT_DISC | CDC_SELECT_SPEED);
|
||||||
scsi_release_request(SRpnt);
|
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
printk("%s: scsi-1 drive\n", cd->cdi.name);
|
printk("%s: scsi-1 drive\n", cd->cdi.name);
|
||||||
return;
|
return;
|
||||||
|
@ -885,7 +857,6 @@ static void get_capabilities(struct scsi_cd *cd)
|
||||||
cd->device->writeable = 1;
|
cd->device->writeable = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_release_request(SRpnt);
|
|
||||||
kfree(buffer);
|
kfree(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <scsi/scsi_eh.h>
|
#include <scsi/scsi_eh.h>
|
||||||
#include <scsi/scsi_host.h>
|
#include <scsi/scsi_host.h>
|
||||||
#include <scsi/scsi_ioctl.h>
|
#include <scsi/scsi_ioctl.h>
|
||||||
#include <scsi/scsi_request.h>
|
#include <scsi/scsi_cmnd.h>
|
||||||
|
|
||||||
#include "sr.h"
|
#include "sr.h"
|
||||||
|
|
||||||
|
@ -84,41 +84,37 @@ static int sr_fake_playtrkind(struct cdrom_device_info *cdi, struct cdrom_ti *ti
|
||||||
|
|
||||||
int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
|
int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
|
||||||
{
|
{
|
||||||
struct scsi_request *SRpnt;
|
|
||||||
struct scsi_device *SDev;
|
struct scsi_device *SDev;
|
||||||
struct request *req;
|
struct scsi_sense_hdr sshdr;
|
||||||
int result, err = 0, retries = 0;
|
int result, err = 0, retries = 0;
|
||||||
|
struct request_sense *sense = cgc->sense;
|
||||||
|
|
||||||
SDev = cd->device;
|
SDev = cd->device;
|
||||||
SRpnt = scsi_allocate_request(SDev, GFP_KERNEL);
|
|
||||||
if (!SRpnt) {
|
if (!sense) {
|
||||||
printk(KERN_ERR "Unable to allocate SCSI request in sr_do_ioctl");
|
sense = kmalloc(sizeof(*sense), GFP_KERNEL);
|
||||||
err = -ENOMEM;
|
if (!sense) {
|
||||||
goto out;
|
err = -ENOMEM;
|
||||||
}
|
goto out;
|
||||||
SRpnt->sr_data_direction = cgc->data_direction;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
if (!scsi_block_when_processing_errors(SDev)) {
|
if (!scsi_block_when_processing_errors(SDev)) {
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto out_free;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
scsi_wait_req(SRpnt, cgc->cmd, cgc->buffer, cgc->buflen,
|
memset(sense, 0, sizeof(*sense));
|
||||||
cgc->timeout, IOCTL_RETRIES);
|
result = scsi_execute(SDev, cgc->cmd, cgc->data_direction,
|
||||||
|
cgc->buffer, cgc->buflen, (char *)sense,
|
||||||
|
cgc->timeout, IOCTL_RETRIES, 0);
|
||||||
|
|
||||||
req = SRpnt->sr_request;
|
scsi_normalize_sense((char *)sense, sizeof(*sense), &sshdr);
|
||||||
if (SRpnt->sr_buffer && req->buffer && SRpnt->sr_buffer != req->buffer) {
|
|
||||||
memcpy(req->buffer, SRpnt->sr_buffer, SRpnt->sr_bufflen);
|
|
||||||
kfree(SRpnt->sr_buffer);
|
|
||||||
SRpnt->sr_buffer = req->buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = SRpnt->sr_result;
|
|
||||||
|
|
||||||
/* Minimal error checking. Ignore cases we know about, and report the rest. */
|
/* Minimal error checking. Ignore cases we know about, and report the rest. */
|
||||||
if (driver_byte(result) != 0) {
|
if (driver_byte(result) != 0) {
|
||||||
switch (SRpnt->sr_sense_buffer[2] & 0xf) {
|
switch (sshdr.sense_key) {
|
||||||
case UNIT_ATTENTION:
|
case UNIT_ATTENTION:
|
||||||
SDev->changed = 1;
|
SDev->changed = 1;
|
||||||
if (!cgc->quiet)
|
if (!cgc->quiet)
|
||||||
|
@ -128,8 +124,8 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
|
||||||
err = -ENOMEDIUM;
|
err = -ENOMEDIUM;
|
||||||
break;
|
break;
|
||||||
case NOT_READY: /* This happens if there is no disc in drive */
|
case NOT_READY: /* This happens if there is no disc in drive */
|
||||||
if (SRpnt->sr_sense_buffer[12] == 0x04 &&
|
if (sshdr.asc == 0x04 &&
|
||||||
SRpnt->sr_sense_buffer[13] == 0x01) {
|
sshdr.ascq == 0x01) {
|
||||||
/* sense: Logical unit is in process of becoming ready */
|
/* sense: Logical unit is in process of becoming ready */
|
||||||
if (!cgc->quiet)
|
if (!cgc->quiet)
|
||||||
printk(KERN_INFO "%s: CDROM not ready yet.\n", cd->cdi.name);
|
printk(KERN_INFO "%s: CDROM not ready yet.\n", cd->cdi.name);
|
||||||
|
@ -146,37 +142,33 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
|
||||||
if (!cgc->quiet)
|
if (!cgc->quiet)
|
||||||
printk(KERN_INFO "%s: CDROM not ready. Make sure there is a disc in the drive.\n", cd->cdi.name);
|
printk(KERN_INFO "%s: CDROM not ready. Make sure there is a disc in the drive.\n", cd->cdi.name);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
scsi_print_req_sense("sr", SRpnt);
|
scsi_print_sense_hdr("sr", &sshdr);
|
||||||
#endif
|
#endif
|
||||||
err = -ENOMEDIUM;
|
err = -ENOMEDIUM;
|
||||||
break;
|
break;
|
||||||
case ILLEGAL_REQUEST:
|
case ILLEGAL_REQUEST:
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
if (SRpnt->sr_sense_buffer[12] == 0x20 &&
|
if (sshdr.asc == 0x20 &&
|
||||||
SRpnt->sr_sense_buffer[13] == 0x00)
|
sshdr.ascq == 0x00)
|
||||||
/* sense: Invalid command operation code */
|
/* sense: Invalid command operation code */
|
||||||
err = -EDRIVE_CANT_DO_THIS;
|
err = -EDRIVE_CANT_DO_THIS;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
__scsi_print_command(cgc->cmd);
|
__scsi_print_command(cgc->cmd);
|
||||||
scsi_print_req_sense("sr", SRpnt);
|
scsi_print_sense_hdr("sr", &sshdr);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk(KERN_ERR "%s: CDROM (ioctl) error, command: ", cd->cdi.name);
|
printk(KERN_ERR "%s: CDROM (ioctl) error, command: ", cd->cdi.name);
|
||||||
__scsi_print_command(cgc->cmd);
|
__scsi_print_command(cgc->cmd);
|
||||||
scsi_print_req_sense("sr", SRpnt);
|
scsi_print_sense_hdr("sr", &sshdr);
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cgc->sense)
|
|
||||||
memcpy(cgc->sense, SRpnt->sr_sense_buffer, sizeof(*cgc->sense));
|
|
||||||
|
|
||||||
/* Wake up a process waiting for device */
|
/* Wake up a process waiting for device */
|
||||||
out_free:
|
|
||||||
scsi_release_request(SRpnt);
|
|
||||||
SRpnt = NULL;
|
|
||||||
out:
|
out:
|
||||||
|
if (!cgc->sense)
|
||||||
|
kfree(sense);
|
||||||
cgc->stat = err;
|
cgc->stat = err;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue