X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fosst.c;h=fb3494ab281e07079d1f325e5ccdebdeb15de79d;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=fb74a2f64cd51528a2d5d5b020d4f38e1db730a0;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index fb74a2f64..fb3494ab2 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -13,18 +13,18 @@ order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale. - Copyright 1992 - 2002 Kai Makisara / Willem Riede - email Kai.Makisara@metla.fi / osst@riede.org + Copyright 1992 - 2002 Kai Makisara / 2000 - 2004 Willem Riede + email osst@riede.org - $Header: /cvsroot/osst/Driver/osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $ + $Header: /cvsroot/osst/Driver/osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $ Microscopic alterations - Rik Ling, 2000/12/21 Last st.c sync: Tue Oct 15 22:01:04 2002 by makisara Some small formal changes - aeb, 950809 */ -static const char * cvsid = "$Id: osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $"; -const char * osst_version = "0.99.1"; +static const char * cvsid = "$Id: osst.c,v 1.73 2005/01/01 21:13:34 wriede Exp $"; +const char * osst_version = "0.99.3"; /* The "failure to reconnect" firmware bug */ #define OSST_FW_NEED_POLL_MIN 10601 /*(107A)*/ @@ -36,6 +36,7 @@ const char * osst_version = "0.99.1"; #include #include #include +#include #include #include #include @@ -46,7 +47,9 @@ const char * osst_version = "0.99.1"; #include #include #include +#include #include +#include #include #include #include @@ -60,10 +63,14 @@ const char * osst_version = "0.99.1"; in the drivers are more widely classified, this may be changed to KERN_DEBUG. */ #define OSST_DEB_MSG KERN_NOTICE -#include "scsi.h" -#include +#include +#include +#include #include +#include +#include #include +#include #define ST_KILOBYTE 1024 @@ -81,13 +88,13 @@ MODULE_AUTHOR("Willem Riede"); MODULE_DESCRIPTION("OnStream {DI-|FW-|SC-|USB}{30|50} Tape Driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(max_dev, "i"); +module_param(max_dev, int, 0444); MODULE_PARM_DESC(max_dev, "Maximum number of OnStream Tape Drives to attach (4)"); -MODULE_PARM(write_threshold_kbs, "i"); +module_param(write_threshold_kbs, int, 0644); MODULE_PARM_DESC(write_threshold_kbs, "Asynchronous write threshold (KB; 32)"); -MODULE_PARM(max_sg_segs, "i"); +module_param(max_sg_segs, int, 0644); MODULE_PARM_DESC(max_sg_segs, "Maximum number of scatter/gather segments to use (9)"); #else static struct osst_dev_parm { @@ -118,10 +125,10 @@ static int debugging = 1; // #define OSST_INJECT_ERRORS 1 #endif -#define MAX_RETRIES 2 -#define MAX_READ_RETRIES 0 -#define MAX_WRITE_RETRIES 0 -#define MAX_READY_RETRIES 0 +/* Do not retry! The drive firmware already retries when appropriate, + and when it tries to tell us something, we had better listen... */ +#define MAX_RETRIES 0 + #define NO_TAPE NOT_READY #define OSST_WAIT_POSITION_COMPLETE (HZ > 200 ? HZ / 200 : 1) @@ -146,19 +153,19 @@ static int osst_max_sg_segs = OSST_MAX_SG; static int osst_max_dev = OSST_MAX_TAPES; static int osst_nr_dev; -static OS_Scsi_Tape **os_scsi_tapes = NULL; -static rwlock_t os_scsi_tapes_lock = RW_LOCK_UNLOCKED; +static struct osst_tape **os_scsi_tapes = NULL; +static DEFINE_RWLOCK(os_scsi_tapes_lock); -static int modes_defined = FALSE; +static int modes_defined = 0; -static OSST_buffer *new_tape_buffer(int, int, int); -static int enlarge_buffer(OSST_buffer *, int); -static void normalize_buffer(OSST_buffer *); -static int append_to_buffer(const char __user *, OSST_buffer *, int); -static int from_buffer(OSST_buffer *, char __user *, int); -static int osst_zero_buffer_tail(OSST_buffer *); -static int osst_copy_to_buffer(OSST_buffer *, unsigned char *); -static int osst_copy_from_buffer(OSST_buffer *, unsigned char *); +static struct osst_buffer *new_tape_buffer(int, int, int); +static int enlarge_buffer(struct osst_buffer *, int); +static void normalize_buffer(struct osst_buffer *); +static int append_to_buffer(const char __user *, struct osst_buffer *, int); +static int from_buffer(struct osst_buffer *, char __user *, int); +static int osst_zero_buffer_tail(struct osst_buffer *); +static int osst_copy_to_buffer(struct osst_buffer *, unsigned char *); +static int osst_copy_from_buffer(struct osst_buffer *, unsigned char *); static int osst_probe(struct device *); static int osst_remove(struct device *); @@ -172,17 +179,18 @@ struct scsi_driver osst_template = { } }; -static int osst_int_ioctl(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, unsigned int cmd_in,unsigned long arg); +static int osst_int_ioctl(struct osst_tape *STp, struct scsi_request ** aSRpnt, + unsigned int cmd_in, unsigned long arg); -static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int frame, int skip); +static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int frame, int skip); -static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt); +static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt); -static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt); +static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt); -static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending); +static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending); -static inline char *tape_name(OS_Scsi_Tape *tape) +static inline char *tape_name(struct osst_tape *tape) { return tape->drive->disk_name; } @@ -190,7 +198,7 @@ static inline char *tape_name(OS_Scsi_Tape *tape) /* Routines that handle the interaction with mid-layer SCSI routines */ /* Convert the result to success code */ -static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) +static int osst_chk_result(struct osst_tape * STp, struct scsi_request * SRpnt) { char *name = tape_name(STp); int result = SRpnt->sr_result; @@ -219,9 +227,9 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) if (scode) printk(OSST_DEB_MSG "%s:D: Sense: %02x, ASC: %02x, ASCQ: %02x\n", name, scode, sense[12], sense[13]); if (driver_byte(result) & DRIVER_SENSE) - print_req_sense("osst ", SRpnt); + scsi_print_req_sense("osst ", SRpnt); } -// else + else #endif if (!(driver_byte(result) & DRIVER_SENSE) || ((sense[0] & 0x70) == 0x70 && @@ -233,8 +241,8 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) SRpnt->sr_cmnd[0] != MODE_SENSE && SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */ if (driver_byte(result) & DRIVER_SENSE) { - printk(KERN_WARNING "%s:W: Command with sense data: ", name); - print_req_sense("osst:", SRpnt); + printk(KERN_WARNING "%s:W: Command with sense data:\n", name); + scsi_print_req_sense("osst:", SRpnt); } else { static int notyetprinted = 1; @@ -278,9 +286,9 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt) /* Wakeup from interrupt */ -static void osst_sleep_done (Scsi_Cmnd * SCpnt) +static void osst_sleep_done (struct scsi_cmnd * SCpnt) { - OS_Scsi_Tape * STp = container_of(SCpnt->request->rq_disk->private_data, OS_Scsi_Tape, driver); + struct osst_tape * STp = container_of(SCpnt->request->rq_disk->private_data, struct osst_tape, driver); if ((STp->buffer)->writing && (SCpnt->sense_buffer[0] & 0x70) == 0x70 && @@ -306,7 +314,7 @@ static void osst_sleep_done (Scsi_Cmnd * SCpnt) /* Do the scsi command. Waits until command performed if do_wait is true. Otherwise osst_write_behind_check() is used to check that the command has finished. */ -static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp, +static struct scsi_request * osst_do_scsi(struct scsi_request *SRpnt, struct osst_tape *STp, unsigned char *cmd, int bytes, int direction, int timeout, int retries, int do_wait) { unsigned char *bp; @@ -365,9 +373,9 @@ static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp, /* Handle the write-behind checking (downs the semaphore) */ -static void osst_write_behind_check(OS_Scsi_Tape *STp) +static void osst_write_behind_check(struct osst_tape *STp) { - OSST_buffer * STbuffer; + struct osst_buffer * STbuffer; STbuffer = STp->buffer; @@ -405,7 +413,7 @@ static void osst_write_behind_check(OS_Scsi_Tape *STp) /* * Initialize the OnStream AUX */ -static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int frame_seq_number, +static void osst_init_aux(struct osst_tape * STp, int frame_type, int frame_seq_number, int logical_blk_num, int blk_sz, int blk_cnt) { os_aux_t *aux = STp->buffer->aux; @@ -467,13 +475,13 @@ static void osst_init_aux(OS_Scsi_Tape * STp, int frame_type, int frame_seq_numb /* * Verify that we have the correct tape frame */ -static int osst_verify_frame(OS_Scsi_Tape * STp, int frame_seq_number, int quiet) +static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int quiet) { - char * name = tape_name(STp); - os_aux_t * aux = STp->buffer->aux; - os_partition_t * par = &(aux->partition); - ST_partstat * STps = &(STp->ps[STp->partition]); - int blk_cnt, blk_sz, i; + char * name = tape_name(STp); + os_aux_t * aux = STp->buffer->aux; + os_partition_t * par = &(aux->partition); + struct st_partstat * STps = &(STp->ps[STp->partition]); + int blk_cnt, blk_sz, i; if (STp->raw) { if (STp->buffer->syscall_result) { @@ -601,27 +609,26 @@ err_out: /* * Wait for the unit to become Ready */ -static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout, int initial_delay) +static int osst_wait_ready(struct osst_tape * STp, struct scsi_request ** aSRpnt, + unsigned timeout, int initial_delay) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - unsigned long startwait = jiffies; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + unsigned long startwait = jiffies; #if DEBUG - int dbg = debugging; - char * name = tape_name(STp); + int dbg = debugging; + char * name = tape_name(STp); printk(OSST_DEB_MSG "%s:D: Reached onstream wait ready\n", name); #endif - if (initial_delay > 0) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(initial_delay); - } + if (initial_delay > 0) + msleep(jiffies_to_msecs(initial_delay)); memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -637,13 +644,12 @@ static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned debugging = 0; } #endif - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ / 10); + msleep(100); memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); } *aSRpnt = SRpnt; #if DEBUG @@ -668,14 +674,14 @@ static int osst_wait_ready(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned /* * Wait for a tape to be inserted in the unit */ -static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned timeout) +static int osst_wait_for_medium(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned timeout) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - unsigned long startwait = jiffies; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + unsigned long startwait = jiffies; #if DEBUG - int dbg = debugging; - char * name = tape_name(STp); + int dbg = debugging; + char * name = tape_name(STp); printk(OSST_DEB_MSG "%s:D: Reached onstream wait for medium\n", name); #endif @@ -683,7 +689,7 @@ static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsi memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -697,13 +703,12 @@ static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsi debugging = 0; } #endif - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ / 10); + msleep(100); memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); } *aSRpnt = SRpnt; #if DEBUG @@ -725,7 +730,7 @@ static int osst_wait_for_medium(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsi return 1; } -static int osst_position_tape_and_confirm(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame) +static int osst_position_tape_and_confirm(struct osst_tape * STp, struct scsi_request ** aSRpnt, int frame) { int retval; @@ -739,15 +744,14 @@ static int osst_position_tape_and_confirm(OS_Scsi_Tape * STp, Scsi_Request ** aS /* * Wait for write(s) to complete */ -static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_flush_drive_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - - int result = 0; - int delay = OSST_WAIT_WRITE_COMPLETE; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + int result = 0; + int delay = OSST_WAIT_WRITE_COMPLETE; #if DEBUG - char * name = tape_name(STp); + char * name = tape_name(STp); printk(OSST_DEB_MSG "%s:D: Reached onstream flush drive buffer (write filemark)\n", name); #endif @@ -756,7 +760,7 @@ static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) cmd[0] = WRITE_FILEMARKS; cmd[1] = 1; - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_WRITE_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); if (STp->buffer->syscall_result) { @@ -774,12 +778,12 @@ static int osst_flush_drive_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) } #define OSST_POLL_PER_SEC 10 -static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, int minlast, int to) +static int osst_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int curr, int minlast, int to) { - unsigned long startwait = jiffies; - char * name = tape_name(STp); + unsigned long startwait = jiffies; + char * name = tape_name(STp); #if DEBUG - char notyetprinted = 1; + char notyetprinted = 1; #endif if (minlast >= 0 && STp->ps[STp->partition].rw != ST_READING) printk(KERN_ERR "%s:A: Waiting for frame without having initialized read!\n", name); @@ -787,7 +791,7 @@ static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, while (time_before (jiffies, startwait + to*HZ)) { int result; - result = osst_get_frame_position (STp, aSRpnt); + result = osst_get_frame_position(STp, aSRpnt); if (result == -EIO) if ((result = osst_write_error_recovery(STp, aSRpnt, 0)) == 0) return 0; /* successful recovery leaves drive ready for frame */ @@ -818,8 +822,7 @@ static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, notyetprinted--; } #endif - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout (HZ / OSST_POLL_PER_SEC); + msleep(1000 / OSST_POLL_PER_SEC); } #if DEBUG printk (OSST_DEB_MSG "%s:D: Fail wait f fr %i (>%i): %i-%i %i: %3li.%li s\n", @@ -830,23 +833,79 @@ static int osst_wait_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int curr, return -EBUSY; } +static int osst_recover_wait_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int writing) +{ + struct scsi_request * SRpnt; + unsigned char cmd[MAX_COMMAND_SIZE]; + unsigned long startwait = jiffies; + int retval = 1; + char * name = tape_name(STp); + + if (writing) { + char mybuf[24]; + char * olddata = STp->buffer->b_data; + int oldsize = STp->buffer->buffer_size; + + /* write zero fm then read pos - if shows write error, try to recover - if no progress, wait */ + + memset(cmd, 0, MAX_COMMAND_SIZE); + cmd[0] = WRITE_FILEMARKS; + cmd[1] = 1; + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, + MAX_RETRIES, 1); + + while (retval && time_before (jiffies, startwait + 5*60*HZ)) { + + if (STp->buffer->syscall_result && (SRpnt->sr_sense_buffer[2] & 0x0f) != 2) { + + /* some failure - not just not-ready */ + retval = osst_write_error_recovery(STp, aSRpnt, 0); + break; + } + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout (HZ / OSST_POLL_PER_SEC); + + STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; + memset(cmd, 0, MAX_COMMAND_SIZE); + cmd[0] = READ_POSITION; + + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout, + MAX_RETRIES, 1); + + retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 ); + STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; + } + if (retval) + printk(KERN_ERR "%s:E: Device did not succeed to write buffered data\n", name); + } else + /* TODO - figure out which error conditions can be handled */ + if (STp->buffer->syscall_result) + printk(KERN_WARNING + "%s:W: Recover_wait_frame(read) cannot handle %02x:%02x:%02x\n", name, + (*aSRpnt)->sr_sense_buffer[ 2] & 0x0f, + (*aSRpnt)->sr_sense_buffer[12], + (*aSRpnt)->sr_sense_buffer[13]); + + return retval; +} + /* * Read the next OnStream tape frame at the current location */ -static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeout) +static int osst_read_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int timeout) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - int retval = 0; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + int retval = 0; #if DEBUG - os_aux_t * aux = STp->buffer->aux; - char * name = tape_name(STp); + os_aux_t * aux = STp->buffer->aux; + char * name = tape_name(STp); #endif - /* TODO: Error handling */ if (STp->poll) - retval = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout); - + if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, 0, timeout)) + retval = osst_recover_wait_frame(STp, aSRpnt, 0); + memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = READ_6; cmd[1] = 1; @@ -854,13 +913,13 @@ static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeo #if DEBUG if (debugging) - printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name); + printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name); #endif - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ, - STp->timeout, MAX_READ_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE, + STp->timeout, MAX_RETRIES, 1); *aSRpnt = SRpnt; if (!SRpnt) - return (-EBUSY); + return (-EBUSY); if ((STp->buffer)->syscall_result) { retval = 1; @@ -904,15 +963,13 @@ static int osst_read_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int timeo return (retval); } -static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_initiate_read(struct osst_tape * STp, struct scsi_request ** aSRpnt) { - ST_partstat * STps = &(STp->ps[STp->partition]); - Scsi_Request * SRpnt ; - unsigned char cmd[MAX_COMMAND_SIZE]; - int retval = 0; -#if DEBUG - char * name = tape_name(STp); -#endif + struct st_partstat * STps = &(STp->ps[STp->partition]); + struct scsi_request * SRpnt ; + unsigned char cmd[MAX_COMMAND_SIZE]; + int retval = 0; + char * name = tape_name(STp); if (STps->rw != ST_READING) { /* Initialize read operation */ if (STps->rw == ST_WRITING || STp->dirty) { @@ -934,23 +991,25 @@ static int osst_initiate_read(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) #if DEBUG printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name); #endif - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READ_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); *aSRpnt = SRpnt; - retval = STp->buffer->syscall_result; + if ((retval = STp->buffer->syscall_result)) + printk(KERN_WARNING "%s:W: Error starting read ahead\n", name); } return retval; } -static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int frame_seq_number, int quiet) +static int osst_get_logical_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, + int frame_seq_number, int quiet) { - ST_partstat * STps = &(STp->ps[STp->partition]); - char * name = tape_name(STp); - int cnt = 0, - bad = 0, - past = 0, - x, - position; + struct st_partstat * STps = &(STp->ps[STp->partition]); + char * name = tape_name(STp); + int cnt = 0, + bad = 0, + past = 0, + x, + position; /* * If we want just any frame (-1) and there is a frame in the buffer, return it @@ -975,6 +1034,7 @@ static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, in name, STp->read_error_frame); #endif STp->read_error_frame = 0; + STp->abort_count++; } return (-EIO); } @@ -992,10 +1052,11 @@ static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, in position = 0xbb8; else if (position > STp->eod_frame_ppos || ++bad == 10) { position = STp->read_error_frame - 1; + bad = 0; } else { - position += 39; - cnt += 20; + position += 29; + cnt += 19; } #if DEBUG printk(OSST_DEB_MSG "%s:D: Bad frame detected, positioning tape to block %d\n", @@ -1063,15 +1124,15 @@ static int osst_get_logical_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, in "%s:D: Exit get logical frame (%d=>%d) from OnStream tape with code %d\n", name, frame_seq_number, STp->frame_seq_number, STps->eof); #endif - STp->fast_open = FALSE; + STp->fast_open = 0; STp->read_error_frame = 0; return (STps->eof); } -static int osst_seek_logical_blk(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int logical_blk_num) +static int osst_seek_logical_blk(struct osst_tape * STp, struct scsi_request ** aSRpnt, int logical_blk_num) { - ST_partstat * STps = &(STp->ps[STp->partition]); - char * name = tape_name(STp); + struct st_partstat * STps = &(STp->ps[STp->partition]); + char * name = tape_name(STp); int retries = 0; int frame_seq_estimate, ppos_estimate, move; @@ -1177,7 +1238,7 @@ error: #define OSST_SECTOR_SHIFT 9 #define OSST_SECTOR_MASK 0x03F -static int osst_get_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_get_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int sector; #if DEBUG @@ -1207,12 +1268,12 @@ static int osst_get_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) return sector; } -static int osst_seek_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sector) +static int osst_seek_sector(struct osst_tape * STp, struct scsi_request ** aSRpnt, int sector) { - ST_partstat * STps = &(STp->ps[STp->partition]); - int frame = sector >> OSST_FRAME_SHIFT, - offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, - r; + struct st_partstat * STps = &(STp->ps[STp->partition]); + int frame = sector >> OSST_FRAME_SHIFT, + offset = (sector & OSST_SECTOR_MASK) << OSST_SECTOR_SHIFT, + r; #if DEBUG char * name = tape_name(STp); @@ -1270,23 +1331,23 @@ static int osst_seek_sector(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sect * Precondition for this function to work: all frames in the * drive's buffer must be of one type (DATA, MARK or EOD)! */ -static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, - unsigned int frame, unsigned int skip, int pending) +static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct scsi_request ** aSRpnt, + unsigned int frame, unsigned int skip, int pending) { - Scsi_Request * SRpnt = * aSRpnt; - unsigned char * buffer, * p; - unsigned char cmd[MAX_COMMAND_SIZE]; - int flag, new_frame, i; - int nframes = STp->cur_frames; - int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); - int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num) + struct scsi_request * SRpnt = * aSRpnt; + unsigned char * buffer, * p; + unsigned char cmd[MAX_COMMAND_SIZE]; + int flag, new_frame, i; + int nframes = STp->cur_frames; + int blks_per_frame = ntohs(STp->buffer->aux->dat.dat_list[0].blk_cnt); + int frame_seq_number = ntohl(STp->buffer->aux->frame_seq_num) - (nframes + pending - 1); - int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num) + int logical_blk_num = ntohl(STp->buffer->aux->logical_blk_num) - (nframes + pending - 1) * blks_per_frame; - char * name = tape_name(STp); - unsigned long startwait = jiffies; + char * name = tape_name(STp); + unsigned long startwait = jiffies; #if DEBUG - int dbg = debugging; + int dbg = debugging; #endif if ((buffer = (unsigned char *)vmalloc((nframes + 1) * OS_DATA_SIZE)) == NULL) @@ -1311,8 +1372,8 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** cmd[7] = 32768 >> 8; cmd[8] = 32768 & 0xff; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_READ, - STp->timeout, MAX_READ_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE, + STp->timeout, MAX_RETRIES, 1); if ((STp->buffer)->syscall_result || !SRpnt) { printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name); @@ -1361,8 +1422,8 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** vfree((void *)buffer); return (-EIO); } - flag = 0; if ( i >= nframes + pending ) break; + flag = 0; } osst_copy_to_buffer(STp->buffer, p); /* @@ -1383,8 +1444,8 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** name, new_frame+i, frame_seq_number+i, logical_blk_num + i*blks_per_frame, p[0], p[1], p[2], p[3]); #endif - SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE, - STp->timeout, MAX_WRITE_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, + STp->timeout, MAX_RETRIES, 1); if (STp->buffer->syscall_result) flag = 1; @@ -1399,8 +1460,8 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = WRITE_FILEMARKS; cmd[1] = 1; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, - STp->timeout, MAX_WRITE_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, + STp->timeout, MAX_RETRIES, 1); #if DEBUG if (debugging) { printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name); @@ -1414,14 +1475,13 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, - MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, + MAX_RETRIES, 1); if (SRpnt->sr_sense_buffer[2] == 2 && SRpnt->sr_sense_buffer[12] == 4 && (SRpnt->sr_sense_buffer[13] == 1 || SRpnt->sr_sense_buffer[13] == 8)) { /* in the process of becoming ready */ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ / 10); + msleep(100); continue; } if (STp->buffer->syscall_result) @@ -1453,29 +1513,34 @@ static int osst_read_back_buffer_and_rewrite(OS_Scsi_Tape * STp, Scsi_Request ** #endif osst_get_frame_position(STp, aSRpnt); #if DEBUG - printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d\n", - name, STp->first_frame_position, STp->last_frame_position); + printk(OSST_DEB_MSG "%s:D: reported frame positions: host = %d, tape = %d, buffer = %d\n", + name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames); #endif } - } + } + if (flag) { + /* error recovery did not successfully complete */ + printk(KERN_ERR "%s:D: Write error recovery failed in %s\n", name, + STp->write_type == OS_WRITE_HEADER?"header":"body"); + } if (!pending) osst_copy_to_buffer(STp->buffer, p); /* so buffer content == at entry in all cases */ vfree((void *)buffer); return 0; } -static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, +static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request ** aSRpnt, unsigned int frame, unsigned int skip, int pending) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - char * name = tape_name(STp); - int expected = 0; - int attempts = 1000 / skip; - int flag = 1; - unsigned long startwait = jiffies; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + char * name = tape_name(STp); + int expected = 0; + int attempts = 1000 / skip; + int flag = 1; + unsigned long startwait = jiffies; #if DEBUG - int dbg = debugging; + int dbg = debugging; #endif while (attempts && time_before(jiffies, startwait + 60*HZ)) { @@ -1516,8 +1581,8 @@ static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, printk(OSST_DEB_MSG "%s:D: About to write pending fseq %d at fppos %d\n", name, STp->frame_seq_number-1, STp->first_frame_position); #endif - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE, - STp->timeout, MAX_WRITE_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, + STp->timeout, MAX_RETRIES, 1); *aSRpnt = SRpnt; if (STp->buffer->syscall_result) { /* additional write error */ @@ -1555,6 +1620,7 @@ static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, debugging = 0; } #endif + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); } printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name); @@ -1568,14 +1634,14 @@ static int osst_reposition_and_retry(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, * Error recovery algorithm for the OnStream tape. */ -static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int pending) +static int osst_write_error_recovery(struct osst_tape * STp, struct scsi_request ** aSRpnt, int pending) { - Scsi_Request * SRpnt = * aSRpnt; - ST_partstat * STps = & STp->ps[STp->partition]; - char * name = tape_name(STp); - int retval = 0; - int rw_state; - unsigned int frame, skip; + struct scsi_request * SRpnt = * aSRpnt; + struct st_partstat * STps = & STp->ps[STp->partition]; + char * name = tape_name(STp); + int retval = 0; + int rw_state; + unsigned int frame, skip; rw_state = STps->rw; @@ -1640,12 +1706,14 @@ static int osst_write_error_recovery(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, if (retval == 0) { STp->recover_count++; STp->recover_erreg++; - } + } else + STp->abort_count++; + STps->rw = rw_state; return retval; } -static int osst_space_over_filemarks_backward(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, +static int osst_space_over_filemarks_backward(struct osst_tape * STp, struct scsi_request ** aSRpnt, int mt_op, int mt_count) { char * name = tape_name(STp); @@ -1744,7 +1812,7 @@ found: * * Just scans for the filemark sequentially. */ -static int osst_space_over_filemarks_forward_slow(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, +static int osst_space_over_filemarks_forward_slow(struct osst_tape * STp, struct scsi_request ** aSRpnt, int mt_op, int mt_count) { int cnt = 0; @@ -1798,7 +1866,7 @@ static int osst_space_over_filemarks_forward_slow(OS_Scsi_Tape * STp, Scsi_Reque /* * Fast linux specific version of OnStream FSF */ -static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, +static int osst_space_over_filemarks_forward_fast(struct osst_tape * STp, struct scsi_request ** aSRpnt, int mt_op, int mt_count) { char * name = tape_name(STp); @@ -1949,11 +2017,11 @@ static int osst_space_over_filemarks_forward_fast(OS_Scsi_Tape * STp, Scsi_Reque * to test the error recovery mechanism. */ #if DEBUG -static void osst_set_retries(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int retries) +static void osst_set_retries(struct osst_tape * STp, struct scsi_request ** aSRpnt, int retries) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt = * aSRpnt; - char * name = tape_name(STp); + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt = * aSRpnt; + char * name = tape_name(STp); memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = MODE_SELECT; @@ -1972,7 +2040,7 @@ static void osst_set_retries(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int ret if (debugging) printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries); - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); *aSRpnt = SRpnt; if ((STp->buffer)->syscall_result) @@ -1981,7 +2049,7 @@ static void osst_set_retries(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int ret #endif -static int osst_write_filemark(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_write_filemark(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int result; int this_mark_ppos = STp->first_frame_position; @@ -2009,7 +2077,7 @@ static int osst_write_filemark(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) return result; } -static int osst_write_eod(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_write_eod(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int result; #if DEBUG @@ -2032,7 +2100,7 @@ static int osst_write_eod(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) return result; } -static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count) +static int osst_write_filler(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count) { char * name = tape_name(STp); @@ -2057,7 +2125,7 @@ static int osst_write_filler(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int whe return osst_flush_drive_buffer(STp, aSRpnt); } -static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int where, int count) +static int __osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int where, int count) { char * name = tape_name(STp); int result; @@ -2084,7 +2152,7 @@ static int __osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int w return result; } -static int osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int locate_eod) +static int osst_write_header(struct osst_tape * STp, struct scsi_request ** aSRpnt, int locate_eod) { os_header_t * header; int result; @@ -2158,7 +2226,7 @@ static int osst_write_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int loc return result; } -static int osst_reset_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_reset_header(struct osst_tape * STp, struct scsi_request ** aSRpnt) { if (STp->header_cache != NULL) memset(STp->header_cache, 0, sizeof(os_header_t)); @@ -2171,7 +2239,7 @@ static int osst_reset_header(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) return osst_write_header(STp, aSRpnt, 1); } -static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int ppos) +static int __osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt, int ppos) { char * name = tape_name(STp); os_header_t * header; @@ -2348,7 +2416,7 @@ static int __osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, in return 1; } -static int osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_analyze_headers(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int position, ppos; int first, last; @@ -2403,7 +2471,7 @@ static int osst_analyze_headers(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) return 1; } -static int osst_verify_position(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt) +static int osst_verify_position(struct osst_tape * STp, struct scsi_request ** aSRpnt) { int frame_position = STp->first_frame_position; int frame_seq_numbr = STp->frame_seq_number; @@ -2479,11 +2547,11 @@ static unsigned int osst_parse_firmware_rev (const char * str) /* * Configure the OnStream SCII tape drive for default operation */ -static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) +static int osst_configure_onstream(struct osst_tape *STp, struct scsi_request ** aSRpnt) { unsigned char cmd[MAX_COMMAND_SIZE]; char * name = tape_name(STp); - Scsi_Request * SRpnt = * aSRpnt; + struct scsi_request * SRpnt = * aSRpnt; osst_mode_parameter_header_t * header; osst_block_size_page_t * bs; osst_capabilities_page_t * cp; @@ -2512,7 +2580,7 @@ static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) cmd[2] = BLOCK_SIZE_PAGE; cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); if (SRpnt == NULL) { #if DEBUG printk(OSST_DEB_MSG "osst :D: Busy\n"); @@ -2549,7 +2617,7 @@ static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) cmd[1] = 0x10; cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); *aSRpnt = SRpnt; if ((STp->buffer)->syscall_result != 0) { printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name); @@ -2589,7 +2657,7 @@ static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0; (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); *aSRpnt = SRpnt; if ((STp->buffer)->syscall_result != 0) { @@ -2604,7 +2672,7 @@ static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) cmd[2] = CAPABILITIES_PAGE; cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); *aSRpnt = SRpnt; if ((STp->buffer)->syscall_result != 0) { @@ -2624,7 +2692,7 @@ static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) cmd[2] = TAPE_PARAMTR_PAGE; cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); *aSRpnt = SRpnt; if ((STp->buffer)->syscall_result != 0) { @@ -2650,7 +2718,7 @@ static int osst_configure_onstream(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) /* Step over EOF if it has been inadvertently crossed (ioctl not used because it messes up the block number). */ -static int cross_eof(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int forward) +static int cross_eof(struct osst_tape *STp, struct scsi_request ** aSRpnt, int forward) { int result; char * name = tape_name(STp); @@ -2679,18 +2747,18 @@ static int cross_eof(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int forward) /* Get the tape position. */ -static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) +static int osst_get_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt) { - unsigned char scmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - int result = 0; + unsigned char scmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + int result = 0; + char * name = tape_name(STp); /* KG: We want to be able to use it for checking Write Buffer availability * and thus don't want to risk to overwrite anything. Exchange buffers ... */ char mybuf[24]; char * olddata = STp->buffer->b_data; int oldsize = STp->buffer->buffer_size; - char * name = tape_name(STp); if (STp->ready != ST_READY) return (-EIO); @@ -2698,8 +2766,8 @@ static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) scmd[0] = READ_POSITION; STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; - SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, SCSI_DATA_READ, - STp->timeout, MAX_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE, + STp->timeout, MAX_RETRIES, 1); if (!SRpnt) { STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; return (-EBUSY); @@ -2707,22 +2775,28 @@ static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) *aSRpnt = SRpnt; if (STp->buffer->syscall_result) - result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL; + result = ((SRpnt->sr_sense_buffer[2] & 0x0f) == 3) ? -EIO : -EINVAL; /* 3: Write Error */ if (result == -EINVAL) printk(KERN_ERR "%s:E: Can't read tape position.\n", name); else { - - if (result == -EIO) { /* re-read position */ + if (result == -EIO) { /* re-read position - this needs to preserve media errors */ unsigned char mysense[16]; memcpy (mysense, SRpnt->sr_sense_buffer, 16); memset (scmd, 0, MAX_COMMAND_SIZE); scmd[0] = READ_POSITION; STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; - SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, SCSI_DATA_READ, - STp->timeout, MAX_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE, + STp->timeout, MAX_RETRIES, 1); +#if DEBUG + printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n", + name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:", + SRpnt->sr_sense_buffer[2],SRpnt->sr_sense_buffer[12],SRpnt->sr_sense_buffer[13]); +#endif if (!STp->buffer->syscall_result) memcpy (SRpnt->sr_sense_buffer, mysense, 16); + else + printk(KERN_WARNING "%s:W: Double error in get position\n", name); } STp->first_frame_position = ((STp->buffer)->b_data[4] << 24) + ((STp->buffer)->b_data[5] << 16) @@ -2744,7 +2818,7 @@ static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) #endif if (STp->cur_frames == 0 && STp->first_frame_position != STp->last_frame_position) { #if DEBUG - printk(KERN_WARNING "%s:D: Correcting read position %d, %d, %d\n", name, + printk(OSST_DEB_MSG "%s:D: Correcting read position %d, %d, %d\n", name, STp->first_frame_position, STp->last_frame_position, STp->cur_frames); #endif STp->first_frame_position = STp->last_frame_position; @@ -2757,14 +2831,14 @@ static int osst_get_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) /* Set the tape block */ -static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int ppos, int skip) +static int osst_set_frame_position(struct osst_tape *STp, struct scsi_request ** aSRpnt, int ppos, int skip) { - unsigned char scmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - ST_partstat * STps; - int result = 0; - int pp = (ppos == 3000 && !skip)? 0 : ppos; - char * name = tape_name(STp); + unsigned char scmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + struct st_partstat * STps; + int result = 0; + int pp = (ppos == 3000 && !skip)? 0 : ppos; + char * name = tape_name(STp); if (STp->ready != ST_READY) return (-EIO); @@ -2791,8 +2865,8 @@ static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, in if (skip) scmd[9] = 0x80; - SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, SCSI_DATA_NONE, STp->long_timeout, - MAX_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout, + MAX_RETRIES, 1); if (!SRpnt) return (-EBUSY); *aSRpnt = SRpnt; @@ -2815,9 +2889,9 @@ static int osst_set_frame_position(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, in return result; } -static int osst_write_trailer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, int leave_at_EOT) +static int osst_write_trailer(struct osst_tape *STp, struct scsi_request ** aSRpnt, int leave_at_EOT) { - ST_partstat * STps = &(STp->ps[STp->partition]); + struct st_partstat * STps = &(STp->ps[STp->partition]); int result = 0; if (STp->write_type != OS_WRITE_NEW_MARK) { @@ -2842,26 +2916,26 @@ out: /* osst versions of st functions - augmented and stripped to suit OnStream only */ /* Flush the write buffer (never need to write if variable blocksize). */ -static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) +static int osst_flush_write_buffer(struct osst_tape *STp, struct scsi_request ** aSRpnt) { - int offset, transfer, blks = 0; - int result = 0; - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt = *aSRpnt; - ST_partstat * STps; - char * name = tape_name(STp); + int offset, transfer, blks = 0; + int result = 0; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt = *aSRpnt; + struct st_partstat * STps; + char * name = tape_name(STp); if ((STp->buffer)->writing) { if (SRpnt == (STp->buffer)->last_SRpnt) #if DEBUG { printk(OSST_DEB_MSG - "%s:D: aSRpnt points to Scsi_Request that write_behind_check will release -- cleared\n", name); + "%s:D: aSRpnt points to scsi_request that write_behind_check will release -- cleared\n", name); #endif *aSRpnt = SRpnt = NULL; #if DEBUG } else if (SRpnt) printk(OSST_DEB_MSG - "%s:D: aSRpnt does not point to Scsi_Request that write_behind_check will release -- strange\n", name); + "%s:D: aSRpnt does not point to scsi_request that write_behind_check will release -- strange\n", name); #endif osst_write_behind_check(STp); if ((STp->buffer)->syscall_result) { @@ -2889,9 +2963,9 @@ static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) if (offset < OS_DATA_SIZE) osst_zero_buffer_tail(STp->buffer); - /* TODO: Error handling! */ if (STp->poll) - result = osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120); + if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 120)) + result = osst_recover_wait_frame(STp, aSRpnt, 1); memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = WRITE_6; @@ -2929,8 +3003,8 @@ static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) name, offset, transfer, blks); #endif - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, SCSI_DATA_WRITE, - STp->timeout, MAX_WRITE_RETRIES, TRUE); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE, + STp->timeout, MAX_RETRIES, 1); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -2972,12 +3046,12 @@ static int osst_flush_write_buffer(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt) /* Flush the tape buffer. The tape will be positioned correctly unless seek_next is true. */ -static int osst_flush_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int seek_next) +static int osst_flush_buffer(struct osst_tape * STp, struct scsi_request ** aSRpnt, int seek_next) { - ST_partstat * STps; - int backspace = 0, result = 0; + struct st_partstat * STps; + int backspace = 0, result = 0; #if DEBUG - char * name = tape_name(STp); + char * name = tape_name(STp); #endif /* @@ -3012,7 +3086,7 @@ static int osst_flush_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int see if (!seek_next) { if (STps->eof == ST_FM_HIT) { - result = cross_eof(STp, aSRpnt, FALSE); /* Back over the EOF hit */ + result = cross_eof(STp, aSRpnt, 0); /* Back over the EOF hit */ if (!result) STps->eof = ST_NOEOF; else { @@ -3034,13 +3108,13 @@ static int osst_flush_buffer(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int see return result; } -static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int synchronous) +static int osst_write_frame(struct osst_tape * STp, struct scsi_request ** aSRpnt, int synchronous) { - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt; - int blks; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt; + int blks; #if DEBUG - char * name = tape_name(STp); + char * name = tape_name(STp); #endif if ((!STp-> raw) && (STp->first_frame_position == 0xbae)) { /* _must_ preserve buffer! */ @@ -3060,8 +3134,9 @@ static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sync } if (STp->poll) - osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -50, 60); - /* TODO: Check for an error ! */ + if (osst_wait_frame (STp, aSRpnt, STp->first_frame_position, -48, 120)) + if (osst_recover_wait_frame(STp, aSRpnt, 1)) + return (-EIO); // osst_build_stats(STp, &SRpnt); @@ -3085,8 +3160,8 @@ static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sync if (!synchronous) STp->write_pending = 1; #endif - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, SCSI_DATA_WRITE, STp->timeout, - MAX_WRITE_RETRIES, synchronous); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout, + MAX_RETRIES, synchronous); if (!SRpnt) return (-EBUSY); *aSRpnt = SRpnt; @@ -3116,8 +3191,8 @@ static int osst_write_frame(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, int sync return 0; } -/* Lock or unlock the drive door. Don't use when Scsi_Request allocated. */ -static int do_door_lock(OS_Scsi_Tape * STp, int do_lock) +/* Lock or unlock the drive door. Don't use when struct scsi_request allocated. */ +static int do_door_lock(struct osst_tape * STp, int do_lock) { int retval, cmd; @@ -3136,10 +3211,10 @@ static int do_door_lock(OS_Scsi_Tape * STp, int do_lock) } /* Set the internal state after reset */ -static void reset_state(OS_Scsi_Tape *STp) +static void reset_state(struct osst_tape *STp) { int i; - ST_partstat *STps; + struct st_partstat *STps; STp->pos_unknown = 0; for (i = 0; i < ST_NBR_PARTITIONS; i++) { @@ -3147,7 +3222,7 @@ static void reset_state(OS_Scsi_Tape *STp) STps->rw = ST_IDLE; STps->eof = ST_NOEOF; STps->at_sm = 0; - STps->last_block_valid = FALSE; + STps->last_block_valid = 0; STps->drv_block = -1; STps->drv_file = -1; } @@ -3159,16 +3234,16 @@ static void reset_state(OS_Scsi_Tape *STp) /* Write command */ static ssize_t osst_write(struct file * filp, const char __user * buf, size_t count, loff_t *ppos) { - ssize_t total, retval = 0; - ssize_t i, do_count, blks, transfer; - int write_threshold; - int doing_write = 0; + ssize_t total, retval = 0; + ssize_t i, do_count, blks, transfer; + int write_threshold; + int doing_write = 0; const char __user * b_point; - Scsi_Request * SRpnt = NULL; - ST_mode * STm; - ST_partstat * STps; - OS_Scsi_Tape * STp = filp->private_data; - char * name = tape_name(STp); + struct scsi_request * SRpnt = NULL; + struct st_modedef * STm; + struct st_partstat * STps; + struct osst_tape * STp = filp->private_data; + char * name = tape_name(STp); if (down_interruptible(&STp->lock)) @@ -3301,7 +3376,7 @@ static ssize_t osst_write(struct file * filp, const char __user * buf, size_t co #endif } } - STp->fast_open = FALSE; + STp->fast_open = 0; } if (!STp->header_ok) { #if DEBUG @@ -3376,7 +3451,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name blks = do_count / STp->block_size; STp->logical_blk_num += blks; /* logical_blk_num is incremented as data is moved from user */ - i = osst_write_frame(STp, &SRpnt, TRUE); + i = osst_write_frame(STp, &SRpnt, 1); if (i == (-ENOSPC)) { transfer = STp->buffer->writing; /* FIXME -- check this logic */ @@ -3457,7 +3532,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name STp->dirty = !((STp->buffer)->writing == (STp->buffer)->buffer_bytes); - i = osst_write_frame(STp, &SRpnt, FALSE); + i = osst_write_frame(STp, &SRpnt, 0); if (i < 0) { retval = (-EIO); goto out; @@ -3482,14 +3557,14 @@ out: /* Read command */ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, loff_t *ppos) { - ssize_t total, retval = 0; - ssize_t i, transfer; - int special; - ST_mode * STm; - ST_partstat * STps; - Scsi_Request * SRpnt = NULL; - OS_Scsi_Tape * STp = filp->private_data; - char * name = tape_name(STp); + ssize_t total, retval = 0; + ssize_t i, transfer; + int special; + struct st_modedef * STm; + struct st_partstat * STps; + struct scsi_request * SRpnt = NULL; + struct osst_tape * STp = filp->private_data; + char * name = tape_name(STp); if (down_interruptible(&STp->lock)) @@ -3665,7 +3740,7 @@ out: /* Set the driver options */ -static void osst_log_options(OS_Scsi_Tape *STp, ST_mode *STm, char *name) +static void osst_log_options(struct osst_tape *STp, struct st_modedef *STm, char *name) { printk(KERN_INFO "%s:I: Mode %d options: buffer writes: %d, async writes: %d, read ahead: %d\n", @@ -3688,17 +3763,17 @@ static void osst_log_options(OS_Scsi_Tape *STp, ST_mode *STm, char *name) } -static int osst_set_options(OS_Scsi_Tape *STp, long options) +static int osst_set_options(struct osst_tape *STp, long options) { - int value; - long code; - ST_mode * STm; - char * name = tape_name(STp); + int value; + long code; + struct st_modedef * STm; + char * name = tape_name(STp); STm = &(STp->modes[STp->current_mode]); if (!STm->defined) { - memcpy(STm, &(STp->modes[0]), sizeof(ST_mode)); - modes_defined = TRUE; + memcpy(STm, &(STp->modes[0]), sizeof(*STm)); + modes_defined = 1; #if DEBUG if (debugging) printk(OSST_DEB_MSG "%s:D: Initialized mode %d definition from mode 0\n", @@ -3844,18 +3919,19 @@ static int osst_set_options(OS_Scsi_Tape *STp, long options) /* Internal ioctl function */ -static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned int cmd_in, unsigned long arg) +static int osst_int_ioctl(struct osst_tape * STp, struct scsi_request ** aSRpnt, + unsigned int cmd_in, unsigned long arg) { - int timeout; - long ltmp; - int i, ioctl_result; - int chg_eof = TRUE; - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt = * aSRpnt; - ST_partstat * STps; - int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num; - int datalen = 0, direction = SCSI_DATA_NONE; - char * name = tape_name(STp); + int timeout; + long ltmp; + int i, ioctl_result; + int chg_eof = 1; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt = * aSRpnt; + struct st_partstat * STps; + int fileno, blkno, at_sm, frame_seq_numbr, logical_blk_num; + int datalen = 0, direction = DMA_NONE; + char * name = tape_name(STp); if (STp->ready != ST_READY && cmd_in != MTLOAD) { if (STp->ready == ST_NO_TAPE) @@ -3874,7 +3950,7 @@ static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned i memset(cmd, 0, MAX_COMMAND_SIZE); switch (cmd_in) { case MTFSFM: - chg_eof = FALSE; /* Changed from the FSF after this */ + chg_eof = 0; /* Changed from the FSF after this */ case MTFSF: if (STp->raw) return (-EIO); @@ -3889,7 +3965,7 @@ static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned i goto os_bypass; case MTBSF: - chg_eof = FALSE; /* Changed from the FSF after this */ + chg_eof = 0; /* Changed from the FSF after this */ case MTBSFM: if (STp->raw) return (-EIO); @@ -4104,7 +4180,7 @@ static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned i case MTSETDENSITY: /* Set tape density */ case MTSETDRVBUFFER: /* Set drive buffering */ case SET_DENS_AND_BLK: /* Set density and block size */ - chg_eof = FALSE; + chg_eof = 0; if (STp->dirty || (STp->buffer)->buffer_bytes != 0) return (-EIO); /* Not allowed if data in buffer */ if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) && @@ -4121,7 +4197,7 @@ static int osst_int_ioctl(OS_Scsi_Tape * STp, Scsi_Request ** aSRpnt, unsigned i return (-ENOSYS); } - SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1); ioctl_result = (STp->buffer)->syscall_result; @@ -4177,7 +4253,7 @@ os_bypass: else if (cmd_in == MTLOAD) { for (i=0; i < ST_NBR_PARTITIONS; i++) { STp->ps[i].rw = ST_IDLE; - STp->ps[i].last_block_valid = FALSE;/* FIXME - where else is this field maintained? */ + STp->ps[i].last_block_valid = 0;/* FIXME - where else is this field maintained? */ } STp->partition = 0; } @@ -4231,16 +4307,16 @@ os_bypass: /* Open the device */ static int os_scsi_tape_open(struct inode * inode, struct file * filp) { - unsigned short flags; - int i, b_size, new_session = FALSE, retval = 0; - unsigned char cmd[MAX_COMMAND_SIZE]; - Scsi_Request * SRpnt = NULL; - OS_Scsi_Tape * STp; - ST_mode * STm; - ST_partstat * STps; - char * name; - int dev = TAPE_NR(inode); - int mode = TAPE_MODE(inode); + unsigned short flags; + int i, b_size, new_session = 0, retval = 0; + unsigned char cmd[MAX_COMMAND_SIZE]; + struct scsi_request * SRpnt = NULL; + struct osst_tape * STp; + struct st_modedef * STm; + struct st_partstat * STps; + char * name; + int dev = TAPE_NR(inode); + int mode = TAPE_MODE(inode); nonseekable_open(inode, filp); write_lock(&os_scsi_tapes_lock); @@ -4281,7 +4357,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) printk(OSST_DEB_MSG "%s:D: Mode change from %d to %d.\n", name, STp->current_mode, mode); #endif - new_session = TRUE; + new_session = 1; STp->current_mode = mode; } STm = &(STp->modes[STp->current_mode]); @@ -4331,9 +4407,9 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) memset (cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE, STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1); if (!SRpnt) { - retval = (STp->buffer)->syscall_result; + retval = (STp->buffer)->syscall_result; /* FIXME - valid? */ goto err_out; } if ((SRpnt->sr_sense_buffer[0] & 0x70) == 0x70 && @@ -4351,8 +4427,8 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) cmd[0] = START_STOP; cmd[1] = 1; cmd[4] = 1; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, - STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, + STp->timeout, MAX_RETRIES, 1); } osst_wait_ready(STp, &SRpnt, (SRpnt->sr_sense_buffer[13]==1?15:3) * 60, 0); } @@ -4368,8 +4444,8 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) memset (cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, - STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, + STp->timeout, MAX_RETRIES, 1); if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 || (SRpnt->sr_sense_buffer[2] & 0x0f) != UNIT_ATTENTION) break; @@ -4384,12 +4460,13 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) STps->rw = ST_IDLE; /* FIXME - seems to be redundant... */ STps->eof = ST_NOEOF; STps->at_sm = 0; - STps->last_block_valid = FALSE; + STps->last_block_valid = 0; STps->drv_block = 0; STps->drv_file = 0 ; } - new_session = TRUE; + new_session = 1; STp->recover_count = 0; + STp->abort_count = 0; } /* * if we have valid headers from before, and the drive/tape seem untouched, @@ -4404,7 +4481,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) cmd[2] = VENDOR_IDENT_PAGE; cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, STp->timeout, 0, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1); if (STp->buffer->syscall_result || STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' || @@ -4434,7 +4511,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) STp->buffer->buffer_bytes = STp->buffer->read_pointer = 0; } STp->buffer->buffer_blocks = OS_DATA_SIZE / STp->block_size; - STp->fast_open = TRUE; + STp->fast_open = 1; scsi_release_request(SRpnt); return 0; } @@ -4445,7 +4522,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) #endif STp->header_ok = 0; } - STp->fast_open = FALSE; + STp->fast_open = 0; if ((STp->buffer)->syscall_result != 0 && /* in all error conditions except no medium */ (SRpnt->sr_sense_buffer[2] != 2 || SRpnt->sr_sense_buffer[12] != 0x3A) ) { @@ -4467,7 +4544,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) #if DEBUG printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name); #endif - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, STp->timeout, 0, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1); STp->header_ok = 0; @@ -4476,8 +4553,8 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) memset (cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, - STp->timeout, MAX_READY_RETRIES, TRUE); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, + STp->timeout, MAX_RETRIES, 1); if ((SRpnt->sr_sense_buffer[0] & 0x70) != 0x70 || (SRpnt->sr_sense_buffer[2] & 0x0f) == NOT_READY) break; @@ -4492,11 +4569,11 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) STps->rw = ST_IDLE; STps->eof = ST_NOEOF; STps->at_sm = 0; - STps->last_block_valid = FALSE; + STps->last_block_valid = 0; STps->drv_block = 0; STps->drv_file = 0 ; } - new_session = TRUE; + new_session = 1; } } } @@ -4556,8 +4633,8 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp) if (debugging) printk(OSST_DEB_MSG "%s:D: New Session\n", name); #endif - STp->density_changed = STp->blksize_changed = FALSE; - STp->compression_changed = FALSE; + STp->density_changed = STp->blksize_changed = 0; + STp->compression_changed = 0; } /* @@ -4592,12 +4669,12 @@ err_out: /* Flush the tape buffer before close */ static int os_scsi_tape_flush(struct file * filp) { - int result = 0, result2; - OS_Scsi_Tape * STp = filp->private_data; - ST_mode * STm = &(STp->modes[STp->current_mode]); - ST_partstat * STps = &(STp->ps[STp->partition]); - Scsi_Request * SRpnt = NULL; - char * name = tape_name(STp); + int result = 0, result2; + struct osst_tape * STp = filp->private_data; + struct st_modedef * STm = &(STp->modes[STp->current_mode]); + struct st_partstat * STps = &(STp->ps[STp->partition]); + struct scsi_request * SRpnt = NULL; + char * name = tape_name(STp); if (file_count(filp) > 1) return 0; @@ -4631,7 +4708,7 @@ static int os_scsi_tape_flush(struct file * filp) if (STp->can_bsr) result = osst_flush_buffer(STp, &SRpnt, 0); /* this is the default path */ else if (STps->eof == ST_FM_HIT) { - result = cross_eof(STp, &SRpnt, FALSE); + result = cross_eof(STp, &SRpnt, 0); if (result) { if (STps->drv_file >= 0) STps->drv_file++; @@ -4643,7 +4720,7 @@ static int os_scsi_tape_flush(struct file * filp) } } else if ((STps->eof == ST_NOEOF && - !(result = cross_eof(STp, &SRpnt, TRUE))) || + !(result = cross_eof(STp, &SRpnt, 1))) || STps->eof == ST_FM_HIT) { if (STps->drv_file >= 0) STps->drv_file++; @@ -4661,14 +4738,19 @@ out: } if (SRpnt) scsi_release_request(SRpnt); - if (STp->recover_count) { - printk(KERN_INFO "%s:I: %d recovered errors in", name, STp->recover_count); + if (STp->abort_count || STp->recover_count) { + printk(KERN_INFO "%s:I:", name); + if (STp->abort_count) + printk(" %d unrecovered errors", STp->abort_count); + if (STp->recover_count) + printk(" %d recovered errors", STp->recover_count); if (STp->write_count) - printk(" %d frames written", STp->write_count); + printk(" in %d frames written", STp->write_count); if (STp->read_count) - printk(" %d frames read", STp->read_count); + printk(" in %d frames read", STp->read_count); printk("\n"); STp->recover_count = 0; + STp->abort_count = 0; } STp->write_count = 0; STp->read_count = 0; @@ -4680,9 +4762,9 @@ out: /* Close the device and release it */ static int os_scsi_tape_close(struct inode * inode, struct file * filp) { - int result = 0; - OS_Scsi_Tape * STp = filp->private_data; - Scsi_Request * SRpnt = NULL; + int result = 0; + struct osst_tape * STp = filp->private_data; + struct scsi_request * SRpnt = NULL; if (SRpnt) scsi_release_request(SRpnt); @@ -4707,14 +4789,14 @@ static int os_scsi_tape_close(struct inode * inode, struct file * filp) static int osst_ioctl(struct inode * inode,struct file * file, unsigned int cmd_in, unsigned long arg) { - int i, cmd_nr, cmd_type, retval = 0; - unsigned int blk; - ST_mode * STm; - ST_partstat * STps; - Scsi_Request * SRpnt = NULL; - OS_Scsi_Tape * STp = file->private_data; - char * name = tape_name(STp); - void __user *p = (void __user *)arg; + int i, cmd_nr, cmd_type, retval = 0; + unsigned int blk; + struct st_modedef * STm; + struct st_partstat * STps; + struct scsi_request * SRpnt = NULL; + struct osst_tape * STp = file->private_data; + char * name = tape_name(STp); + void __user * p = (void __user *)arg; if (down_interruptible(&STp->lock)) return -ERESTARTSYS; @@ -4893,7 +4975,7 @@ static int osst_ioctl(struct inode * inode,struct file * file, for (i=0; i < ST_NBR_PARTITIONS; i++) { STp->ps[i].rw = ST_IDLE; STp->ps[i].at_sm = 0; - STp->ps[i].last_block_valid = FALSE; + STp->ps[i].last_block_valid = 0; } STp->partition = STp->new_partition = 0; STp->nbr_partitions = 1; /* Bad guess ?-) */ @@ -4919,7 +5001,7 @@ static int osst_ioctl(struct inode * inode,struct file * file, } if (auto_weof) - cross_eof(STp, &SRpnt, FALSE); + cross_eof(STp, &SRpnt, 0); if (mtc.mt_op == MTCOMPRESSION) retval = -EINVAL; /* OnStream drives don't have compression hardware */ @@ -4935,7 +5017,7 @@ static int osst_ioctl(struct inode * inode,struct file * file, goto out; } - if ((i = osst_flush_buffer(STp, &SRpnt, FALSE)) < 0) { + if ((i = osst_flush_buffer(STp, &SRpnt, 0)) < 0) { retval = i; goto out; } @@ -5043,18 +5125,18 @@ out: /* Memory handling routines */ /* Try to allocate a new tape buffer skeleton. Caller must not hold os_scsi_tapes_lock */ -static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg ) +static struct osst_buffer * new_tape_buffer( int from_initialization, int need_dma, int max_sg ) { int i, priority; - OSST_buffer *tb; + struct osst_buffer *tb; if (from_initialization) priority = GFP_ATOMIC; else priority = GFP_KERNEL; - i = sizeof(OSST_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); - tb = (OSST_buffer *)kmalloc(i, priority); + i = sizeof(struct osst_buffer) + (osst_max_sg_segs - 1) * sizeof(struct scatterlist); + tb = (struct osst_buffer *)kmalloc(i, priority); if (!tb) { printk(KERN_NOTICE "osst :I: Can't allocate new tape buffer.\n"); return NULL; @@ -5062,7 +5144,7 @@ static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma, int memset(tb, 0, i); tb->sg_segs = tb->orig_sg_segs = 0; tb->use_sg = max_sg; - tb->in_use = TRUE; + tb->in_use = 1; tb->dma = need_dma; tb->buffer_size = 0; #if DEBUG @@ -5075,12 +5157,12 @@ static OSST_buffer * new_tape_buffer( int from_initialization, int need_dma, int } /* Try to allocate a temporary (while a user has the device open) enlarged tape buffer */ -static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma) +static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma) { int segs, nbr, max_segs, b_size, priority, order, got; if (STbuffer->buffer_size >= OS_FRAME_SIZE) - return TRUE; + return 1; if (STbuffer->sg_segs) { printk(KERN_WARNING "osst :A: Buffer not previously normalized.\n"); @@ -5089,14 +5171,12 @@ static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma) /* See how many segments we can use -- need at least two */ nbr = max_segs = STbuffer->use_sg; if (nbr <= 2) - return FALSE; + return 0; - priority = GFP_KERNEL; + priority = GFP_KERNEL /* | __GFP_NOWARN */; if (need_dma) priority |= GFP_DMA; - priority |= __GFP_NOWARN; - /* Try to allocate the first segment up to OS_DATA_SIZE and the others big enough to reach the goal (code assumes no segments in place) */ for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) { @@ -5110,7 +5190,7 @@ static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma) } if (STbuffer->sg[0].page == NULL) { printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n"); - return FALSE; + return 0; } /* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */ for (segs=STbuffer->sg_segs=1, got=b_size; @@ -5130,7 +5210,7 @@ static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma) STbuffer->buffer_size = got; #endif normalize_buffer(STbuffer); - return FALSE; + return 0; } STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size; got += STbuffer->sg[segs].length; @@ -5149,12 +5229,12 @@ static int enlarge_buffer(OSST_buffer *STbuffer, int need_dma) } #endif - return TRUE; + return 1; } /* Release the segments */ -static void normalize_buffer(OSST_buffer *STbuffer) +static void normalize_buffer(struct osst_buffer *STbuffer) { int i, order, b_size; @@ -5178,7 +5258,7 @@ static void normalize_buffer(OSST_buffer *STbuffer) /* Move data from the user buffer to the tape buffer. Returns zero (success) or negative error code. */ -static int append_to_buffer(const char __user *ubp, OSST_buffer *st_bp, int do_count) +static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, int do_count) { int i, cnt, res, offset; @@ -5211,7 +5291,7 @@ static int append_to_buffer(const char __user *ubp, OSST_buffer *st_bp, int do_c /* Move data from the tape buffer to the user buffer. Returns zero (success) or negative error code. */ -static int from_buffer(OSST_buffer *st_bp, char __user *ubp, int do_count) +static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count) { int i, cnt, res, offset; @@ -5243,7 +5323,7 @@ static int from_buffer(OSST_buffer *st_bp, char __user *ubp, int do_count) /* Sets the tail of the buffer after fill point to zero. Returns zero (success) or negative error code. */ -static int osst_zero_buffer_tail(OSST_buffer *st_bp) +static int osst_zero_buffer_tail(struct osst_buffer *st_bp) { int i, offset, do_count, cnt; @@ -5271,7 +5351,7 @@ static int osst_zero_buffer_tail(OSST_buffer *st_bp) /* Copy a osst 32K chunk of memory into the buffer. Returns zero (success) or negative error code. */ -static int osst_copy_to_buffer(OSST_buffer *st_bp, unsigned char *ptr) +static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr) { int i, cnt, do_count = OS_DATA_SIZE; @@ -5292,7 +5372,7 @@ static int osst_copy_to_buffer(OSST_buffer *st_bp, unsigned char *ptr) /* Copy a osst 32K chunk of memory from the buffer. Returns zero (success) or negative error code. */ -static int osst_copy_from_buffer(OSST_buffer *st_bp, unsigned char *ptr) +static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr) { int i, cnt, do_count = OS_DATA_SIZE; @@ -5381,7 +5461,7 @@ static struct file_operations osst_fops = { .release = os_scsi_tape_close, }; -static int osst_supports(Scsi_Device * SDp) +static int osst_supports(struct scsi_device * SDp) { struct osst_support_data { char *vendor; @@ -5409,19 +5489,164 @@ static struct osst_support_data support_list[] = { return 0; } +/* + * sysfs support for osst driver parameter information + */ + +static ssize_t osst_version_show(struct device_driver *ddd, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%s\n", osst_version); +} + +static DRIVER_ATTR(version, S_IRUGO, osst_version_show, NULL); + +static void osst_create_driverfs_files(struct device_driver *driverfs) +{ + driver_create_file(driverfs, &driver_attr_version); +} + +static void osst_remove_driverfs_files(struct device_driver *driverfs) +{ + driver_remove_file(driverfs, &driver_attr_version); +} + +/* + * sysfs support for accessing ADR header information + */ + +static ssize_t osst_adr_rev_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "%d.%d\n", STp->header_cache->major_rev, STp->header_cache->minor_rev); + return l; +} + +CLASS_DEVICE_ATTR(ADR_rev, S_IRUGO, osst_adr_rev_show, NULL); + +static ssize_t osst_linux_media_version_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "LIN%d\n", STp->linux_media_version); + return l; +} + +CLASS_DEVICE_ATTR(media_version, S_IRUGO, osst_linux_media_version_show, NULL); + +static ssize_t osst_capacity_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "%d\n", STp->capacity); + return l; +} + +CLASS_DEVICE_ATTR(capacity, S_IRUGO, osst_capacity_show, NULL); + +static ssize_t osst_first_data_ppos_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "%d\n", STp->first_data_ppos); + return l; +} + +CLASS_DEVICE_ATTR(BOT_frame, S_IRUGO, osst_first_data_ppos_show, NULL); + +static ssize_t osst_eod_frame_ppos_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "%d\n", STp->eod_frame_ppos); + return l; +} + +CLASS_DEVICE_ATTR(EOD_frame, S_IRUGO, osst_eod_frame_ppos_show, NULL); + +static ssize_t osst_filemark_cnt_show(struct class_device *class_dev, char *buf) +{ + struct osst_tape * STp = (struct osst_tape *) class_get_devdata (class_dev); + ssize_t l = 0; + + if (STp && STp->header_ok && STp->linux_media) + l = snprintf(buf, PAGE_SIZE, "%d\n", STp->filemark_cnt); + return l; +} + +CLASS_DEVICE_ATTR(file_count, S_IRUGO, osst_filemark_cnt_show, NULL); + +static struct class_simple * osst_sysfs_class; + +static int osst_sysfs_valid = 0; + +static void osst_sysfs_init(void) +{ + osst_sysfs_class = class_simple_create(THIS_MODULE, "onstream_tape"); + if ( IS_ERR(osst_sysfs_class) ) + printk(KERN_WARNING "osst :W: Unable to register sysfs class\n"); + else + osst_sysfs_valid = 1; +} + +static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * STp, char * name) +{ + struct class_device *osst_class_member; + + if (!osst_sysfs_valid) return; + + osst_class_member = class_simple_device_add(osst_sysfs_class, dev, device, "%s", name); + if (IS_ERR(osst_class_member)) { + printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name); + return; + } + class_set_devdata(osst_class_member, STp); + class_device_create_file(osst_class_member, &class_device_attr_ADR_rev); + class_device_create_file(osst_class_member, &class_device_attr_media_version); + class_device_create_file(osst_class_member, &class_device_attr_capacity); + class_device_create_file(osst_class_member, &class_device_attr_BOT_frame); + class_device_create_file(osst_class_member, &class_device_attr_EOD_frame); + class_device_create_file(osst_class_member, &class_device_attr_file_count); +} + +static void osst_sysfs_destroy(dev_t dev) +{ + if (!osst_sysfs_valid) return; + + class_simple_device_remove(dev); +} + +static void osst_sysfs_cleanup(void) +{ + if (osst_sysfs_valid) { + class_simple_destroy(osst_sysfs_class); + osst_sysfs_valid = 0; + } +} + /* * osst startup / cleanup code */ static int osst_probe(struct device *dev) { - Scsi_Device * SDp = to_scsi_device(dev); - OS_Scsi_Tape * tpnt; - ST_mode * STm; - ST_partstat * STps; - OSST_buffer * buffer; - struct gendisk * drive; - int i, mode, dev_num; + struct scsi_device * SDp = to_scsi_device(dev); + struct osst_tape * tpnt; + struct st_modedef * STm; + struct st_partstat * STps; + struct osst_buffer * buffer; + struct gendisk * drive; + int i, mode, dev_num; if (SDp->type != TYPE_TAPE || !osst_supports(SDp)) return -ENODEV; @@ -5436,7 +5661,7 @@ static int osst_probe(struct device *dev) write_lock(&os_scsi_tapes_lock); if (os_scsi_tapes == NULL) { os_scsi_tapes = - (OS_Scsi_Tape **)kmalloc(osst_max_dev * sizeof(OS_Scsi_Tape *), + (struct osst_tape **)kmalloc(osst_max_dev * sizeof(struct osst_tape *), GFP_ATOMIC); if (os_scsi_tapes == NULL) { write_unlock(&os_scsi_tapes_lock); @@ -5457,20 +5682,20 @@ static int osst_probe(struct device *dev) if(i >= osst_max_dev) panic ("Scsi_devices corrupt (osst)"); dev_num = i; - /* allocate a OS_Scsi_Tape for this device */ - tpnt = (OS_Scsi_Tape *)kmalloc(sizeof(OS_Scsi_Tape), GFP_ATOMIC); + /* allocate a struct osst_tape for this device */ + tpnt = (struct osst_tape *)kmalloc(sizeof(struct osst_tape), GFP_ATOMIC); if (tpnt == NULL) { write_unlock(&os_scsi_tapes_lock); printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n"); goto out_put_disk; } - memset(tpnt, 0, sizeof(OS_Scsi_Tape)); + memset(tpnt, 0, sizeof(struct osst_tape)); /* allocate a buffer for this device */ i = SDp->host->sg_tablesize; if (osst_max_sg_segs < i) i = osst_max_sg_segs; - buffer = new_tape_buffer(TRUE, SDp->host->unchecked_isa_dma, i); + buffer = new_tape_buffer(1, SDp->host->unchecked_isa_dma, i); if (buffer == NULL) { write_unlock(&os_scsi_tapes_lock); printk(KERN_ERR "osst :E: Unable to allocate a tape buffer, device not attached.\n"); @@ -5520,7 +5745,7 @@ static int osst_probe(struct device *dev) for (i=0; i < ST_NBR_MODES; i++) { STm = &(tpnt->modes[i]); - STm->defined = FALSE; + STm->defined = 0; STm->sysv = OSST_SYSV; STm->defaults_for_writes = 0; STm->do_async_writes = OSST_ASYNC_WRITES; @@ -5536,20 +5761,27 @@ static int osst_probe(struct device *dev) STps->rw = ST_IDLE; STps->eof = ST_NOEOF; STps->at_sm = 0; - STps->last_block_valid = FALSE; + STps->last_block_valid = 0; STps->drv_block = (-1); STps->drv_file = (-1); } tpnt->current_mode = 0; - tpnt->modes[0].defined = TRUE; - tpnt->modes[2].defined = TRUE; - tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = FALSE; + tpnt->modes[0].defined = 1; + tpnt->modes[2].defined = 1; + tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0; init_MUTEX(&tpnt->lock); osst_nr_dev++; write_unlock(&os_scsi_tapes_lock); - + { + char name[8]; + /* Rewind entry */ + osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num), dev, tpnt, tape_name(tpnt)); + /* No-rewind entry */ + snprintf(name, 8, "%s%s", "n", tape_name(tpnt)); + osst_sysfs_add(MKDEV(OSST_MAJOR, dev_num + 128), dev, tpnt, name); + } for (mode = 0; mode < ST_NBR_MODES; ++mode) { /* Rewind entry */ devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)), @@ -5576,8 +5808,8 @@ out_put_disk: static int osst_remove(struct device *dev) { - Scsi_Device * SDp = to_scsi_device(dev); - OS_Scsi_Tape * tpnt; + struct scsi_device * SDp = to_scsi_device(dev); + struct osst_tape * tpnt; int i, mode; if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0)) @@ -5586,6 +5818,8 @@ static int osst_remove(struct device *dev) write_lock(&os_scsi_tapes_lock); for(i=0; i < osst_max_dev; i++) { if((tpnt = os_scsi_tapes[i]) && (tpnt->device == SDp)) { + osst_sysfs_destroy(MKDEV(OSST_MAJOR, i)); + osst_sysfs_destroy(MKDEV(OSST_MAJOR, i+128)); tpnt->device = NULL; for (mode = 0; mode < ST_NBR_MODES; ++mode) { devfs_remove("%s/ot%s", SDp->devfs_name, osst_formats[mode]); @@ -5614,11 +5848,14 @@ static int __init init_osst(void) printk(KERN_INFO "osst :I: Tape driver with OnStream support version %s\nosst :I: %s\n", osst_version, cvsid); validate_options(); - + osst_sysfs_init(); + if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) { printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR); + osst_sysfs_cleanup(); return 1; } + osst_create_driverfs_files(&osst_template.gendrv); return 0; } @@ -5626,10 +5863,12 @@ static int __init init_osst(void) static void __exit exit_osst (void) { int i; - OS_Scsi_Tape * STp; + struct osst_tape * STp; + osst_remove_driverfs_files(&osst_template.gendrv); scsi_unregister_driver(&osst_template.gendrv); unregister_chrdev(OSST_MAJOR, "osst"); + osst_sysfs_cleanup(); if (os_scsi_tapes) { for (i=0; i < osst_max_dev; ++i) {