diff options
| -rw-r--r-- | drivers/scsi/st.c | 254 | ||||
| -rw-r--r-- | drivers/scsi/st.h | 14 |
2 files changed, 123 insertions, 145 deletions
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 053444b027d4..26e13dc7bcdb 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
| @@ -50,7 +50,6 @@ static const char *verstr = "20050830"; | |||
| 50 | #include <scsi/scsi_eh.h> | 50 | #include <scsi/scsi_eh.h> |
| 51 | #include <scsi/scsi_host.h> | 51 | #include <scsi/scsi_host.h> |
| 52 | #include <scsi/scsi_ioctl.h> | 52 | #include <scsi/scsi_ioctl.h> |
| 53 | #include <scsi/scsi_request.h> | ||
| 54 | #include <scsi/sg.h> | 53 | #include <scsi/sg.h> |
| 55 | 54 | ||
| 56 | 55 | ||
| @@ -188,8 +187,6 @@ static int from_buffer(struct st_buffer *, char __user *, int); | |||
| 188 | static void move_buffer_data(struct st_buffer *, int); | 187 | static void move_buffer_data(struct st_buffer *, int); |
| 189 | static void buf_to_sg(struct st_buffer *, unsigned int); | 188 | static void buf_to_sg(struct st_buffer *, unsigned int); |
| 190 | 189 | ||
| 191 | static int st_map_user_pages(struct scatterlist *, const unsigned int, | ||
| 192 | unsigned long, size_t, int, unsigned long); | ||
| 193 | static int sgl_map_user_pages(struct scatterlist *, const unsigned int, | 190 | static int sgl_map_user_pages(struct scatterlist *, const unsigned int, |
| 194 | unsigned long, size_t, int); | 191 | unsigned long, size_t, int); |
| 195 | static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int); | 192 | static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int); |
| @@ -313,12 +310,13 @@ static inline char *tape_name(struct scsi_tape *tape) | |||
| 313 | } | 310 | } |
| 314 | 311 | ||
| 315 | 312 | ||
| 316 | static void st_analyze_sense(struct scsi_request *SRpnt, struct st_cmdstatus *s) | 313 | static void st_analyze_sense(struct st_request *SRpnt, struct st_cmdstatus *s) |
| 317 | { | 314 | { |
| 318 | const u8 *ucp; | 315 | const u8 *ucp; |
| 319 | const u8 *sense = SRpnt->sr_sense_buffer; | 316 | const u8 *sense = SRpnt->sense; |
| 320 | 317 | ||
| 321 | s->have_sense = scsi_request_normalize_sense(SRpnt, &s->sense_hdr); | 318 | s->have_sense = scsi_normalize_sense(SRpnt->sense, |
| 319 | SCSI_SENSE_BUFFERSIZE, &s->sense_hdr); | ||
| 322 | s->flags = 0; | 320 | s->flags = 0; |
| 323 | 321 | ||
| 324 | if (s->have_sense) { | 322 | if (s->have_sense) { |
| @@ -345,9 +343,9 @@ static void st_analyze_sense(struct scsi_request *SRpnt, struct st_cmdstatus *s) | |||
| 345 | 343 | ||
| 346 | 344 | ||
| 347 | /* Convert the result to success code */ | 345 | /* Convert the result to success code */ |
| 348 | static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt) | 346 | static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt) |
| 349 | { | 347 | { |
| 350 | int result = SRpnt->sr_result; | 348 | int result = SRpnt->result; |
| 351 | u8 scode; | 349 | u8 scode; |
| 352 | DEB(const char *stp;) | 350 | DEB(const char *stp;) |
| 353 | char *name = tape_name(STp); | 351 | char *name = tape_name(STp); |
| @@ -366,13 +364,12 @@ static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt) | |||
| 366 | 364 | ||
| 367 | DEB( | 365 | DEB( |
| 368 | if (debugging) { | 366 | if (debugging) { |
| 369 | printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x Len: %d\n", | 367 | printk(ST_DEB_MSG "%s: Error: %x, cmd: %x %x %x %x %x %x\n", |
| 370 | name, result, | 368 | name, result, |
| 371 | SRpnt->sr_cmnd[0], SRpnt->sr_cmnd[1], SRpnt->sr_cmnd[2], | 369 | SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2], |
| 372 | SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5], | 370 | SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]); |
| 373 | SRpnt->sr_bufflen); | ||
| 374 | if (cmdstatp->have_sense) | 371 | if (cmdstatp->have_sense) |
| 375 | scsi_print_req_sense("st", SRpnt); | 372 | __scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); |
| 376 | } ) /* end DEB */ | 373 | } ) /* end DEB */ |
| 377 | if (!debugging) { /* Abnormal conditions for tape */ | 374 | if (!debugging) { /* Abnormal conditions for tape */ |
| 378 | if (!cmdstatp->have_sense) | 375 | if (!cmdstatp->have_sense) |
| @@ -386,20 +383,21 @@ static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt) | |||
| 386 | /* scode != UNIT_ATTENTION && */ | 383 | /* scode != UNIT_ATTENTION && */ |
| 387 | scode != BLANK_CHECK && | 384 | scode != BLANK_CHECK && |
| 388 | scode != VOLUME_OVERFLOW && | 385 | scode != VOLUME_OVERFLOW && |
| 389 | SRpnt->sr_cmnd[0] != MODE_SENSE && | 386 | SRpnt->cmd[0] != MODE_SENSE && |
| 390 | SRpnt->sr_cmnd[0] != TEST_UNIT_READY) { | 387 | SRpnt->cmd[0] != TEST_UNIT_READY) { |
| 391 | printk(KERN_WARNING "%s: Error with sense data: ", name); | 388 | printk(KERN_WARNING "%s: Error with sense data: ", name); |
| 392 | scsi_print_req_sense("st", SRpnt); | 389 | __scsi_print_sense("st", SRpnt->sense, |
| 390 | SCSI_SENSE_BUFFERSIZE); | ||
| 393 | } | 391 | } |
| 394 | } | 392 | } |
| 395 | 393 | ||
| 396 | if (cmdstatp->fixed_format && | 394 | if (cmdstatp->fixed_format && |
| 397 | STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */ | 395 | STp->cln_mode >= EXTENDED_SENSE_START) { /* Only fixed format sense */ |
| 398 | if (STp->cln_sense_value) | 396 | if (STp->cln_sense_value) |
| 399 | STp->cleaning_req |= ((SRpnt->sr_sense_buffer[STp->cln_mode] & | 397 | STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] & |
| 400 | STp->cln_sense_mask) == STp->cln_sense_value); | 398 | STp->cln_sense_mask) == STp->cln_sense_value); |
| 401 | else | 399 | else |
| 402 | STp->cleaning_req |= ((SRpnt->sr_sense_buffer[STp->cln_mode] & | 400 | STp->cleaning_req |= ((SRpnt->sense[STp->cln_mode] & |
| 403 | STp->cln_sense_mask) != 0); | 401 | STp->cln_sense_mask) != 0); |
| 404 | } | 402 | } |
| 405 | if (cmdstatp->have_sense && | 403 | if (cmdstatp->have_sense && |
| @@ -411,8 +409,8 @@ static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt) | |||
| 411 | if (cmdstatp->have_sense && | 409 | if (cmdstatp->have_sense && |
| 412 | scode == RECOVERED_ERROR | 410 | scode == RECOVERED_ERROR |
| 413 | #if ST_RECOVERED_WRITE_FATAL | 411 | #if ST_RECOVERED_WRITE_FATAL |
| 414 | && SRpnt->sr_cmnd[0] != WRITE_6 | 412 | && SRpnt->cmd[0] != WRITE_6 |
| 415 | && SRpnt->sr_cmnd[0] != WRITE_FILEMARKS | 413 | && SRpnt->cmd[0] != WRITE_FILEMARKS |
| 416 | #endif | 414 | #endif |
| 417 | ) { | 415 | ) { |
| 418 | STp->recover_count++; | 416 | STp->recover_count++; |
| @@ -420,9 +418,9 @@ static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt) | |||
| 420 | 418 | ||
| 421 | DEB( | 419 | DEB( |
| 422 | if (debugging) { | 420 | if (debugging) { |
| 423 | if (SRpnt->sr_cmnd[0] == READ_6) | 421 | if (SRpnt->cmd[0] == READ_6) |
| 424 | stp = "read"; | 422 | stp = "read"; |
| 425 | else if (SRpnt->sr_cmnd[0] == WRITE_6) | 423 | else if (SRpnt->cmd[0] == WRITE_6) |
| 426 | stp = "write"; | 424 | stp = "write"; |
| 427 | else | 425 | else |
| 428 | stp = "ioctl"; | 426 | stp = "ioctl"; |
| @@ -438,28 +436,37 @@ static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt) | |||
| 438 | 436 | ||
| 439 | 437 | ||
| 440 | /* Wakeup from interrupt */ | 438 | /* Wakeup from interrupt */ |
| 441 | static void st_sleep_done(struct scsi_cmnd * SCpnt) | 439 | static void st_sleep_done(void *data, char *sense, int result, int resid) |
| 442 | { | 440 | { |
| 443 | struct scsi_tape *STp = container_of(SCpnt->request->rq_disk->private_data, | 441 | struct st_request *SRpnt = data; |
| 444 | struct scsi_tape, driver); | 442 | struct scsi_tape *STp = SRpnt->stp; |
| 445 | 443 | ||
| 446 | (STp->buffer)->cmdstat.midlevel_result = SCpnt->result; | 444 | memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE); |
| 447 | SCpnt->request->rq_status = RQ_SCSI_DONE; | 445 | (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result; |
| 448 | DEB( STp->write_pending = 0; ) | 446 | DEB( STp->write_pending = 0; ) |
| 449 | 447 | ||
| 450 | if (SCpnt->request->waiting) | 448 | if (SRpnt->waiting) |
| 451 | complete(SCpnt->request->waiting); | 449 | complete(SRpnt->waiting); |
| 450 | } | ||
| 451 | |||
| 452 | static struct st_request *st_allocate_request(void) | ||
| 453 | { | ||
| 454 | return kzalloc(sizeof(struct st_request), GFP_KERNEL); | ||
| 455 | } | ||
| 456 | |||
| 457 | static void st_release_request(struct st_request *streq) | ||
| 458 | { | ||
| 459 | kfree(streq); | ||
| 452 | } | 460 | } |
| 453 | 461 | ||
| 454 | /* Do the scsi command. Waits until command performed if do_wait is true. | 462 | /* Do the scsi command. Waits until command performed if do_wait is true. |
| 455 | Otherwise write_behind_check() is used to check that the command | 463 | Otherwise write_behind_check() is used to check that the command |
| 456 | has finished. */ | 464 | has finished. */ |
| 457 | static struct scsi_request * | 465 | static struct st_request * |
| 458 | st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd, | 466 | st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd, |
| 459 | int bytes, int direction, int timeout, int retries, int do_wait) | 467 | int bytes, int direction, int timeout, int retries, int do_wait) |
| 460 | { | 468 | { |
| 461 | struct completion *waiting; | 469 | struct completion *waiting; |
| 462 | unsigned char *bp; | ||
| 463 | 470 | ||
| 464 | /* if async, make sure there's no command outstanding */ | 471 | /* if async, make sure there's no command outstanding */ |
| 465 | if (!do_wait && ((STp->buffer)->last_SRpnt)) { | 472 | if (!do_wait && ((STp->buffer)->last_SRpnt)) { |
| @@ -473,7 +480,7 @@ st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *c | |||
