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 053444b027d..26e13dc7bcd 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 | |||
473 | } | 480 | } |
474 | 481 | ||
475 | if (SRpnt == NULL) { | 482 | if (SRpnt == NULL) { |
476 | SRpnt = scsi_allocate_request(STp->device, GFP_ATOMIC); | 483 | SRpnt = st_allocate_request(); |
477 | if (SRpnt == NULL) { | 484 | if (SRpnt == NULL) { |
478 | DEBC( printk(KERN_ERR "%s: Can't get SCSI request.\n", | 485 | DEBC( printk(KERN_ERR "%s: Can't get SCSI request.\n", |
479 | tape_name(STp)); ); | 486 | tape_name(STp)); ); |
@@ -483,6 +490,7 @@ st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *c | |||
483 | (STp->buffer)->syscall_result = (-EBUSY); | 490 | (STp->buffer)->syscall_result = (-EBUSY); |
484 | return NULL; | 491 | return NULL; |
485 | } | 492 | } |
493 | SRpnt->stp = STp; | ||
486 | } | 494 | } |
487 | 495 | ||
488 | /* If async IO, set last_SRpnt. This ptr tells write_behind_check | 496 | /* If async IO, set last_SRpnt. This ptr tells write_behind_check |
@@ -492,32 +500,26 @@ st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *c | |||
492 | 500 | ||
493 | waiting = &STp->wait; | 501 | waiting = &STp->wait; |
494 | init_completion(waiting); | 502 | init_completion(waiting); |
495 | SRpnt->sr_use_sg = STp->buffer->do_dio || (bytes > (STp->buffer)->frp[0].length); | 503 | SRpnt->waiting = waiting; |
496 | if (SRpnt->sr_use_sg) { | ||
497 | if (!STp->buffer->do_dio) | ||
498 | buf_to_sg(STp->buffer, bytes); | ||
499 | SRpnt->sr_use_sg = (STp->buffer)->sg_segs; | ||
500 | bp = (char *) &((STp->buffer)->sg[0]); | ||
501 | } else | ||
502 | bp = (STp->buffer)->b_data; | ||
503 | SRpnt->sr_data_direction = direction; | ||
504 | SRpnt->sr_cmd_len = 0; | ||
505 | SRpnt->sr_request->waiting = waiting; | ||
506 | SRpnt->sr_request->rq_status = RQ_SCSI_BUSY; | ||
507 | SRpnt->sr_request->rq_disk = STp->disk; | ||
508 | SRpnt->sr_request->end_io = blk_end_sync_rq; | ||
509 | STp->buffer->cmdstat.have_sense = 0; | ||
510 | 504 | ||
511 | scsi_do_req(SRpnt, (void *) cmd, bp, bytes, | 505 | if (!STp->buffer->do_dio) |
512 | st_sleep_done, timeout, retries); | 506 | buf_to_sg(STp->buffer, bytes); |
513 | 507 | ||
514 | if (do_wait) { | 508 | memcpy(SRpnt->cmd, cmd, sizeof(SRpnt->cmd)); |
509 | STp->buffer->cmdstat.have_sense = 0; | ||
510 | STp->buffer->syscall_result = 0; | ||
511 | |||
512 | if (scsi_execute_async(STp->device, cmd, direction, | ||
513 | &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs, | ||
514 | timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) | ||
515 | /* could not allocate the buffer or request was too large */ | ||
516 | (STp->buffer)->syscall_result = (-EBUSY); | ||
517 | else if (do_wait) { | ||
515 | wait_for_completion(waiting); | 518 | wait_for_completion(waiting); |
516 | SRpnt->sr_request->waiting = NULL; | 519 | SRpnt->waiting = NULL; |
517 | if (SRpnt->sr_request->rq_status != RQ_SCSI_DONE) | ||
518 | SRpnt->sr_result |= (DRIVER_ERROR << 24); | ||
519 | (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt); | 520 | (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt); |
520 | } | 521 | } |
522 | |||
521 | return SRpnt; | 523 | return SRpnt; |
522 | } | 524 | } |
523 | 525 | ||
@@ -532,7 +534,7 @@ static int write_behind_check(struct scsi_tape * STp) | |||
532 | struct st_buffer *STbuffer; | 534 | struct st_buffer *STbuffer; |
533 | struct st_partstat *STps; | 535 | struct st_partstat *STps; |
534 | struct st_cmdstatus *cmdstatp; | 536 | struct st_cmdstatus *cmdstatp; |
535 | struct scsi_request *SRpnt; | 537 | struct st_request *SRpnt; |
536 | 538 | ||
537 | STbuffer = STp->buffer; | 539 | STbuffer = STp->buffer; |
538 | if (!STbuffer->writing) | 540 | if (!STbuffer->writing) |
@@ -548,12 +550,10 @@ static int write_behind_check(struct scsi_tape * STp) | |||
548 | wait_for_completion(&(STp->wait)); | 550 | wait_for_completion(&(STp->wait)); |
549 | SRpnt = STbuffer->last_SRpnt; | 551 | SRpnt = STbuffer->last_SRpnt; |
550 | STbuffer->last_SRpnt = NULL; | 552 | STbuffer->last_SRpnt = NULL; |
551 | SRpnt->sr_request->waiting = NULL; | 553 | SRpnt->waiting = NULL; |
552 | if (SRpnt->sr_request->rq_status != RQ_SCSI_DONE) | ||
553 | SRpnt->sr_result |= (DRIVER_ERROR << 24); | ||
554 | 554 | ||
555 | (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt); | 555 | (STp->buffer)->syscall_result = st_chk_result(STp, SRpnt); |
556 | scsi_release_request(SRpnt); | 556 | st_release_request(SRpnt); |
557 | 557 | ||
558 | STbuffer->buffer_bytes -= STbuffer->writing; | 558 | STbuffer->buffer_bytes -= STbuffer->writing; |
559 | STps = &(STp->ps[STp->partition]); | 559 | STps = &(STp->ps[STp->partition]); |
@@ -593,7 +593,7 @@ static int write_behind_check(struct scsi_tape * STp) | |||
593 | it messes up the block number). */ | 593 | it messes up the block number). */ |
594 | static int cross_eof(struct scsi_tape * STp, int forward) | 594 | static int cross_eof(struct scsi_tape * STp, int forward) |
595 | { | 595 | { |
596 | struct scsi_request *SRpnt; | 596 | struct st_request *SRpnt; |
597 | unsigned char cmd[MAX_COMMAND_SIZE]; | 597 | unsigned char cmd[MAX_COMMAND_SIZE]; |
598 | 598 | ||
599 | cmd[0] = SPACE; | 599 | cmd[0] = SPACE; |
@@ -613,7 +613,7 @@ static int cross_eof(struct scsi_tape * STp, int forward) | |||
613 | if (!SRpnt) | 613 | if (!SRpnt) |
614 | return (STp->buffer)->syscall_result; | 614 | return (STp->buffer)->syscall_result; |
615 | 615 | ||
616 | scsi_release_request(SRpnt); | 616 | st_release_request(SRpnt); |
617 | SRpnt = NULL; | 617 | SRpnt = NULL; |
618 | 618 | ||
619 | if ((STp->buffer)->cmdstat.midlevel_result != 0) | 619 | if ((STp->buffer)->cmdstat.midlevel_result != 0) |
@@ -630,7 +630,7 @@ static int flush_write_buffer(struct scsi_tape * STp) | |||
630 | int offset, transfer, blks; | 630 | int offset, transfer, blks; |
631 | int result; | 631 | int result; |
632 | unsigned char cmd[MAX_COMMAND_SIZE]; | 632 | unsigned char cmd[MAX_COMMAND_SIZE]; |
633 | struct scsi_request *SRpnt; | 633 | struct st_request *SRpnt; |
634 | struct st_partstat *STps; | 634 | struct st_partstat *STps; |
635 | 635 | ||
636 | result = write_behind_check(STp); | 636 | result = write_behind_check(STp); |
@@ -688,7 +688,7 @@ static int flush_write_buffer(struct scsi_tape * STp) | |||
688 | STp->dirty = 0; | 688 | STp->dirty = 0; |
689 | (STp->buffer)->buffer_bytes = 0; | 689 | (STp->buffer)->buffer_bytes = 0; |
690 | } | 690 | } |
691 | scsi_release_request(SRpnt); | 691 | st_release_request(SRpnt); |
692 | SRpnt = NULL; | 692 | SRpnt = NULL; |
693 | } | 693 | } |
694 | return result; | 694 | return result; |
@@ -785,7 +785,7 @@ static int set_mode_densblk(struct scsi_tape * STp, struct st_modedef * STm) | |||
785 | } | 785 | } |
786 | 786 | ||
787 | 787 | ||
788 | /* Lock or unlock the drive door. Don't use when scsi_request allocated. */ | 788 | /* Lock or unlock the drive door. Don't use when st_request allocated. */ |
789 | static int do_door_lock(struct scsi_tape * STp, int do_lock) | 789 | static int do_door_lock(struct scsi_tape * STp, int do_lock) |
790 | { | 790 | { |
791 | int retval, cmd; | 791 | int retval, cmd; |
@@ -844,7 +844,7 @@ static int test_ready(struct scsi_tape *STp, int do_wait) | |||
844 | int attentions, waits, max_wait, scode; | 844 | int attentions, waits, max_wait, scode; |
845 | int retval = CHKRES_READY, new_session = 0; | 845 | int retval = CHKRES_READY, new_session = 0; |
846 | unsigned char cmd[MAX_COMMAND_SIZE]; | 846 | unsigned char cmd[MAX_COMMAND_SIZE]; |
847 | struct scsi_request *SRpnt = NULL; | 847 | struct st_request *SRpnt = NULL; |
848 | struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat; | 848 | struct st_cmdstatus *cmdstatp = &STp->buffer->cmdstat; |
849 | 849 | ||
850 | max_wait = do_wait ? ST_BLOCK_SECONDS : 0; | 850 | max_wait = do_wait ? ST_BLOCK_SECONDS : 0; |
@@ -903,7 +903,7 @@ static int test_ready(struct scsi_tape *STp, int do_wait) | |||
903 | } | 903 | } |
904 | 904 | ||
905 | if (SRpnt != NULL) | 905 | if (SRpnt != NULL) |
906 | scsi_release_request(SRpnt); | 906 | st_release_request(SRpnt); |
907 | return retval; | 907 | return retval; |
908 | } | 908 | } |
909 | 909 | ||
@@ -918,7 +918,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) | |||
918 | int i, retval, new_session = 0, do_wait; | 918 | int i, retval, new_session = 0, do_wait; |
919 | unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning; | 919 | unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning; |
920 | unsigned short st_flags = filp->f_flags; | 920 | unsigned short st_flags = filp->f_flags; |
921 | struct scsi_request *SRpnt = NULL; | 921 | struct st_request *SRpnt = NULL; |
922 | struct st_modedef *STm; | 922 | struct st_modedef *STm; |
923 | struct st_partstat *STps; | 923 | struct st_partstat *STps; |
924 | char *name = tape_name(STp); | 924 | char *name = tape_name(STp); |
@@ -993,7 +993,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) | |||
993 | goto err_out; | 993 | goto err_out; |
994 | } | 994 | } |
995 | 995 | ||
996 | if (!SRpnt->sr_result && !STp->buffer->cmdstat.have_sense) { | 996 | if (!SRpnt->result && !STp->buffer->cmdstat.have_sense) { |
997 | STp->max_block = ((STp->buffer)->b_data[1] << 16) | | 997 | STp->max_block = ((STp->buffer)->b_data[1] << 16) | |
998 | ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3]; | 998 | ((STp->buffer)->b_data[2] << 8) | (STp->buffer)->b_data[3]; |
999 | STp->min_block = ((STp->buffer)->b_data[4] << 8) | | 999 | STp->min_block = ((STp->buffer)->b_data[4] << 8) | |
@@ -1045,7 +1045,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) | |||
1045 | } | 1045 | } |
1046 | STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0; | 1046 | STp->drv_write_prot = ((STp->buffer)->b_data[2] & 0x80) != 0; |
1047 | } | 1047 | } |
1048 | scsi_release_request(SRpnt); | 1048 | st_release_request(SRpnt); |
1049 | SRpnt = NULL; | 1049 | SRpnt = NULL; |
1050 | STp->inited = 1; | 1050 | STp->inited = 1; |
1051 | 1051 | ||
@@ -1196,7 +1196,7 @@ static int st_flush(struct file *filp) | |||
1196 | { | 1196 | { |
1197 | int result = 0, result2; | 1197 | int result = 0, result2; |
1198 | unsigned char cmd[MAX_COMMAND_SIZE]; | 1198 | unsigned char cmd[MAX_COMMAND_SIZE]; |
1199 | struct scsi_request *SRpnt; | 1199 | struct st_request *SRpnt; |
1200 | struct scsi_tape *STp = filp->private_data; | 1200 | struct scsi_tape *STp = filp->private_data; |
1201 | struct st_modedef *STm = &(STp->modes[STp->current_mode]); | 1201 | struct st_modedef *STm = &(STp->modes[STp->current_mode]); |
1202 | struct st_partstat *STps = &(STp->ps[STp->partition]); | 1202 | struct st_partstat *STps = &(STp->ps[STp->partition]); |
@@ -1249,7 +1249,7 @@ static int st_flush(struct file *filp) | |||
1249 | cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) && | 1249 | cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) && |
1250 | (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) { | 1250 | (!cmdstatp->remainder_valid || cmdstatp->uremainder64 == 0))) { |
1251 | /* Write successful at EOM */ | 1251 | /* Write successful at EOM */ |
1252 | scsi_release_request(SRpnt); | 1252 | st_release_request(SRpnt); |
1253 | SRpnt = NULL; | 1253 | SRpnt = NULL; |
1254 | if (STps->drv_file >= 0) | 1254 | if (STps->drv_file >= 0) |
1255 | STps->drv_file++; | 1255 | STps->drv_file++; |
@@ -1259,7 +1259,7 @@ static int st_flush(struct file *filp) | |||
1259 | STps->eof = ST_FM; | 1259 | STps->eof = ST_FM; |
1260 | } | 1260 | } |
1261 | else { /* Write error */ | 1261 | else { /* Write error */ |
1262 | scsi_release_request(SRpnt); | 1262 | st_release_request(SRpnt); |
1263 | SRpnt = NULL; | 1263 | SRpnt = NULL; |
1264 | printk(KERN_ERR "%s: Error on write filemark.\n", name); | 1264 | printk(KERN_ERR "%s: Error on write filemark.\n", name); |
1265 | if (result == 0) | 1265 | if (result == 0) |
@@ -1400,11 +1400,11 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf, | |||
1400 | i = STp->try_dio && try_rdio; | 1400 | i = STp->try_dio && try_rdio; |
1401 | else | 1401 | else |
1402 | i = STp->try_dio && try_wdio; | 1402 | i = STp->try_dio && try_wdio; |
1403 | |||
1403 | if (i && ((unsigned long)buf & queue_dma_alignment( | 1404 | if (i && ((unsigned long)buf & queue_dma_alignment( |
1404 | STp->device->request_queue)) == 0) { | 1405 | STp->device->request_queue)) == 0) { |
1405 | i = st_map_user_pages(&(STbp->sg[0]), STbp->use_sg, | 1406 | i = sgl_map_user_pages(&(STbp->sg[0]), STbp->use_sg, |
1406 | (unsigned long)buf, count, (is_read ? READ : WRITE), | 1407 | (unsigned long)buf, count, (is_read ? READ : WRITE)); |
1407 | STp->max_pfn); | ||
1408 | if (i > 0) { | 1408 | if (i > 0) { |
1409 | STbp->do_dio = i; | 1409 | STbp->do_dio = i; |
1410 | STbp->buffer_bytes = 0; /* can be used as transfer counter */ | 1410 | STbp->buffer_bytes = 0; /* can be used as transfer counter */ |
@@ -1472,7 +1472,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
1472 | int async_write; | 1472 | int async_write; |
1473 | unsigned char cmd[MAX_COMMAND_SIZE]; | 1473 | unsigned char cmd[MAX_COMMAND_SIZE]; |
1474 | const char __user *b_point; | 1474 | const char __user *b_point; |
1475 | struct scsi_request *SRpnt = NULL; | 1475 | struct st_request *SRpnt = NULL; |
1476 | struct scsi_tape *STp = filp->private_data; | 1476 | struct scsi_tape *STp = filp->private_data; |
1477 | struct st_modedef *STm; | 1477 | struct st_modedef *STm; |
1478 | struct st_partstat *STps; | 1478 | struct st_partstat *STps; |
@@ -1624,7 +1624,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
1624 | retval = STbp->syscall_result; | 1624 | retval = STbp->syscall_result; |
1625 | goto out; | 1625 | goto out; |
1626 | } | 1626 | } |
1627 | if (async_write) { | 1627 | if (async_write && !STbp->syscall_result) { |
1628 | STbp->writing = transfer; | 1628 | STbp->writing = transfer; |
1629 | STp->dirty = !(STbp->writing == | 1629 | STp->dirty = !(STbp->writing == |
1630 | STbp->buffer_bytes); | 1630 | STbp->buffer_bytes); |
@@ -1698,7 +1698,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
1698 | } else { | 1698 | } else { |
1699 | count += do_count; | 1699 | count += do_count; |
1700 | STps->drv_block = (-1); /* Too cautious? */ | 1700 | STps->drv_block = (-1); /* Too cautious? */ |
1701 | retval = (-EIO); | 1701 | retval = STbp->syscall_result; |
1702 | } | 1702 | } |
1703 | 1703 | ||
1704 | } | 1704 | } |
@@ -1728,7 +1728,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
1728 | 1728 | ||
1729 | out: | 1729 | out: |
1730 | if (SRpnt != NULL) | 1730 | if (SRpnt != NULL) |
1731 | scsi_release_request(SRpnt); | 1731 | st_release_request(SRpnt); |
1732 | release_buffering(STp); | 1732 | release_buffering(STp); |
1733 | up(&STp->lock); | 1733 | up(&STp->lock); |
1734 | 1734 | ||
@@ -1742,11 +1742,11 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
1742 | Does release user buffer mapping if it is set. | 1742 | Does release user buffer mapping if it is set. |
1743 | */ | 1743 | */ |
1744 | static long read_tape(struct scsi_tape *STp, long count, | 1744 | static long read_tape(struct scsi_tape *STp, long count, |
1745 | struct scsi_request ** aSRpnt) | 1745 | struct st_request ** aSRpnt) |
1746 | { | 1746 | { |
1747 | int transfer, blks, bytes; | 1747 | int transfer, blks, bytes; |
1748 | unsigned char cmd[MAX_COMMAND_SIZE]; | 1748 | unsigned char cmd[MAX_COMMAND_SIZE]; |
1749 | struct scsi_request *SRpnt; | 1749 | struct st_request *SRpnt; |
1750 | struct st_modedef *STm; | 1750 | struct st_modedef *STm; |
1751 | struct st_partstat *STps; | 1751 | struct st_partstat *STps; |
1752 | struct st_buffer *STbp; | 1752 | struct st_buffer *STbp; |
@@ -1802,10 +1802,10 @@ static long read_tape(struct scsi_tape *STp, long count, | |||
1802 | retval = 1; | 1802 | retval = 1; |
1803 | DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", | 1803 | DEBC(printk(ST_DEB_MSG "%s: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", |
1804 | name, | 1804 | name, |
1805 | SRpnt->sr_sense_buffer[0], SRpnt->sr_sense_buffer[1], | 1805 | SRpnt->sense[0], SRpnt->sense[1], |
1806 | SRpnt->sr_sense_buffer[2], SRpnt->sr_sense_buffer[3], | 1806 | SRpnt->sense[2], SRpnt->sense[3], |
1807 | SRpnt->sr_sense_buffer[4], SRpnt->sr_sense_buffer[5], | 1807 | SRpnt->sense[4], SRpnt->sense[5], |
1808 | SRpnt->sr_sense_buffer[6], SRpnt->sr_sense_buffer[7])); | 1808 | SRpnt->sense[6], SRpnt->sense[7])); |
1809 | if (cmdstatp->have_sense) { | 1809 | if (cmdstatp->have_sense) { |
1810 | 1810 | ||
1811 | if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK) | 1811 | if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK) |
@@ -1835,7 +1835,7 @@ static long read_tape(struct scsi_tape *STp, long count, | |||
1835 | } | 1835 | } |
1836 | STbp->buffer_bytes = bytes - transfer; | 1836 | STbp->buffer_bytes = bytes - transfer; |
1837 | } else { | 1837 | } else { |
1838 | scsi_release_request(SRpnt); | 1838 | st_release_request(SRpnt); |
1839 | SRpnt = *aSRpnt = NULL; | 1839 | SRpnt = *aSRpnt = NULL; |
1840 | if (transfer == blks) { /* We did not get anything, error */ | 1840 | if (transfer == blks) { /* We did not get anything, error */ |
1841 | printk(KERN_NOTICE "%s: Incorrect block size.\n", name); | 1841 | printk(KERN_NOTICE "%s: Incorrect block size.\n", name); |
@@ -1929,7 +1929,7 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) | |||
1929 | ssize_t retval = 0; | 1929 | ssize_t retval = 0; |
1930 | ssize_t i, transfer; | 1930 | ssize_t i, transfer; |
1931 | int special, do_dio = 0; | 1931 | int special, do_dio = 0; |
1932 | struct scsi_request *SRpnt = NULL; | 1932 | struct st_request *SRpnt = NULL; |
1933 | struct scsi_tape *STp = filp->private_data; | 1933 | struct scsi_tape *STp = filp->private_data; |
1934 | struct st_modedef *STm; | 1934 | struct st_modedef *STm; |
1935 | struct st_partstat *STps; | 1935 | struct st_partstat *STps; |
@@ -2054,7 +2054,7 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) | |||
2054 | 2054 | ||
2055 | out: | 2055 | out: |
2056 | if (SRpnt != NULL) { | 2056 | if (SRpnt != NULL) { |
2057 | scsi_release_request(SRpnt); | 2057 | st_release_request(SRpnt); |
2058 | SRpnt = NULL; | 2058 | SRpnt = NULL; |
2059 | } | 2059 | } |
2060 | if (do_dio) { | 2060 | if (do_dio) { |
@@ -2284,7 +2284,7 @@ static int st_set_options(struct scsi_tape *STp, long options) | |||
2284 | static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs) | 2284 | static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs) |
2285 | { | 2285 | { |
2286 | unsigned char cmd[MAX_COMMAND_SIZE]; | 2286 | unsigned char cmd[MAX_COMMAND_SIZE]; |
2287 | struct scsi_request *SRpnt = NULL; | 2287 | struct st_request *SRpnt = NULL; |
2288 | 2288 | ||
2289 | memset(cmd, 0, MAX_COMMAND_SIZE); | 2289 | memset(cmd, 0, MAX_COMMAND_SIZE); |
2290 | cmd[0] = MODE_SENSE; | 2290 | cmd[0] = MODE_SENSE; |
@@ -2298,7 +2298,7 @@ static int read_mode_page(struct scsi_tape *STp, int page, int omit_block_descs) | |||
2298 | if (SRpnt == NULL) | 2298 | if (SRpnt == NULL) |
2299 | return (STp->buffer)->syscall_result; | 2299 | return (STp->buffer)->syscall_result; |
2300 | 2300 | ||
2301 | scsi_release_request(SRpnt); | 2301 | st_release_request(SRpnt); |
2302 | 2302 | ||
2303 | return (STp->buffer)->syscall_result; | 2303 | return (STp->buffer)->syscall_result; |
2304 | } | 2304 | } |
@@ -2310,7 +2310,7 @@ static int write_mode_page(struct scsi_tape *STp, int page, int slow) | |||
2310 | { | 2310 | { |
2311 | int pgo; | 2311 | int pgo; |
2312 | unsigned char cmd[MAX_COMMAND_SIZE]; | 2312 | unsigned char cmd[MAX_COMMAND_SIZE]; |
2313 | struct scsi_request *SRpnt = NULL; | 2313 | struct st_request *SRpnt = NULL; |
2314 | 2314 | ||
2315 | memset(cmd, 0, MAX_COMMAND_SIZE); | 2315 | memset(cmd, 0, MAX_COMMAND_SIZE); |
2316 | cmd[0] = MODE_SELECT; | 2316 | cmd[0] = MODE_SELECT; |
@@ -2329,7 +2329,7 @@ static int write_mode_page(struct scsi_tape *STp, int page, int slow) | |||
2329 | if (SRpnt == NULL) | 2329 | if (SRpnt == NULL) |
2330 | return (STp->buffer)->syscall_result; | 2330 | return (STp->buffer)->syscall_result; |
2331 | 2331 | ||
2332 | scsi_release_request(SRpnt); | 2332 | st_release_request(SRpnt); |
2333 | 2333 | ||
2334 | return (STp->buffer)->syscall_result; | 2334 | return (STp->buffer)->syscall_result; |
2335 | } | 2335 | } |
@@ -2412,7 +2412,7 @@ static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_cod | |||
2412 | DEB( char *name = tape_name(STp); ) | 2412 | DEB( char *name = tape_name(STp); ) |
2413 | unsigned char cmd[MAX_COMMAND_SIZE]; | 2413 | unsigned char cmd[MAX_COMMAND_SIZE]; |
2414 | struct st_partstat *STps; | 2414 | struct st_partstat *STps; |
2415 | struct scsi_request *SRpnt; | 2415 | struct st_request *SRpnt; |
2416 | 2416 | ||
2417 | if (STp->ready != ST_READY && !load_code) { | 2417 | if (STp->ready != ST_READY && !load_code) { |
2418 | if (STp->ready == ST_NO_TAPE) | 2418 | if (STp->ready == ST_NO_TAPE) |
@@ -2455,7 +2455,7 @@ static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_cod | |||
2455 | return (STp->buffer)->syscall_result; | 2455 | return (STp->buffer)->syscall_result; |
2456 | 2456 | ||
2457 | retval = (STp->buffer)->syscall_result; | 2457 | retval = (STp->buffer)->syscall_result; |
2458 | scsi_release_request(SRpnt); | 2458 | st_release_request(SRpnt); |
2459 | 2459 | ||
2460 | if (!retval) { /* SCSI command successful */ | 2460 | if (!retval) { /* SCSI command successful */ |
2461 | 2461 | ||
@@ -2503,7 +2503,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon | |||
2503 | int ioctl_result; | 2503 | int ioctl_result; |
2504 | int chg_eof = 1; | 2504 | int chg_eof = 1; |
2505 | unsigned char cmd[MAX_COMMAND_SIZE]; | 2505 | unsigned char cmd[MAX_COMMAND_SIZE]; |
2506 | struct scsi_request *SRpnt; | 2506 | struct st_request *SRpnt; |
2507 | struct st_partstat *STps; | 2507 | struct st_partstat *STps; |
2508 | int fileno, blkno, at_sm, undone; | 2508 | int fileno, blkno, at_sm, undone; |
2509 | int datalen = 0, direction = DMA_NONE; | 2509 | int datalen = 0, direction = DMA_NONE; |
@@ -2757,7 +2757,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon | |||
2757 | ioctl_result = (STp->buffer)->syscall_result; | 2757 | ioctl_result = (STp->buffer)->syscall_result; |
2758 | 2758 | ||
2759 | if (!ioctl_result) { /* SCSI command successful */ | 2759 | if (!ioctl_result) { /* SCSI command successful */ |
2760 | scsi_release_request(SRpnt); | 2760 | st_release_request(SRpnt); |
2761 | SRpnt = NULL; | 2761 | SRpnt = NULL; |
2762 | STps->drv_block = blkno; | 2762 | STps->drv_block = blkno; |
2763 | STps->drv_file = fileno; | 2763 | STps->drv_file = fileno; |
@@ -2872,7 +2872,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon | |||
2872 | /* Try the other possible state of Page Format if not | 2872 | /* Try the other possible state of Page Format if not |
2873 | already tried */ | 2873 | already tried */ |
2874 | STp->use_pf = !STp->use_pf | PF_TESTED; | 2874 | STp->use_pf = !STp->use_pf | PF_TESTED; |
2875 | scsi_release_request(SRpnt); | 2875 | st_release_request(SRpnt); |
2876 | SRpnt = NULL; | 2876 | SRpnt = NULL; |
2877 | return st_int_ioctl(STp, cmd_in, arg); | 2877 | return st_int_ioctl(STp, cmd_in, arg); |
2878 | } | 2878 | } |
@@ -2882,7 +2882,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon | |||
2882 | if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK) | 2882 | if (cmdstatp->sense_hdr.sense_key == BLANK_CHECK) |
2883 | STps->eof = ST_EOD; | 2883 | STps->eof = ST_EOD; |
2884 | 2884 | ||
2885 | scsi_release_request(SRpnt); | 2885 | st_release_request(SRpnt); |
2886 | SRpnt = NULL; | 2886 | SRpnt = NULL; |
2887 | } | 2887 | } |
2888 | 2888 | ||
@@ -2898,7 +2898,7 @@ static int get_location(struct scsi_tape *STp, unsigned int *block, int *partiti | |||
2898 | { | 2898 | { |
2899 | int result; | 2899 | int result; |
2900 | unsigned char scmd[MAX_COMMAND_SIZE]; | 2900 | unsigned char scmd[MAX_COMMAND_SIZE]; |
2901 | struct scsi_request *SRpnt; | 2901 | struct st_request *SRpnt; |
2902 | DEB( char *name = tape_name(STp); ) | 2902 | DEB( char *name = tape_name(STp); ) |
2903 | 2903 | ||
2904 | if (STp->ready != ST_READY) | 2904 | if (STp->ready != ST_READY) |
@@ -2944,7 +2944,7 @@ static int get_location(struct scsi_tape *STp, unsigned int *block, int *partiti | |||
2944 | DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name, | 2944 | DEBC(printk(ST_DEB_MSG "%s: Got tape pos. blk %d part %d.\n", name, |
2945 | *block, *partition)); | 2945 | *block, *partition)); |
2946 | } | 2946 | } |
2947 | scsi_release_request(SRpnt); | 2947 | st_release_request(SRpnt); |
2948 | SRpnt = NULL; | 2948 | SRpnt = NULL; |
2949 | 2949 | ||
2950 | return result; | 2950 | return result; |
@@ -2961,7 +2961,7 @@ static int set_location(struct scsi_tape *STp, unsigned int block, int partition | |||
2961 | unsigned int blk; | 2961 | unsigned int blk; |
2962 | int timeout; | 2962 | int timeout; |
2963 | unsigned char scmd[MAX_COMMAND_SIZE]; | 2963 | unsigned char scmd[MAX_COMMAND_SIZE]; |
2964 | struct scsi_request *SRpnt; | 2964 | struct st_request *SRpnt; |
2965 | DEB( char *name = tape_name(STp); ) | 2965 | DEB( char *name = tape_name(STp); ) |
2966 | 2966 | ||
2967 | if (STp->ready != ST_READY) | 2967 | if (STp->ready != ST_READY) |
@@ -3047,7 +3047,7 @@ static int set_location(struct scsi_tape *STp, unsigned int block, int partition | |||
3047 | result = 0; | 3047 | result = 0; |
3048 | } | 3048 | } |
3049 | 3049 | ||
3050 | scsi_release_request(SRpnt); | 3050 | st_release_request(SRpnt); |
3051 | SRpnt = NULL; | 3051 | SRpnt = NULL; |
3052 | 3052 | ||
3053 | return result; | 3053 | return result; |
@@ -3577,7 +3577,7 @@ static long st_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a | |||
3577 | static struct st_buffer * | 3577 | static struct st_buffer * |
3578 | new_tape_buffer(int from_initialization, int need_dma, int max_sg) | 3578 | new_tape_buffer(int from_initialization, int need_dma, int max_sg) |
3579 | { | 3579 | { |
3580 | int i, got = 0, segs = 0; | 3580 | int i, got = 0; |
3581 | gfp_t priority; | 3581 | gfp_t priority; |
3582 | struct st_buffer *tb; | 3582 | struct st_buffer *tb; |
3583 | 3583 | ||
@@ -3594,10 +3594,8 @@ static struct st_buffer * | |||
3594 | return NULL; | 3594 | return NULL; |
3595 | } | 3595 | } |
3596 | memset(tb, 0, i); | 3596 | memset(tb, 0, i); |
3597 | tb->frp_segs = tb->orig_frp_segs = segs; | 3597 | tb->frp_segs = tb->orig_frp_segs = 0; |
3598 | tb->use_sg = max_sg; | 3598 | tb->use_sg = max_sg; |
3599 | if (segs > 0) | ||
3600 | tb->b_data = page_address(tb->sg[0].page); | ||
3601 | tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg); | 3599 | tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg); |
3602 | 3600 | ||
3603 | tb->in_use = 1; | 3601 | tb->in_use = 1; |
@@ -3628,7 +3626,7 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm | |||
3628 | priority = GFP_KERNEL | __GFP_NOWARN; | 3626 | priority = GFP_KERNEL | __GFP_NOWARN; |
3629 | if (need_dma) | 3627 | if (need_dma) |
3630 | priority |= GFP_DMA; | 3628 | priority |= GFP_DMA; |
3631 | for (b_size = PAGE_SIZE, order=0; | 3629 | for (b_size = PAGE_SIZE, order=0; order <= 6 && |
3632 | b_size < new_size - STbuffer->buffer_size; | 3630 | b_size < new_size - STbuffer->buffer_size; |
3633 | order++, b_size *= 2) | 3631 | order++, b_size *= 2) |
3634 | ; /* empty */ | 3632 | ; /* empty */ |
@@ -3670,6 +3668,7 @@ static void normalize_buffer(struct st_buffer * STbuffer) | |||
3670 | } | 3668 | } |
3671 | STbuffer->frp_segs = STbuffer->orig_frp_segs; | 3669 | STbuffer->frp_segs = STbuffer->orig_frp_segs; |
3672 | STbuffer->frp_sg_current = 0; | 3670 | STbuffer->frp_sg_current = 0; |
3671 | STbuffer->sg_segs = 0; | ||
3673 | } | 3672 | } |
3674 | 3673 | ||
3675 | 3674 | ||
@@ -3882,7 +3881,6 @@ static int st_probe(struct device *dev) | |||
3882 | struct st_buffer *buffer; | 3881 | struct st_buffer *buffer; |
3883 | int i, j, mode, dev_num, error; | 3882 | int i, j, mode, dev_num, error; |
3884 | char *stp; | 3883 | char *stp; |
3885 | u64 bounce_limit; | ||
3886 | 3884 | ||
3887 | if (SDp->type != TYPE_TAPE) | 3885 | if (SDp->type != TYPE_TAPE) |
3888 | return -ENODEV; | 3886 | return -ENODEV; |
@@ -3892,7 +3890,8 @@ static int st_probe(struct device *dev) | |||
3892 | return -ENODEV; | 3890 | return -ENODEV; |
3893 | } | 3891 | } |
3894 | 3892 | ||
3895 | i = SDp->host->sg_tablesize; | 3893 | i = min(SDp->request_queue->max_hw_segments, |
3894 | SDp->request_queue->max_phys_segments); | ||
3896 | if (st_max_sg_segs < i) | 3895 | if (st_max_sg_segs < i) |
3897 | i = st_max_sg_segs; | 3896 | i = st_max_sg_segs; |
3898 | buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i); | 3897 | buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i); |
@@ -3994,11 +3993,6 @@ static int st_probe(struct device *dev) | |||
3994 | tpnt->long_timeout = ST_LONG_TIMEOUT; | 3993 | tpnt->long_timeout = ST_LONG_TIMEOUT; |
3995 | tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma; | 3994 | tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma; |
3996 | 3995 | ||
3997 | bounce_limit = scsi_calculate_bounce_limit(SDp->host) >> PAGE_SHIFT; | ||
3998 | if (bounce_limit > ULONG_MAX) | ||
3999 | bounce_limit = ULONG_MAX; | ||
4000 | tpnt->max_pfn = bounce_limit; | ||
4001 | |||
4002 | for (i = 0; i < ST_NBR_MODES; i++) { | 3996 | for (i = 0; i < ST_NBR_MODES; i++) { |
4003 | STm = &(tpnt->modes[i]); | 3997 | STm = &(tpnt->modes[i]); |
4004 | STm->defined = 0; | 3998 | STm->defined = 0; |
@@ -4077,9 +4071,9 @@ static int st_probe(struct device *dev) | |||
4077 | 4071 | ||
4078 | sdev_printk(KERN_WARNING, SDp, | 4072 | sdev_printk(KERN_WARNING, SDp, |
4079 | "Attached scsi tape %s", tape_name(tpnt)); | 4073 | "Attached scsi tape %s", tape_name(tpnt)); |
4080 | printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B), max page reachable by HBA %lu\n", | 4074 | printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n", |
4081 | tape_name(tpnt), tpnt->try_dio ? "yes" : "no", | 4075 | tape_name(tpnt), tpnt->try_dio ? "yes" : "no", |
4082 | queue_dma_alignment(SDp->request_queue) + 1, tpnt->max_pfn); | 4076 | queue_dma_alignment(SDp->request_queue) + 1); |
4083 | 4077 | ||
4084 | return 0; | 4078 | return 0; |
4085 | 4079 | ||
@@ -4411,34 +4405,6 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) | |||
4411 | return; | 4405 | return; |
4412 | } | 4406 | } |
4413 | 4407 | ||
4414 | |||
4415 | /* Pin down user pages and put them into a scatter gather list. Returns <= 0 if | ||
4416 | - mapping of all pages not successful | ||
4417 | - any page is above max_pfn | ||
4418 | (i.e., either completely successful or fails) | ||
4419 | */ | ||
4420 | static int st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, | ||
4421 | unsigned long uaddr, size_t count, int rw, | ||
4422 | unsigned long max_pfn) | ||
4423 | { | ||
4424 | int i, nr_pages; | ||
4425 | |||
4426 | nr_pages = sgl_map_user_pages(sgl, max_pages, uaddr, count, rw); | ||
4427 | if (nr_pages <= 0) | ||
4428 | return nr_pages; | ||
4429 | |||
4430 | for (i=0; i < nr_pages; i++) { | ||
4431 | if (page_to_pfn(sgl[i].page) > max_pfn) | ||
4432 | goto out_unmap; | ||
4433 | } | ||
4434 | return nr_pages; | ||
4435 | |||
4436 | out_unmap: | ||
4437 | sgl_unmap_user_pages(sgl, nr_pages, 0); | ||
4438 | return 0; | ||
4439 | } | ||
4440 | |||
4441 | |||
4442 | /* The following functions may be useful for a larger audience. */ | 4408 | /* The following functions may be useful for a larger audience. */ |
4443 | static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, | 4409 | static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, |
4444 | unsigned long uaddr, size_t count, int rw) | 4410 | unsigned long uaddr, size_t count, int rw) |
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 790acac160b..411209048d7 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | #include <linux/completion.h> | 5 | #include <linux/completion.h> |
6 | #include <linux/kref.h> | 6 | #include <linux/kref.h> |
7 | #include <scsi/scsi_cmnd.h> | ||
7 | 8 | ||
8 | /* Descriptor for analyzed sense data */ | 9 | /* Descriptor for analyzed sense data */ |
9 | struct st_cmdstatus { | 10 | struct st_cmdstatus { |
@@ -17,6 +18,17 @@ struct st_cmdstatus { | |||
17 | u8 deferred; | 18 | u8 deferred; |
18 | }; | 19 | }; |
19 | 20 | ||
21 | struct scsi_tape; | ||
22 | |||
23 | /* scsi tape command */ | ||
24 | struct st_request { | ||
25 | unsigned char cmd[MAX_COMMAND_SIZE]; | ||
26 | unsigned char sense[SCSI_SENSE_BUFFERSIZE]; | ||
27 | int result; | ||
28 | struct scsi_tape *stp; | ||
29 | struct completion *waiting; | ||
30 | }; | ||
31 | |||
20 | /* The tape buffer descriptor. */ | 32 | /* The tape buffer descriptor. */ |
21 | struct st_buffer { | 33 | struct st_buffer { |
22 | unsigned char in_use; | 34 | unsigned char in_use; |
@@ -28,7 +40,7 @@ struct st_buffer { | |||
28 | int read_pointer; | 40 | int read_pointer; |
29 | int writing; | 41 | int writing; |
30 | int syscall_result; | 42 | int syscall_result; |
31 | struct scsi_request *last_SRpnt; | 43 | struct st_request *last_SRpnt; |
32 | struct st_cmdstatus cmdstat; | 44 | struct st_cmdstatus cmdstat; |
33 | unsigned char *b_data; | 45 | unsigned char *b_data; |
34 | unsigned short use_sg; /* zero or max number of s/g segments for this adapter */ | 46 | unsigned short use_sg; /* zero or max number of s/g segments for this adapter */ |