Commit 83a78d9b authored by Peter Chubb's avatar Peter Chubb Committed by Tony Luck

[IA64] Fix simscsi for new SCSI midlayer

The sd driver now uses scsi_execute_req() for almost everything.
scsi_execute_req() converts requests into scatterlists.

Fix the HP SCSI disk simulator to understand scatterlists for
more commands.

Without this patch the current kernel will not boot on the simulator
(the disks are always detected as having no sectors, and so cannot be
mounted).
Signed-off-by: default avatarPeter Chubb <peterc@gelato.unsw.edu.au>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 0fc084ea
...@@ -233,6 +233,23 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode) ...@@ -233,6 +233,23 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512); simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
} }
static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
{
int scatterlen = sc->use_sg;
struct scatterlist *slp;
if (scatterlen == 0)
memcpy(sc->request_buffer, buf, len);
else for (slp = (struct scatterlist *)sc->buffer; scatterlen-- > 0 && len > 0; slp++) {
unsigned thislen = min(len, slp->length);
memcpy(page_address(slp->page) + slp->offset, buf, thislen);
slp++;
len -= thislen;
}
}
static int static int
simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
{ {
...@@ -240,6 +257,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) ...@@ -240,6 +257,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
char fname[MAX_ROOT_LEN+16]; char fname[MAX_ROOT_LEN+16];
size_t disk_size; size_t disk_size;
char *buf; char *buf;
char localbuf[36];
#if DEBUG_SIMSCSI #if DEBUG_SIMSCSI
register long sp asm ("sp"); register long sp asm ("sp");
...@@ -263,7 +281,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) ...@@ -263,7 +281,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
/* disk doesn't exist... */ /* disk doesn't exist... */
break; break;
} }
buf = sc->request_buffer; buf = localbuf;
buf[0] = 0; /* magnetic disk */ buf[0] = 0; /* magnetic disk */
buf[1] = 0; /* not a removable medium */ buf[1] = 0; /* not a removable medium */
buf[2] = 2; /* SCSI-2 compliant device */ buf[2] = 2; /* SCSI-2 compliant device */
...@@ -273,6 +291,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) ...@@ -273,6 +291,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
buf[6] = 0; /* reserved */ buf[6] = 0; /* reserved */
buf[7] = 0; /* various flags */ buf[7] = 0; /* various flags */
memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28); memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28);
simscsi_fillresult(sc, buf, 36);
sc->result = GOOD; sc->result = GOOD;
break; break;
...@@ -304,16 +323,13 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) ...@@ -304,16 +323,13 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
simscsi_readwrite10(sc, SSC_WRITE); simscsi_readwrite10(sc, SSC_WRITE);
break; break;
case READ_CAPACITY: case READ_CAPACITY:
if (desc[target_id] < 0 || sc->request_bufflen < 8) { if (desc[target_id] < 0 || sc->request_bufflen < 8) {
break; break;
} }
buf = sc->request_buffer; buf = localbuf;
disk_size = simscsi_get_disk_size(desc[target_id]); disk_size = simscsi_get_disk_size(desc[target_id]);
/* pretend to be a 1GB disk (partition table contains real stuff): */
buf[0] = (disk_size >> 24) & 0xff; buf[0] = (disk_size >> 24) & 0xff;
buf[1] = (disk_size >> 16) & 0xff; buf[1] = (disk_size >> 16) & 0xff;
buf[2] = (disk_size >> 8) & 0xff; buf[2] = (disk_size >> 8) & 0xff;
...@@ -323,13 +339,14 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) ...@@ -323,13 +339,14 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
buf[5] = 0; buf[5] = 0;
buf[6] = 2; buf[6] = 2;
buf[7] = 0; buf[7] = 0;
simscsi_fillresult(sc, buf, 8);
sc->result = GOOD; sc->result = GOOD;
break; break;
case MODE_SENSE: case MODE_SENSE:
case MODE_SENSE_10: case MODE_SENSE_10:
/* sd.c uses this to determine whether disk does write-caching. */ /* sd.c uses this to determine whether disk does write-caching. */
memset(sc->request_buffer, 0, 128); simscsi_fillresult(sc, (char *)empty_zero_page, sc->request_bufflen);
sc->result = GOOD; sc->result = GOOD;
break; break;
......
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