diff options
Diffstat (limited to 'arch/ia64/hp')
-rw-r--r-- | arch/ia64/hp/sim/simscsi.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c index 56405dbfd739..a18983a3c934 100644 --- a/arch/ia64/hp/sim/simscsi.c +++ b/arch/ia64/hp/sim/simscsi.c | |||
@@ -233,6 +233,23 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode) | |||
233 | simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512); | 233 | simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512); |
234 | } | 234 | } |
235 | 235 | ||
236 | static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len) | ||
237 | { | ||
238 | |||
239 | int scatterlen = sc->use_sg; | ||
240 | struct scatterlist *slp; | ||
241 | |||
242 | if (scatterlen == 0) | ||
243 | memcpy(sc->request_buffer, buf, len); | ||
244 | else for (slp = (struct scatterlist *)sc->buffer; scatterlen-- > 0 && len > 0; slp++) { | ||
245 | unsigned thislen = min(len, slp->length); | ||
246 | |||
247 | memcpy(page_address(slp->page) + slp->offset, buf, thislen); | ||
248 | slp++; | ||
249 | len -= thislen; | ||
250 | } | ||
251 | } | ||
252 | |||
236 | static int | 253 | static int |
237 | simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | 254 | simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) |
238 | { | 255 | { |
@@ -240,6 +257,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
240 | char fname[MAX_ROOT_LEN+16]; | 257 | char fname[MAX_ROOT_LEN+16]; |
241 | size_t disk_size; | 258 | size_t disk_size; |
242 | char *buf; | 259 | char *buf; |
260 | char localbuf[36]; | ||
243 | #if DEBUG_SIMSCSI | 261 | #if DEBUG_SIMSCSI |
244 | register long sp asm ("sp"); | 262 | register long sp asm ("sp"); |
245 | 263 | ||
@@ -263,7 +281,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
263 | /* disk doesn't exist... */ | 281 | /* disk doesn't exist... */ |
264 | break; | 282 | break; |
265 | } | 283 | } |
266 | buf = sc->request_buffer; | 284 | buf = localbuf; |
267 | buf[0] = 0; /* magnetic disk */ | 285 | buf[0] = 0; /* magnetic disk */ |
268 | buf[1] = 0; /* not a removable medium */ | 286 | buf[1] = 0; /* not a removable medium */ |
269 | buf[2] = 2; /* SCSI-2 compliant device */ | 287 | buf[2] = 2; /* SCSI-2 compliant device */ |
@@ -273,6 +291,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
273 | buf[6] = 0; /* reserved */ | 291 | buf[6] = 0; /* reserved */ |
274 | buf[7] = 0; /* various flags */ | 292 | buf[7] = 0; /* various flags */ |
275 | memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28); | 293 | memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28); |
294 | simscsi_fillresult(sc, buf, 36); | ||
276 | sc->result = GOOD; | 295 | sc->result = GOOD; |
277 | break; | 296 | break; |
278 | 297 | ||
@@ -304,16 +323,13 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
304 | simscsi_readwrite10(sc, SSC_WRITE); | 323 | simscsi_readwrite10(sc, SSC_WRITE); |
305 | break; | 324 | break; |
306 | 325 | ||
307 | |||
308 | case READ_CAPACITY: | 326 | case READ_CAPACITY: |
309 | if (desc[target_id] < 0 || sc->request_bufflen < 8) { | 327 | if (desc[target_id] < 0 || sc->request_bufflen < 8) { |
310 | break; | 328 | break; |
311 | } | 329 | } |
312 | buf = sc->request_buffer; | 330 | buf = localbuf; |
313 | |||
314 | disk_size = simscsi_get_disk_size(desc[target_id]); | 331 | disk_size = simscsi_get_disk_size(desc[target_id]); |
315 | 332 | ||
316 | /* pretend to be a 1GB disk (partition table contains real stuff): */ | ||
317 | buf[0] = (disk_size >> 24) & 0xff; | 333 | buf[0] = (disk_size >> 24) & 0xff; |
318 | buf[1] = (disk_size >> 16) & 0xff; | 334 | buf[1] = (disk_size >> 16) & 0xff; |
319 | buf[2] = (disk_size >> 8) & 0xff; | 335 | buf[2] = (disk_size >> 8) & 0xff; |
@@ -323,13 +339,14 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
323 | buf[5] = 0; | 339 | buf[5] = 0; |
324 | buf[6] = 2; | 340 | buf[6] = 2; |
325 | buf[7] = 0; | 341 | buf[7] = 0; |
342 | simscsi_fillresult(sc, buf, 8); | ||
326 | sc->result = GOOD; | 343 | sc->result = GOOD; |
327 | break; | 344 | break; |
328 | 345 | ||
329 | case MODE_SENSE: | 346 | case MODE_SENSE: |
330 | case MODE_SENSE_10: | 347 | case MODE_SENSE_10: |
331 | /* sd.c uses this to determine whether disk does write-caching. */ | 348 | /* sd.c uses this to determine whether disk does write-caching. */ |
332 | memset(sc->request_buffer, 0, 128); | 349 | simscsi_fillresult(sc, (char *)empty_zero_page, sc->request_bufflen); |
333 | sc->result = GOOD; | 350 | sc->result = GOOD; |
334 | break; | 351 | break; |
335 | 352 | ||