aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/st.c254
-rw-r--r--drivers/scsi/st.h14
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);
188static void move_buffer_data(struct st_buffer *, int); 187static void move_buffer_data(struct st_buffer *, int);
189static void buf_to_sg(struct st_buffer *, unsigned int); 188static void buf_to_sg(struct st_buffer *, unsigned int);
190 189
191static int st_map_user_pages(struct scatterlist *, const unsigned int,
192 unsigned long, size_t, int, unsigned long);
193static int sgl_map_user_pages(struct scatterlist *, const unsigned int, 190static int sgl_map_user_pages(struct scatterlist *, const unsigned int,
194 unsigned long, size_t, int); 191 unsigned long, size_t, int);
195static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int); 192static 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
316static void st_analyze_sense(struct scsi_request *SRpnt, struct st_cmdstatus *s) 313static 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 */
348static int st_chk_result(struct scsi_tape *STp, struct scsi_request * SRpnt) 346static 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 */
441static void st_sleep_done(struct scsi_cmnd * SCpnt) 439static 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
452static struct st_request *st_allocate_request(void)
453{
454 return kzalloc(sizeof(struct st_request), GFP_KERNEL);
455}
456
457static 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. */
457static struct scsi_request * 465static struct st_request *
458st_do_scsi(struct scsi_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd, 466st_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