diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2005-11-08 05:06:44 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-12-14 22:16:31 -0500 |
commit | 8b05b773b6030de5b1bab1cbb0bf1ff8c34cdbe0 (patch) | |
tree | 0d364c50de0ef767846b366307ba69c3c95779b0 /drivers/scsi/st.c | |
parent | d6b10348f9397943eb968419a2b7f08895e38472 (diff) |
[SCSI] convert st to use scsi_execute_async
convert st to always send scatterlists and kill scsi_request
usage.
This is the same as last time as it was posted, but with Kai's patches
merged and we now pass the bytes value to scsi_execute_async.
TODO:
- move DIO code to common place or make block layers usable for ULDs.
- move buffer allocation code to common place for all ULDs to use. And
make buffer allocation code handle all queue limits so we can find
out about problems before calling scsi_execute_async.
- move indirect (copy_to/from_user) paths commone place or make block
layers usable for ULDs.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/st.c')
-rw-r--r-- | drivers/scsi/st.c | 254 |
1 files changed, 110 insertions, 144 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) |