diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/aic7xxx.c | 1638 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx.h | 18 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx.seq | 192 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx_proc.c | 1 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx_seq.c | 694 | ||||
-rw-r--r-- | drivers/scsi/scsi.c | 5 | ||||
-rw-r--r-- | drivers/scsi/scsi_lib.c | 12 | ||||
-rw-r--r-- | drivers/scsi/scsi_scan.c | 4 | ||||
-rw-r--r-- | drivers/scsi/sg.c | 4 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 5 | ||||
-rw-r--r-- | drivers/scsi/st.c | 8 |
11 files changed, 1085 insertions, 1496 deletions
diff --git a/drivers/scsi/aic7xxx.c b/drivers/scsi/aic7xxx.c index 67648bc75..d9f952ca6 100644 --- a/drivers/scsi/aic7xxx.c +++ b/drivers/scsi/aic7xxx.c @@ -243,6 +243,8 @@ #include <linux/blk.h> #include <linux/tqueue.h> #include <linux/init.h> +#include <linux/spinlock.h> +#include <linux/smp.h> #include "sd.h" #include "scsi.h" #include "hosts.h" @@ -264,7 +266,7 @@ */ #define VIRT_TO_BUS(a) (unsigned int)virt_to_bus((void *)(a)) -#define AIC7XXX_C_VERSION "5.2.0" +#define AIC7XXX_C_VERSION "5.2.1" #define NUMBER(arr) (sizeof(arr) / sizeof(arr[0])) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) @@ -281,45 +283,12 @@ # define FALSE 0 #endif -/* - * We need the bios32.h file if we are kernel version 2.1.92 or less. The - * full set of pci_* changes wasn't in place until 2.1.93 - */ - -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92) -# if defined(__sparc_v9__) || defined(__powerpc__) -# error "PPC and Sparc platforms are only support under 2.1.92 and above" -# endif -# include <linux/bios32.h> -#endif - -#if defined(__powerpc__) +#if defined(__powerpc__) || defined(__i386) # define MMAPIO -# ifdef mb -# undef mb -# endif -# define mb() \ - __asm__ __volatile__("eieio" ::: "memory") -#elif defined(__i386__) -# define MMAPIO -# ifdef mb -# undef mb -# endif -# define mb() \ - __asm__ __volatile__("lock ; addl $0,0(%%esp)": : :"memory") -#elif defined(__alpha__) -# ifdef mb -# undef mb -# endif -# define mb() \ - __asm__ __volatile__("mb": : :"memory") #endif -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) -# include <linux/spinlock.h> -# include <linux/smp.h> -# define cpuid smp_processor_id() # if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) +# define cpuid smp_processor_id() # define DRIVER_LOCK_INIT \ spin_lock_init(&p->spin_lock); # define DRIVER_LOCK \ @@ -337,17 +306,6 @@ # define DRIVER_LOCK # define DRIVER_UNLOCK # endif -#else -# define cpuid 0 -# define DRIVER_LOCK_INIT -# define DRIVER_LOCK \ - save_flags(cpu_flags); \ - cli(); -# define DRIVER_UNLOCK \ - restore_flags(cpu_flags); -# define le32_to_cpu(x) (x) -# define cpu_to_le32(x) (x) -#endif /* * You can try raising me if tagged queueing is enabled, or lowering @@ -359,13 +317,6 @@ #define AIC7XXX_CMDS_PER_DEVICE 8 #endif -/* Set this to the delay in seconds after SCSI bus reset. */ -#ifdef CONFIG_AIC7XXX_RESET_DELAY -#define AIC7XXX_RESET_DELAY CONFIG_AIC7XXX_RESET_DELAY -#else -#define AIC7XXX_RESET_DELAY 5 -#endif - /* * Control collection of SCSI transfer statistics for the /proc filesystem. * @@ -377,28 +328,6 @@ #endif /* - * NOTE: Uncommenting the define below no longer has any effect, the - * tagged queue value array is always active now. I've added - * a setup option to set this particular array and I'm hoping - * insmod will be smart enough to set it properly as well. It's - * by use of this array that a person can enable tagged queueing. - * The DEFAULT_TAG_COMMANDS define has been changed to disable - * tagged queueing by default, so if your devices can handle tagged - * queueing you will need to add a line to their lilo.conf file like: - * append="aic7xxx=verbose,tag_info:{{32,32,32,32},{32,32,32,32}}" - * which will result in the first four devices on the first two - * controllers being set to a tagged queue depth of 32. - * - * Set this for defining the number of tagged commands on a device - * by device, and controller by controller basis. The first set - * of tagged commands will be used for the first detected aic7xxx - * controller, the second set will be used for the second detected - * aic7xxx controller, and so on. These values will *only* be used - * for targets that are tagged queueing capable; these values will - * be ignored in all other cases. The tag_commands is an array of - * 16 to allow for wide and twin adapters. Twin adapters will use - * indexes 0-7 for channel 0, and indexes 8-15 for channel 1. - * * *** Determining commands per LUN *** * * When AIC7XXX_CMDS_PER_DEVICE is not defined, the driver will use its @@ -408,7 +337,6 @@ * use an internal queue depth of 3, with no more than one of those * three commands active at one time. */ -/* #define AIC7XXX_TAGGED_QUEUEING_BY_DEVICE */ typedef struct { @@ -453,8 +381,8 @@ typedef struct /* * NOTE: The below structure is for reference only, the actual structure - * to modify in order to change things is located around line - * number 1305 + * to modify in order to change things is found after this fake one. + * adapter_tag_info_t aic7xxx_tag_info[] = { {DEFAULT_TAG_COMMANDS}, @@ -509,6 +437,7 @@ static const char *board_names[] = { "Adaptec AHA-394X Ultra SCSI host adapter", /* AIC_7882 */ "Adaptec AHA-398X Ultra SCSI host adapter", /* AIC_7883 */ "Adaptec AHA-2944 Ultra SCSI host adapter", /* AIC_7884 */ + "Adaptec AHA-2940UW Pro Ultra SCSI host adapter", /* AIC_7887 */ "Adaptec AIC-7895 Ultra SCSI host adapter", /* AIC_7895 */ "Adaptec AIC-7890/1 Ultra2 SCSI host adapter", /* AIC_7890 */ "Adaptec AHA-293X Ultra2 SCSI host adapter", /* AIC_7890 */ @@ -565,7 +494,7 @@ static const char *board_names[] = { * AIC-7770 I/O range to reserve for a card */ #define MINREG 0xC00 -#define MAXREG 0xCBF +#define MAXREG 0xCFF #define INTDEF 0x5C /* Interrupt Definition Register */ @@ -828,7 +757,8 @@ typedef enum { * and what flags weren't. This way, I could clean up the flag usage on * a use by use basis. Doug Ledford */ - AHC_NO_STPWR = 0x00040000, + AHC_MOTHERBOARD = 0x00020000, + AHC_NO_STPWEN = 0x00040000, AHC_RESET_DELAY = 0x00080000, AHC_A_SCANNED = 0x00100000, AHC_B_SCANNED = 0x00200000, @@ -1056,11 +986,8 @@ struct aic7xxx_host { struct timer_list dev_timer; unsigned long dev_expires[MAX_TARGETS]; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) spinlock_t spin_lock; volatile unsigned char cpu_lock_count[NR_CPUS]; -#endif - Scsi_Cmnd *dev_dtr_cmnd[MAX_TARGETS]; @@ -1384,9 +1311,7 @@ static int aic7xxx_seltime = 0x10; */ #ifdef MODULE static char * aic7xxx = NULL; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,18) MODULE_PARM(aic7xxx, "s"); -#endif /* * Just in case someone uses commas to separate items on the insmod @@ -1444,32 +1369,6 @@ static void aic7xxx_check_scbs(struct aic7xxx_host *p, char *buffer); * ***************************************************************************/ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) -static inline void -mdelay(int milliseconds) -{ - int i; - - for(i=0; i<milliseconds; i++) - udelay(1000); -} - -static inline int -time_after_eq(unsigned long a, unsigned long b) -{ - return((long)((a) - (b)) >= 0L); -} - -static inline int -timer_pending(struct timer_list *timer) -{ - return( timer->prev != NULL ); -} - -#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075 - -#endif - static inline unsigned char aic_inb(struct aic7xxx_host *p, long port) { @@ -1483,7 +1382,6 @@ aic_inb(struct aic7xxx_host *p, long port) { x = inb(p->base + port); } - mb(); return(x); #else return(inb(p->base + port)); @@ -1497,14 +1395,17 @@ aic_outb(struct aic7xxx_host *p, unsigned char val, long port) if(p->maddr) { writeb(val, p->maddr + port); + mb(); /* locked operation in order to force CPU ordering */ + readb(p->maddr + HCNTRL); /* dummy read to flush the PCI write */ } else { outb(val, p->base + port); + mb(); /* locked operation in order to force CPU ordering */ } - mb(); #else outb(val, p->base + port); + mb(); /* locked operation in order to force CPU ordering */ #endif } @@ -1642,7 +1543,7 @@ aic7xxx_setup(char *s) } else if (!strncmp(p, "verbose", n)) { - *(options[i].flag) = 0xff09; + *(options[i].flag) = 0xff29; } else { @@ -1669,7 +1570,7 @@ __setup("aic7xxx=", aic7xxx_setup); * is important since the sequencer can disable pausing for critical * sections. *-F*************************************************************************/ -static inline void +static void pause_sequencer(struct aic7xxx_host *p) { aic_outb(p, p->pause, HCNTRL); @@ -1677,6 +1578,10 @@ pause_sequencer(struct aic7xxx_host *p) { ; } + if(p->features & AHC_ULTRA2) + { + aic_inb(p, CCSCBCTL); + } } /*+F************************************************************************* @@ -1687,7 +1592,7 @@ pause_sequencer(struct aic7xxx_host *p) * Unpause the sequencer. Unremarkable, yet done often enough to * warrant an easy way to do it. *-F*************************************************************************/ -static inline void +static void unpause_sequencer(struct aic7xxx_host *p, int unpause_always) { if (unpause_always || @@ -1706,7 +1611,7 @@ unpause_sequencer(struct aic7xxx_host *p, int unpause_always) * Restart the sequencer program from address zero. This assumes * that the sequencer is already paused. *-F*************************************************************************/ -static inline void +static void restart_sequencer(struct aic7xxx_host *p) { aic_outb(p, 0, SEQADDR0); @@ -1787,7 +1692,6 @@ aic7xxx_download_instr(struct aic7xxx_host *p, int instrptr, struct ins_format1 *fmt1_ins; struct ins_format3 *fmt3_ins; unsigned char opcode; - volatile unsigned char hcntrl; instr = *(union ins_formats*) &seqprog[instrptr * 4]; @@ -1889,14 +1793,10 @@ aic7xxx_download_instr(struct aic7xxx_host *p, int instrptr, } } aic_outb(p, (instr.integer & 0xff), SEQRAM); - hcntrl = aic_inb(p, HCNTRL); aic_outb(p, ((instr.integer >> 8) & 0xff), SEQRAM); - hcntrl = aic_inb(p, HCNTRL); aic_outb(p, ((instr.integer >> 16) & 0xff), SEQRAM); - hcntrl = aic_inb(p, HCNTRL); aic_outb(p, ((instr.integer >> 24) & 0xff), SEQRAM); - hcntrl = aic_inb(p, HCNTRL); - udelay(50); + udelay(10); break; default: @@ -2151,7 +2051,7 @@ aic7xxx_find_syncrate(struct aic7xxx_host *p, unsigned int *period, * Use async transfers for this target */ *options = 0; - *period = 0; + *period = 255; syncrate = NULL; } return (syncrate); @@ -2950,6 +2850,7 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb) #define WIDE_INQUIRY_BITS 0x60 #define SYNC_INQUIRY_BITS 0x10 #define SCSI_VERSION_BITS 0x07 +#define SCSI_DT_BIT 0x04 if ( (buffer[7] & WIDE_INQUIRY_BITS) && (p->features & AHC_WIDE) ) { @@ -2968,48 +2869,66 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb) AHC_TRANS_CUR) ); unpause_sequencer(p, FALSE); } - if (buffer[7] & SYNC_INQUIRY_BITS) + if ( (buffer[7] & SYNC_INQUIRY_BITS) && + p->transinfo[tindex].user_offset ) { - p->needsdtr |= (1<<tindex); - p->needsdtr_copy |= (1<<tindex); - p->transinfo[tindex].goal_period = p->transinfo[tindex].user_period; p->transinfo[tindex].goal_options = p->transinfo[tindex].user_options; - if (p->transinfo[tindex].user_offset) + if (p->features & AHC_ULTRA2) + p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2; + else if (p->transinfo[tindex].goal_width == MSG_EXT_WDTR_BUS_16_BIT) + p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT; + else + p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT; + if ( (((buffer[2] & SCSI_VERSION_BITS) == 3) || + (buffer[56] & SCSI_DT_BIT) || + (p->dev_flags[tindex] & DEVICE_SCSI_3) ) && + (p->transinfo[tindex].user_period <= 9) && + (p->transinfo[tindex].user_options) ) { - if (p->features & AHC_ULTRA2) - p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2; - else if (p->transinfo[tindex].goal_width == MSG_EXT_WDTR_BUS_16_BIT) - p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT; - else - p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT; + p->needppr |= (1<<tindex); + p->needppr_copy |= (1<<tindex); + p->needsdtr &= ~(1<<tindex); + p->needsdtr_copy &= ~(1<<tindex); + p->needwdtr &= ~(1<<tindex); + p->needwdtr_copy &= ~(1<<tindex); + p->dev_flags[tindex] |= DEVICE_SCSI_3; + } + else + { + p->needsdtr |= (1<<tindex); + p->needsdtr_copy |= (1<<tindex); + p->transinfo[tindex].goal_period = + MAX(10, p->transinfo[tindex].goal_period); + p->transinfo[tindex].goal_options = 0; } } else { p->needsdtr &= ~(1<<tindex); p->needsdtr_copy &= ~(1<<tindex); - p->transinfo[tindex].goal_period = 0; + p->transinfo[tindex].goal_period = 255; p->transinfo[tindex].goal_offset = 0; p->transinfo[tindex].goal_options = 0; } - if ( (buffer[2] & SCSI_VERSION_BITS) == 3 ) + /* + * This is needed to work around a sequencer bug for now. Regardless + * of the controller in use, if we have a Quantum drive, we need to + * limit the speed to 80MByte/sec. As soon as I get a fixed version + * of the sequencer, this code will get yanked. + */ + if(!strncmp(buffer + 8, "QUANTUM", 7) && + p->transinfo[tindex].goal_options ) { - p->dev_flags[tindex] |= DEVICE_SCSI_3; - /* - * OK, we are a SCSI 3 device and we are in need of negotiation. - * Use PPR messages instead of WDTR and SDTR messages. - */ - if ( (p->needsdtr & (1<<tindex)) || - (p->needwdtr & (1<<tindex)) ) - { - p->needppr |= (1<<tindex); - p->needppr_copy |= (1<<tindex); - } - p->needwdtr &= ~(1<<tindex); - p->needwdtr_copy &= ~(1<<tindex); - p->needsdtr &= ~(1<<tindex); - p->needsdtr_copy &= ~(1<<tindex); + p->transinfo[tindex].goal_period = + MAX(p->transinfo[tindex].goal_period, 10); + p->transinfo[tindex].goal_options = 0; + p->needppr &= ~(1<<tindex); + p->needppr_copy &= ~(1<<tindex); + p->needsdtr |= (1<<tindex); + p->needsdtr_copy |= (1<<tindex); + p->needwdtr |= (1<<tindex); + p->needwdtr_copy |= (1<<tindex); } /* * Get the INQUIRY checksum. We use this on Ultra 160/m @@ -3039,6 +2958,7 @@ aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb) #undef WIDE_INQUIRY_BITS #undef SYNC_INQUIRY_BITS #undef SCSI_VERSION_BITS +#undef SCSI_DT_BIT } } else if ((scb->flags & SCB_MSGOUT_BITS) != 0) @@ -4170,12 +4090,7 @@ aic7xxx_pci_intr(struct aic7xxx_host *p) { unsigned char status1; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) pci_read_config_byte(p->pdev, PCI_STATUS + 1, &status1); -#else - pcibios_read_config_byte(p->pci_bus, p->pci_device_fn, - PCI_STATUS + 1, &status1); -#endif if ( (status1 & DPE) && (aic7xxx_verbose & VERBOSE_MINOR_ERROR) ) printk(WARN_LEAD "Data Parity Error during PCI address or PCI write" @@ -4196,12 +4111,7 @@ aic7xxx_pci_intr(struct aic7xxx_host *p) printk(WARN_LEAD "Data Parity Error has been reported via PCI pin " "PERR#\n", p->host_no, -1, -1, -1); -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) pci_write_config_byte(p->pdev, PCI_STATUS + 1, status1); -#else - pcibios_write_config_byte(p->pci_bus, p->pci_device_fn, - PCI_STATUS + 1, status1); -#endif if (status1 & (DPR|RMA|RTA)) aic_outb(p, CLRPARERR, CLRINT); @@ -4226,11 +4136,7 @@ aic7xxx_timer(struct aic7xxx_host *p) unsigned long cpu_flags = 0; struct aic7xxx_scb *scb; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - DRIVER_LOCK -#else spin_lock_irqsave(&io_request_lock, cpu_flags); -#endif p->dev_timer_active &= ~(0x01 << MAX_TARGETS); if ( (p->dev_timer_active & (0x01 << p->scsi_id)) && time_after_eq(jiffies, p->dev_expires[p->scsi_id]) ) @@ -4287,11 +4193,7 @@ aic7xxx_timer(struct aic7xxx_host *p) } aic7xxx_run_waiting_queues(p); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) - DRIVER_UNLOCK -#else spin_unlock_irqrestore(&io_request_lock, cpu_flags); -#endif } /*+F************************************************************************* @@ -4673,7 +4575,9 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) * As per the draft specs, any device capable of supporting any of * the option values other than 0 are not allowed to reject the * PPR message. Instead, they must negotiate out what they do - * support instead of rejecting our offering. + * support instead of rejecting our offering or else they cause + * a parity error during msg_out phase to signal that they don't + * like our settings. */ p->needppr &= ~target_mask; p->needppr_copy &= ~target_mask; @@ -4813,39 +4717,36 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) case CHECK_CONDITION: if ( !(scb->flags & SCB_SENSE) ) { - unsigned char *sense_buffer; - /* - * XXX - How do we save the residual (if there is one). - */ - if ( hscb->residual_SG_segment_count != 0 ) - aic7xxx_calculate_residual(p, scb); - /* - * Send a sense command to the requesting target. + * Send a sense command to the requesting target. * XXX - revisit this and get rid of the memcopys. - */ + */ memcpy(scb->sense_cmd, &generic_sense[0], sizeof(generic_sense)); scb->sense_cmd[1] = (cmd->lun << 5); scb->sense_cmd[4] = sizeof(cmd->sense_buffer); - sense_buffer = cmd->sense_buffer; scb->sg_list[0].length = cpu_to_le32(sizeof(cmd->sense_buffer)); + scb->sg_list[0].address = + cpu_to_le32(pci_map_single(p->pdev, cmd->sense_buffer, + sizeof(cmd->sense_buffer), + PCI_DMA_FROMDEVICE)); /* * XXX - We should allow disconnection, but can't as it * might allow overlapped tagged commands. */ - /* hscb->control &= DISCENB; */ + /* hscb->control &= DISCENB; */ hscb->control = 0; hscb->target_status = 0; hscb->SG_list_pointer = cpu_to_le32(SCB_DMA_ADDR(scb, scb->sg_list)); - hscb->data_count = scb->sg_list[0].length; hscb->SCSI_cmd_pointer = cpu_to_le32(SCB_DMA_ADDR(scb, scb->sense_cmd)); + hscb->data_count = scb->sg_list[0].length; + hscb->data_pointer = scb->sg_list[0].address; hscb->SCSI_cmd_length = COMMAND_SIZE(scb->sense_cmd[0]); hscb->residual_SG_segment_count = 0; hscb->residual_data_count[0] = 0; @@ -4855,53 +4756,6 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) scb->sg_count = hscb->SG_segment_count = 1; scb->sg_length = sizeof(cmd->sense_buffer); scb->tag_action = 0; - /* - * This problem could be caused if the target has lost power - * or found some other way to loose the negotiation settings, - * so if needed, we'll re-negotiate while doing the sense cmd. - * However, if this SCB already was attempting to negotiate, - * then we assume this isn't the problem and skip this part. - */ - if ( (scb->cmd->cmnd[0] != TEST_UNIT_READY) && - (p->dev_flags[tindex] & DEVICE_SCANNED) && - !(p->dtr_pending & target_mask) ) - { - p->needppr |= (p->needppr_copy & target_mask); - p->needwdtr |= (p->needwdtr_copy & target_mask); - p->needsdtr |= (p->needsdtr_copy & target_mask); - } - else if ( scb->cmd == p->dev_dtr_cmnd[tindex] ) - { - /* - * This is already a negotiation command, so we must have - * already done PPR, WDTR or SDTR. Since our negotiation - * could have gotten rejected, we don't really know the - * full state of things. Don't do anything here, and allow - * the negotiation_complete() handler to do the right - * thing. - */ - - /* - * This is the important part though. We are getting sense - * info back from this device. It's going into a fake - * command. We need to put that into the real command - * instead so that the mid level SCSI code can act upon it. - * So, when we set up these fake commands, the next pointer - * is used to point to the real command. Use that to change - * the address of our sense_buffer[] to the real command. - * However, don't do this if the real command is also a - * TEST_UNIT_READY as it will most likely pull down its own - * SENSE information anyway. - */ - if (cmd->next->cmnd[0] != TEST_UNIT_READY) - sense_buffer = cmd->next->sense_buffer; - } - scb->sg_list[0].address = - cpu_to_le32(pci_map_single(p->pdev, sense_buffer, - sizeof(cmd->sense_buffer), - PCI_DMA_FROMDEVICE)); - hscb->data_pointer = scb->sg_list[0].address; - scb->flags |= SCB_SENSE; /* * Ensure the target is busy since this will be an @@ -4924,7 +4778,7 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) aic7xxx_error(cmd) = DID_OK; break; } /* first time sense, no errors */ - aic7xxx_error(cmd) = DID_OK; + aic7xxx_error(cmd) = DID_ERROR; scb->flags &= ~SCB_SENSE; break; @@ -5171,51 +5025,14 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) } else if (scb->flags & SCB_MSGOUT_PPR) { - unsigned int max_sync, period; - unsigned char options = 0; - - if (p->features & AHC_ULTRA2) - { - if ( (aic_inb(p, SBLKCTL) & ENAB40) && - !(aic_inb(p, SSTAT2) & EXP_ACTIVE) ) - { - if( (p->features & AHC_ULTRA3) && - (p->dev_flags[tindex] & DEVICE_SCSI_3) && - (p->transinfo[tindex].goal_width == - MSG_EXT_WDTR_BUS_16_BIT) && - (p->transinfo[tindex].goal_options != 0) ) - { - max_sync = AHC_SYNCRATE_ULTRA3; - options = p->transinfo[tindex].goal_options; - } - else - { - max_sync = AHC_SYNCRATE_ULTRA2; - } - } - else - { - max_sync = AHC_SYNCRATE_ULTRA; - } - } - else if (p->features & AHC_ULTRA) - { - max_sync = AHC_SYNCRATE_ULTRA; - } - else - { - max_sync = AHC_SYNCRATE_FAST; - } - period = p->transinfo[tindex].goal_period; - aic7xxx_find_syncrate(p, &period, max_sync, &options); - p->transinfo[tindex].goal_period = period; - p->transinfo[tindex].goal_options = options; if (aic7xxx_verbose & VERBOSE_NEGOTIATION2) { printk(INFO_LEAD "Sending PPR (%d/%d/%d/%d) message.\n", - p->host_no, CTL_OF_SCB(scb), period, + p->host_no, CTL_OF_SCB(scb), + p->transinfo[tindex].goal_period, p->transinfo[tindex].goal_offset, - p->transinfo[tindex].goal_width, options); + p->transinfo[tindex].goal_width, + p->transinfo[tindex].goal_options); } aic7xxx_construct_ppr(p, scb); } @@ -5261,8 +5078,7 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) if (aic7xxx_verbose & VERBOSE_NEGOTIATION2) { printk(INFO_LEAD "Sending SDTR %d/%d message.\n", p->host_no, - CTL_OF_SCB(scb), - p->transinfo[tindex].goal_period, + CTL_OF_SCB(scb), period, p->transinfo[tindex].goal_offset); } aic7xxx_construct_sdtr(p, period, @@ -5375,15 +5191,15 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) resid_sgcnt = aic_inb(p, SCB_RESID_SGCNT); resid_dcnt = aic_inb(p, SCB_RESID_DCNT) | (aic_inb(p, SCB_RESID_DCNT + 1) << 8) | - (aic_inb(p, SCB_RESID_DCNT + 2) << 24); - index = scb->sg_count - resid_sgcnt; + (aic_inb(p, SCB_RESID_DCNT + 2) << 16); + index = scb->sg_count - (resid_sgcnt + 1); native_addr = le32_to_cpu(scb->sg_list[index].address); native_length = le32_to_cpu(scb->sg_list[index].length); /* * Make sure this is a valid sg_seg for the given pointer */ if(cur_addr < native_addr || - cur_addr > (native_addr + native_length)) + cur_addr > (native_addr + native_length + 1)) { printk(WARN_LEAD "invalid cur_addr:0x%x during WIDE_RESIDUE\n", p->host_no, CTL_OF_SCB(scb), cur_addr); @@ -5400,16 +5216,31 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) p->host_no, CTL_OF_SCB(scb), le32_to_cpu(scb->sg_list[index + 1].address), le32_to_cpu(scb->sg_list[index + 1].length)); + printk(WARN_LEAD " cur_address:0x%x resid_dcnt:0x%06x\n", + p->host_no, CTL_OF_SCB(scb), + cur_addr, resid_dcnt); break; } - /* - * If our current address matches the sg_seg->address then we - * have to back up the sg array to the previous segment and set - * it up to have only one byte of transfer left to go. - */ - if(cur_addr == native_addr) + if( (resid_sgcnt == 0) && + ((resid_dcnt == 0) || (resid_dcnt == 0xffffff))) + { + /* + * We are at the end of the transfer and this is about a byte + * we ignored already (because the sequencer knew this was + * the last segment and set the adapter to ignore any wide + * residue bytes that might come through, which is only done + * on the last scatter gather segment of transfers). + */ + break; + } + else if(cur_addr == native_addr) { + /* + * If our current address matches the sg_seg->address then we + * have to back up the sg array to the previous segment and set + * it up to have only one byte of transfer left to go. + */ if(index == 0) { printk(WARN_LEAD "bogus WIDE_RESIDUE message, no data has been " @@ -5439,39 +5270,6 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) aic_outb(p, (cur_addr >> 8) & 0xff, HADDR + 1); aic_outb(p, (cur_addr >> 16) & 0xff, HADDR + 2); aic_outb(p, (cur_addr >> 24) & 0xff, HADDR + 3); - /* - * The sequencer actually wants to find the new address and byte - * count in the SHCNT and SHADDR register sets. These registers - * are a shadow of the regular HCNT and HADDR registers. On the - * Ultra2 controllers, these registers are read only and the way - * we have to set their values is to put the values we want into - * the HCNT and HADDR registers and then output PRELOADEN into - * the DFCNTRL register which causes the card to latch the current - * values in the HADDR and HCNT registers and drop it through to - * the shadow registers. On older cards we copy them directly - * across by hand. - */ - if(p->features & AHC_ULTRA2) - { - aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL); - i=0; - udelay(1); - while(((aic_inb(p, SSTAT0) & SDONE) != 0) && (i++ < 1000)) - { - aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL); - udelay(1); - } - } - else - { - aic_outb(p, 1, STCNT); - aic_outb(p, 0, STCNT + 1); - aic_outb(p, 0, STCNT + 2); - aic_outb(p, cur_addr & 0xff, SHADDR); - aic_outb(p, (cur_addr >> 8) & 0xff, SHADDR + 1); - aic_outb(p, (cur_addr >> 16) & 0xff, SHADDR + 2); - aic_outb(p, (cur_addr >> 24) & 0xff, SHADDR + 3); - } } else { @@ -5491,28 +5289,46 @@ aic7xxx_handle_seqint(struct aic7xxx_host *p, unsigned char intstat) aic_outb(p, (cur_addr >> 8) & 0xff, HADDR + 1); aic_outb(p, (cur_addr >> 16) & 0xff, HADDR + 2); aic_outb(p, (cur_addr >> 24) & 0xff, HADDR + 3); - if(p->features & AHC_ULTRA2) + } + /* + * The sequencer actually wants to find the new address and byte + * count in the SHCNT and SHADDR register sets. These registers + * are a shadow of the regular HCNT and HADDR registers. On the + * Ultra2 controllers, these registers are read only and the way + * we have to set their values is to put the values we want into + * the HCNT and HADDR registers and then output PRELOADEN into + * the DFCNTRL register which causes the card to latch the current + * values in the HADDR and HCNT registers and drop it through to + * the shadow registers. On older cards we copy them directly + * across by hand. + */ + if(p->features & AHC_ULTRA2) + { + aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL); + i=0; + udelay(1); + while(((aic_inb(p, SSTAT0) & SDONE) != 0) && (i++ < 1000)) { - aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL); - i=0; udelay(1); - while(((aic_inb(p, SSTAT0) & SDONE) != 0) && (i++ < 1000)) - { - aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL); - udelay(1); - } } - else + aic_outb(p, aic_inb(p, DMAPARAMS) & ~(SCSIEN|HDMAEN), DFCNTRL); + i=0; + udelay(1); + while(((aic_inb(p, DFCNTRL) & (SCSIEN|HDMAEN)) != 0) && (i++ < 1000)) { - aic_outb(p, resid_dcnt & 0xff, STCNT); - aic_outb(p, (resid_dcnt >> 8) & 0xff, STCNT + 1); - aic_outb(p, (resid_dcnt >> 16) & 0xff, STCNT + 2); - aic_outb(p, cur_addr & 0xff, SHADDR); - aic_outb(p, (cur_addr >> 8) & 0xff, SHADDR + 1); - aic_outb(p, (cur_addr >> 16) & 0xff, SHADDR + 2); - aic_outb(p, (cur_addr >> 24) & 0xff, SHADDR + 3); + udelay(1); } } + else + { + aic_outb(p, resid_dcnt & 0xff, STCNT); + aic_outb(p, (resid_dcnt >> 8) & 0xff, STCNT + 1); + aic_outb(p, (resid_dcnt >> 16) & 0xff, STCNT + 2); + aic_outb(p, cur_addr & 0xff, SHADDR); + aic_outb(p, (cur_addr >> 8) & 0xff, SHADDR + 1); + aic_outb(p, (cur_addr >> 16) & 0xff, SHADDR + 2); + aic_outb(p, (cur_addr >> 24) & 0xff, SHADDR + 3); + } } break; @@ -5921,6 +5737,7 @@ aic7xxx_parse_msg(struct aic7xxx_host *p, struct aic7xxx_scb *scb) reply = TRUE; scb->flags &= ~SCB_MSGOUT_BITS; scb->flags |= SCB_MSGOUT_PPR; + p->dev_flags[tindex] |= DEVICE_SCSI_3; if (!(p->dev_flags[tindex] & DEVICE_SCANNED)) { /* @@ -5954,7 +5771,6 @@ aic7xxx_parse_msg(struct aic7xxx_host *p, struct aic7xxx_scb *scb) p->transinfo[tindex].user_width; p->transinfo[tindex].goal_options = p->transinfo[tindex].user_options; - p->needppr_copy |= target_mask; } if (aic7xxx_verbose & VERBOSE_NEGOTIATION2) { @@ -5988,6 +5804,25 @@ aic7xxx_parse_msg(struct aic7xxx_host *p, struct aic7xxx_scb *scb) break; } } + if ( (p->transinfo[tindex].goal_period > 9) || + (p->transinfo[tindex].goal_options == 0) ) + { + scb->flags &= ~SCB_MSGOUT_BITS; + reject = TRUE; + reply = FALSE; + p->needppr &= ~(1 << tindex); + p->needppr_copy &= ~(1 << tindex); + if ( p->transinfo[tindex].goal_offset ) + { + p->needsdtr |= (1 << tindex); + p->needsdtr_copy |= (1 << tindex); + } + if ( p->transinfo[tindex].goal_width ) + { + p->needwdtr |= (1 << tindex); + p->needwdtr_copy |= (1 << tindex); + } + } } else { @@ -5995,7 +5830,7 @@ aic7xxx_parse_msg(struct aic7xxx_host *p, struct aic7xxx_scb *scb) { default: { - reply = TRUE; + reject = TRUE; if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) && ((p->dev_flags[tindex] & DEVICE_PRINT_DTR) || (aic7xxx_verbose > 0xffff)) ) @@ -6021,27 +5856,18 @@ aic7xxx_parse_msg(struct aic7xxx_host *p, struct aic7xxx_scb *scb) } } - aic7xxx_set_width(p, target, channel, lun, bus_width, - AHC_TRANS_ACTIVE|AHC_TRANS_CUR); - syncrate = aic7xxx_find_syncrate(p, &period, maxsync, - &new_trans_options); - aic7xxx_validate_offset(p, syncrate, &offset, bus_width); - aic7xxx_set_syncrate(p, syncrate, target, channel, period, - offset, new_trans_options, - AHC_TRANS_ACTIVE|AHC_TRANS_CUR); - - if( (offset != saved_offset) || - (trans_options != new_trans_options) || - ((scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_PPR)) != - (SCB_MSGOUT_SENT|SCB_MSGOUT_PPR)) ) + if ( !reject ) { aic7xxx_set_width(p, target, channel, lun, bus_width, - AHC_TRANS_GOAL|AHC_TRANS_QUITE); + AHC_TRANS_ACTIVE|AHC_TRANS_CUR); + syncrate = aic7xxx_find_syncrate(p, &period, maxsync, + &new_trans_options); + aic7xxx_validate_offset(p, syncrate, &offset, bus_width); aic7xxx_set_syncrate(p, syncrate, target, channel, period, offset, new_trans_options, - AHC_TRANS_GOAL|AHC_TRANS_QUITE); - reply = TRUE; + AHC_TRANS_ACTIVE|AHC_TRANS_CUR); } + p->dtr_pending &= ~target_mask; p->needppr &= ~target_mask; if(reply) @@ -6445,15 +6271,33 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat) } } /* - * Restarting the sequencer will stop the selection and make sure devices - * are allowed to reselect in. + * Keep the sequencer from trying to restart any selections + */ + aic_outb(p, aic_inb(p, SCSISEQ) & ~ENSELO, SCSISEQ); + /* + * Make sure the data bits on the bus are released + * Don't do this on 7770 chipsets, it makes them give us + * a BRKADDRINT and kills the card. */ - aic_outb(p, 0, SCSISEQ); + if( (p->chip & ~AHC_CHIPID_MASK) == AHC_PCI ) + aic_outb(p, 0, SCSIBUSL); + + /* + * Delay for the selection timeout delay period then stop the selection + */ + udelay(301); aic_outb(p, CLRSELINGO, CLRSINT0); + /* + * Clear out all the interrupt status bits + */ aic_outb(p, aic_inb(p, SIMODE1) & ~(ENREQINIT|ENBUSFREE), SIMODE1); p->flags &= ~AHC_HANDLING_REQINITS; aic_outb(p, CLRSELTIMEO | CLRBUSFREE, CLRSINT1); aic_outb(p, CLRSCSIINT, CLRINT); + /* + * Restarting the sequencer will stop the selection and make sure devices + * are allowed to reselect in. + */ restart_sequencer(p); unpause_sequencer(p, TRUE); } @@ -6519,7 +6363,9 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat) * A parity error has occurred during a data * transfer phase. Flag it and continue. */ - if( (aic_inb(p, SCSIRATE) & AHC_SYNCRATE_CRC) && (lastphase == P_DATAIN) ) + if( (p->features & AHC_ULTRA3) && + (aic_inb(p, SCSIRATE) & AHC_SYNCRATE_CRC) && + (lastphase == P_DATAIN) ) { printk(WARN_LEAD "CRC error during %s phase.\n", p->host_no, CTL_OF_SCB(scb), phase); @@ -6544,13 +6390,50 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat) p->host_no, CTL_OF_SCB(scb)); } } - else + else if( (lastphase == P_MESGOUT) && + (cmd == p->dev_dtr_cmnd[tindex]) && + (scb->flags & SCB_MSGOUT_PPR) ) { - printk(WARN_LEAD "Parity error during %s phase.\n", - p->host_no, CTL_OF_SCB(scb), phase); + /* + * As per the draft specs, any device capable of supporting any of + * the option values other than 0 are not allowed to reject the + * PPR message. Instead, they must negotiate out what they do + * support instead of rejecting our offering or else they cause + * a parity error during msg_out phase to signal that they don't + * like our settings. + */ + p->needppr &= ~(1 << tindex); + p->needppr_copy &= ~(1 << tindex); + aic7xxx_set_width(p, scb->cmd->target, scb->cmd->channel, scb->cmd->lun, + MSG_EXT_WDTR_BUS_8_BIT, + (AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE)); + aic7xxx_set_syncrate(p, NULL, scb->cmd->target, scb->cmd->channel, 0, 0, + 0, AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE); + p->transinfo[tindex].goal_options = 0; + p->dtr_pending &= ~(1 << tindex); + scb->flags &= ~SCB_MSGOUT_BITS; + if(aic7xxx_verbose & VERBOSE_NEGOTIATION2) + { + printk(INFO_LEAD "parity error during PPR message, reverting " + "to WDTR/SDTR\n", p->host_no, CTL_OF_SCB(scb)); + } + if ( p->transinfo[tindex].goal_width ) + { + p->needwdtr |= (1 << tindex); + p->needwdtr_copy |= (1 << tindex); + } + if ( p->transinfo[tindex].goal_offset ) + { + if( p->transinfo[tindex].goal_period <= 9 ) + { + p->transinfo[tindex].goal_period = 10; + } + p->needsdtr |= (1 << tindex); + p->needsdtr_copy |= (1 << tindex); + } + scb = NULL; } - - if(p->dev_flags[tindex] & DEVICE_PARITY_ERROR) + else if(p->dev_flags[tindex] & DEVICE_PARITY_ERROR) { struct aic7xxx_syncrate *syncrate; unsigned int period = p->transinfo[tindex].cur_period; @@ -6562,6 +6445,8 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat) * instead of slowing down if those exist. That's hard to do with simple * checksums though. */ + printk(WARN_LEAD "Parity error during %s phase.\n", + p->host_no, CTL_OF_SCB(scb), phase); if((syncrate = aic7xxx_find_syncrate(p, &period, 0, &options)) != NULL) { syncrate++; @@ -6569,20 +6454,59 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat) (!(p->features & AHC_ULTRA2) || (syncrate->sxfr_ultra2 == 0)) ) { p->transinfo[tindex].goal_period = syncrate->period; - if( !(syncrate->sxfr_ultra2 & 0x40) ) + if( p->transinfo[tindex].goal_period > 9 ) { p->transinfo[tindex].goal_options = 0; + p->needppr &= ~(1<<tindex); + p->needsdtr |= (1<<tindex); + p->needppr_copy &= ~(1<<tindex); + p->needsdtr_copy |= (1<<tindex); + if (p->transinfo[tindex].goal_width) + { + p->needwdtr |= (1<<tindex); + p->needwdtr_copy |= (1<<tindex); + } + } + } + else if (p->transinfo[tindex].goal_width) + { + p->transinfo[tindex].goal_width = 0; + p->needwdtr &= ~(1<<tindex); + p->needwdtr_copy &= ~(1<<tindex); + p->transinfo[tindex].goal_offset = + p->transinfo[tindex].user_offset; + p->transinfo[tindex].goal_period = + p->transinfo[tindex].user_period; + p->transinfo[tindex].goal_options = + p->transinfo[tindex].user_options; + if( p->transinfo[tindex].goal_period <= 9 ) + { + p->needppr |= (1<<tindex); + p->needsdtr &= ~(1<<tindex); + p->needppr_copy |= (1<<tindex); + p->needsdtr_copy &= ~(1<<tindex); + } + else + { + p->needppr &= ~(1<<tindex); + p->needsdtr |= (1<<tindex); + p->needppr_copy &= ~(1<<tindex); + p->needsdtr_copy |= (1<<tindex); } } else { p->transinfo[tindex].goal_offset = 0; - p->transinfo[tindex].goal_period = 0; + p->transinfo[tindex].goal_period = 255; p->transinfo[tindex].goal_options = 0; + p->transinfo[tindex].goal_width = 0; + p->needppr &= ~(1<<tindex); + p->needsdtr &= ~(1<<tindex); + p->needwdtr &= ~(1<<tindex); + p->needppr_copy &= ~(1<<tindex); + p->needsdtr_copy &= ~(1<<tindex); + p->needwdtr_copy &= ~(1<<tindex); } - p->needppr |= (p->needppr_copy & (1<<tindex)); - p->needsdtr |= (p->needsdtr_copy & (1<<tindex)); - p->needwdtr |= (p->needwdtr_copy & (1<<tindex)); } p->dev_flags[tindex] &= ~DEVICE_PARITY_ERROR; } @@ -6600,6 +6524,7 @@ aic7xxx_handle_scsiint(struct aic7xxx_host *p, unsigned char intstat) if (mesg_out != MSG_NOOP) { aic_outb(p, mesg_out, MSG_OUT); + aic_outb(p, aic_inb(p, SCSISIGI) | ATNO, SCSISIGO); scb = NULL; } aic_outb(p, CLRSCSIPERR, CLRSINT1); @@ -6791,7 +6716,7 @@ aic7xxx_handle_command_completion_intr(struct aic7xxx_host *p) { struct aic7xxx_scb *scb = NULL; Scsi_Cmnd *cmd; - unsigned char scb_index; + unsigned char scb_index, tindex; #ifdef AIC7XXX_VERBOSE_DEBUGGING if( (p->isr_count < 16) && (aic7xxx_verbose > 0xffff) ) @@ -6817,23 +6742,21 @@ aic7xxx_handle_command_completion_intr(struct aic7xxx_host *p) scb_index = p->qoutfifo[p->qoutfifonext]; p->qoutfifo[p->qoutfifonext++] = SCB_LIST_NULL; if ( scb_index >= p->scb_data->numscbs ) - scb = NULL; - else - scb = p->scb_data->scb_array[scb_index]; - if (scb == NULL) { printk(WARN_LEAD "CMDCMPLT with invalid SCB index %d\n", p->host_no, -1, -1, -1, scb_index); continue; } - else if (!(scb->flags & SCB_ACTIVE) || (scb->cmd == NULL)) + scb = p->scb_data->scb_array[scb_index]; + if (!(scb->flags & SCB_ACTIVE) || (scb->cmd == NULL)) { printk(WARN_LEAD "CMDCMPLT without command for SCB %d, SCB flags " "0x%x, cmd 0x%lx\n", p->host_no, -1, -1, -1, scb_index, scb->flags, (unsigned long) scb->cmd); continue; } - else if (scb->flags & SCB_QUEUED_ABORT) + tindex = TARGET_INDEX(scb->cmd); + if (scb->flags & SCB_QUEUED_ABORT) { pause_sequencer(p); if ( ((aic_inb(p, LASTPHASE) & PHASE_MASK) != P_BUSFREE) && @@ -6856,6 +6779,43 @@ aic7xxx_handle_command_completion_intr(struct aic7xxx_host *p) */ scb->flags &= ~(SCB_ABORT|SCB_RESET); } + else if (scb->flags & SCB_SENSE) + { + char *buffer = &scb->cmd->sense_buffer[0]; + if (scb->cmd == p->dev_dtr_cmnd[tindex]) + { + struct aic7xxx_scb *old_scb; + /* + * We have valid sense data, send it back immediately. + */ + old_scb = p->scb_data->scb_array[scb->cmd->next->tag]; + *old_scb->cmd->sense_buffer = *scb->cmd->sense_buffer; + old_scb->hscb->target_status = scb->hscb->target_status; + old_scb->cmd->result = scb->hscb->target_status; + old_scb->cmd->result |= (DID_ERROR << 16); + aic7xxx_status(old_scb->cmd) = scb->hscb->target_status; + scbq_remove(&p->waiting_scbs, old_scb); + scbq_remove(&p->delayed_scbs[tindex], old_scb); + scb->cmd->next = NULL; + aic7xxx_done(p, scb); + aic7xxx_done(p, old_scb); + continue; + } + else if (buffer[12] == 0x47 || buffer[12] == 0x54) + { + /* + * SCSI errors, run domain validation and re-run negotiation + */ + p->needdv |= (1<<tindex); + /* + * Signal that we need to re-negotiate things, this also gets us our + * INQUIRY command to re-checksum off of. + */ + p->needppr |= (p->needppr_copy & (1<<tindex)); + p->needsdtr |= (p->needsdtr_copy & (1<<tindex)); + p->needwdtr |= (p->needwdtr_copy & (1<<tindex)); + } + } switch (status_byte(scb->hscb->target_status)) { case QUEUE_FULL: @@ -6985,6 +6945,13 @@ aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs) if (intstat & SEQINT) { + /* + * Read the CCSCBCTL register to work around a bug in the Ultra2 cards + */ + if(p->features & AHC_ULTRA2) + { + aic_inb(p, CCSCBCTL); + } aic7xxx_handle_seqint(p, intstat); } @@ -7019,10 +6986,10 @@ do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs) p = (struct aic7xxx_host *)dev_id; if(!p) return; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95) spin_lock_irqsave(&io_request_lock, cpu_flags); if(test_and_set_bit(AHC_IN_ISR_BIT, (void *)&p->flags)) { + spin_unlock_irqrestore(&io_request_lock, cpu_flags); return; } do @@ -7033,21 +7000,6 @@ do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs) aic7xxx_run_waiting_queues(p); clear_bit(AHC_IN_ISR_BIT, (void *)&p->flags); spin_unlock_irqrestore(&io_request_lock, cpu_flags); -#else - if(set_bit(AHC_IN_ISR_BIT, (int *)&p->flags)) - { - return; - } - DRIVER_LOCK - do - { - aic7xxx_isr(irq, dev_id, regs); - } while ( (aic_inb(p, INTSTAT) & INT_PEND) ); - DRIVER_UNLOCK - aic7xxx_done_cmds_complete(p); - aic7xxx_run_waiting_queues(p); - clear_bit(AHC_IN_ISR_BIT, (int *)&p->flags); -#endif } /*+F************************************************************************* @@ -7067,7 +7019,7 @@ do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs) * with queue depths for individual devices. It also allows tagged * queueing to be [en|dis]abled for a specific adapter. *-F*************************************************************************/ -static void +static int aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device) { int default_depth = 3; @@ -7077,6 +7029,14 @@ aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device) tindex = device->id | (device->channel << 3); target_mask = (1 << tindex); + if (p->dev_max_queue_depth[tindex] > 1) + { + /* + * We've already scanned this device, leave it alone + */ + return(p->dev_max_queue_depth[tindex]); + } + device->queue_depth = default_depth; p->dev_temp_queue_depth[tindex] = 1; p->dev_max_queue_depth[tindex] = 1; @@ -7145,6 +7105,7 @@ aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device) } } } + return(p->dev_max_queue_depth[tindex]); } /*+F************************************************************************* @@ -7172,8 +7133,7 @@ aic7xxx_select_queue_depth(struct Scsi_Host *host, { if (device->host == host) { - aic7xxx_device_queue_depth(p, device); - scbnum += device->queue_depth; + scbnum += aic7xxx_device_queue_depth(p, device); } } while (scbnum > p->scb_data->numscbs) @@ -7481,7 +7441,6 @@ release_seeprom(struct aic7xxx_host *p) */ CLOCK_PULSE(p); aic_outb(p, 0, SEECTL); - CLOCK_PULSE(p); } /*+F************************************************************************* @@ -7757,8 +7716,6 @@ write_brdctl(struct aic7xxx_host *p, unsigned char value) } } -#undef CLOCK_PULSE - /*+F************************************************************************* * Function: * aic785x_cable_detect @@ -7773,16 +7730,64 @@ aic785x_cable_detect(struct aic7xxx_host *p, int *int_50, unsigned char brdctl; aic_outb(p, BRDRW | BRDCS, BRDCTL); - udelay(1); + CLOCK_PULSE(p); aic_outb(p, 0, BRDCTL); - udelay(1); + CLOCK_PULSE(p); brdctl = aic_inb(p, BRDCTL); - udelay(1); + CLOCK_PULSE(p); *int_50 = !(brdctl & BRDDAT5); *ext_present = !(brdctl & BRDDAT6); *eeprom = (aic_inb(p, SPIOCAP) & EEPROM); } +#undef CLOCK_PULSE + +/*+F************************************************************************* + * Function: + * aic2940_uwpro_cable_detect + * + * Description: + * Detect the cables that are present on the 2940-UWPro cards + * + * NOTE: This functions assumes the SEEPROM will have already been aquired + * prior to invocation of this function. + *-F*************************************************************************/ +static void +aic2940_uwpro_wide_cable_detect(struct aic7xxx_host *p, int *int_68, + int *ext_68, int *eeprom) +{ + unsigned char brdctl; + + /* + * First read the status of our cables. Set the rom bank to + * 0 since the bank setting serves as a multiplexor for the + * cable detection logic. BRDDAT5 controls the bank switch. + */ + write_brdctl(p, 0); + + /* + * Now we read the state of the internal 68 connector. BRDDAT6 + * is don't care, BRDDAT7 is internal 68. The cable is + * present if the bit is 0 + */ + brdctl = read_brdctl(p); + *int_68 = !(brdctl & BRDDAT7); + + /* + * Set the bank bit in brdctl and then read the external cable state + * and the EEPROM status + */ + write_brdctl(p, BRDDAT5); + brdctl = read_brdctl(p); + + *ext_68 = !(brdctl & BRDDAT6); + *eeprom = !(brdctl & BRDDAT7); + + /* + * We're done, the calling function will release the SEEPROM for us + */ +} + /*+F************************************************************************* * Function: * aic787x_cable_detect @@ -7887,59 +7892,182 @@ configure_termination(struct aic7xxx_host *p) max_target = 8; aic_outb(p, SEEMS | SEECS, SEECTL); sxfrctl1 &= ~STPWEN; - if ( (p->adapter_control & CFAUTOTERM) || - (p->features & AHC_NEW_AUTOTERM) ) + /* + * The termination/cable detection logic is split into three distinct + * groups. Ultra2 and later controllers, 2940UW-Pro controllers, and + * older 7850, 7860, 7870, 7880, and 7895 controllers. Each has its + * own unique way of detecting their cables and writing the results + * back to the card. + */ + if (p->features & AHC_ULTRA2) { - if ( (p->adapter_control & CFAUTOTERM) && - !(p->features & AHC_NEW_AUTOTERM) ) + /* + * As long as user hasn't overridden term settings, always check the + * cable detection logic + */ + if (aic7xxx_override_term == -1) { - printk(KERN_INFO "(scsi%d) Warning - detected auto-termination\n", - p->host_no); - printk(KERN_INFO "(scsi%d) Please verify driver detected settings are " - "correct.\n", p->host_no); - printk(KERN_INFO "(scsi%d) If not, then please properly set the device " - "termination\n", p->host_no); - printk(KERN_INFO "(scsi%d) in the Adaptec SCSI BIOS by hitting CTRL-A " - "when prompted\n", p->host_no); - printk(KERN_INFO "(scsi%d) during machine bootup.\n", p->host_no); + aic7xxx_ultra2_term_detect(p, &enableSE_low, &enableSE_high, + &enableLVD_low, &enableLVD_high, + &eprom_present); + } + + /* + * If the user is overriding settings, then they have been preserved + * to here as fake adapter_control entries. Parse them and allow + * them to override the detected settings (if we even did detection). + */ + if (!(p->adapter_control & CFSEAUTOTERM)) + { + enableSE_low = (p->adapter_control & CFSTERM); + enableSE_high = (p->adapter_control & CFWSTERM); + } + if (!(p->adapter_control & CFAUTOTERM)) + { + enableLVD_low = enableLVD_high = (p->adapter_control & CFLVDSTERM); } - /* Configure auto termination. */ - if (p->features & AHC_NEW_AUTOTERM) + /* + * Now take those settings that we have and translate them into the + * values that must be written into the registers. + * + * Flash Enable = BRDDAT7 + * Secondary High Term Enable = BRDDAT6 + * Secondary Low Term Enable = BRDDAT5 + * LVD/Primary High Term Enable = BRDDAT4 + * LVD/Primary Low Term Enable = STPWEN bit in SXFRCTL1 + */ + if (enableLVD_low != 0) { - if (aic7xxx_override_term == -1) - aic7xxx_ultra2_term_detect(p, &enableSE_low, &enableSE_high, - &enableLVD_low, &enableLVD_high, - &eprom_present); - if (!(p->adapter_control & CFSEAUTOTERM)) + sxfrctl1 |= STPWEN; + p->flags |= AHC_TERM_ENB_LVD; + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) LVD/Primary Low byte termination " + "Enabled\n", p->host_no); + } + + if (enableLVD_high != 0) + { + brddat |= BRDDAT4; + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) LVD/Primary High byte termination " + "Enabled\n", p->host_no); + } + + if (enableSE_low != 0) + { + brddat |= BRDDAT5; + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) Secondary Low byte termination " + "Enabled\n", p->host_no); + } + + if (enableSE_high != 0) + { + brddat |= BRDDAT6; + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) Secondary High byte termination " + "Enabled\n", p->host_no); + } + } + else if (p->features & AHC_NEW_AUTOTERM) + { + /* + * The 50 pin connector termination is controlled by STPWEN in the + * SXFRCTL1 register. Since the Adaptec docs typically say the + * controller is not allowed to be in the middle of a cable and + * this is the only connection on that stub of the bus, there is + * no need to even check for narrow termination, it's simply + * always on. + */ + sxfrctl1 |= STPWEN; + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) Narrow channel termination Enabled\n", + p->host_no); + + if (p->adapter_control & CFAUTOTERM) + { + aic2940_uwpro_wide_cable_detect(p, &internal68_present, + &external_present, + &eprom_present); + printk(KERN_INFO "(scsi%d) Cables present (Int-50 %s, Int-68 %s, " + "Ext-68 %s)\n", p->host_no, + "Don't Care", + internal68_present ? "YES" : "NO", + external_present ? "YES" : "NO"); + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) EEPROM %s present.\n", p->host_no, + eprom_present ? "is" : "is not"); + if (internal68_present && external_present) { - enableSE_low = (p->adapter_control & CFSTERM); - enableSE_high = (p->adapter_control & CFWSTERM); + brddat = 0; + p->flags &= ~AHC_TERM_ENB_SE_HIGH; + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) Wide channel termination Disabled\n", + p->host_no); } - if (!(p->adapter_control & CFAUTOTERM)) + else { - enableLVD_low = enableLVD_high = (p->adapter_control & CFLVDSTERM); + brddat = BRDDAT6; + p->flags |= AHC_TERM_ENB_SE_HIGH; + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) Wide channel termination Enabled\n", + p->host_no); } - internal50_present = 0; - internal68_present = 1; - external_present = 1; - } - else if ( (p->chip & AHC_CHIPID_MASK) >= AHC_AIC7870 ) - { - aic787x_cable_detect(p, &internal50_present, &internal68_present, - &external_present, &eprom_present); } else { - aic785x_cable_detect(p, &internal50_present, &external_present, - &eprom_present); + /* + * The termination of the Wide channel is done more like normal + * though, and the setting of this termination is done by writing + * either a 0 or 1 to BRDDAT6 of the BRDDAT register + */ + if (p->adapter_control & CFWSTERM) + { + brddat = BRDDAT6; + p->flags |= AHC_TERM_ENB_SE_HIGH; + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) Wide channel termination Enabled\n", + p->host_no); + } + else + { + brddat = 0; + } } - - if (max_target <= 8) - internal68_present = 0; - - if ( !(p->features & AHC_NEW_AUTOTERM) ) + } + else + { + if (p->adapter_control & CFAUTOTERM) { + if (p->flags & AHC_MOTHERBOARD) + { + printk(KERN_INFO "(scsi%d) Warning - detected auto-termination\n", + p->host_no); + printk(KERN_INFO "(scsi%d) Please verify driver detected settings " + "are correct.\n", p->host_no); + printk(KERN_INFO "(scsi%d) If not, then please properly set the " + "device termination\n", p->host_no); + printk(KERN_INFO "(scsi%d) in the Adaptec SCSI BIOS by hitting " + "CTRL-A when prompted\n", p->host_no); + printk(KERN_INFO "(scsi%d) during machine bootup.\n", p->host_no); + } + /* Configure auto termination. */ + + if ( (p->chip & AHC_CHIPID_MASK) >= AHC_AIC7870 ) + { + aic787x_cable_detect(p, &internal50_present, &internal68_present, + &external_present, &eprom_present); + } + else + { + aic785x_cable_detect(p, &internal50_present, &external_present, + &eprom_present); + } + + if (max_target <= 8) + internal68_present = 0; + if (max_target > 8) { printk(KERN_INFO "(scsi%d) Cables present (Int-50 %s, Int-68 %s, " @@ -7955,100 +8083,73 @@ configure_termination(struct aic7xxx_host *p) internal50_present ? "YES" : "NO", external_present ? "YES" : "NO"); } - } - if (aic7xxx_verbose & VERBOSE_PROBE2) - printk(KERN_INFO "(scsi%d) EEPROM %s present.\n", p->host_no, - eprom_present ? "is" : "is not"); + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) EEPROM %s present.\n", p->host_no, + eprom_present ? "is" : "is not"); - /* - * Now set the termination based on what we found. BRDDAT6 - * controls wide termination enable. - * Flash Enable = BRDDAT7 - * SE High Term Enable = BRDDAT6 - * SE Low Term Enable = BRDDAT5 (7890) - * LVD High Term Enable = BRDDAT4 (7890) - */ - if ( !(p->features & AHC_NEW_AUTOTERM) && - (internal50_present && internal68_present && external_present) ) - { - printk(KERN_INFO "(scsi%d) Illegal cable configuration!! Only two\n", - p->host_no); - printk(KERN_INFO "(scsi%d) connectors on the SCSI controller may be " - "in use at a time!\n", p->host_no); /* - * Force termination (low and high byte) on. This is safer than - * leaving it completely off, especially since this message comes - * most often from motherboard controllers that don't even have 3 - * connectors, but instead are failing the cable detection. + * Now set the termination based on what we found. BRDDAT6 + * controls wide termination enable. + * Flash Enable = BRDDAT7 + * SE High Term Enable = BRDDAT6 */ - internal50_present = external_present = 0; - enableSE_high = enableSE_low = 1; - } - - if ((max_target > 8) && - ((external_present == 0) || (internal68_present == 0) || - (enableSE_high != 0))) - { - brddat |= BRDDAT6; - p->flags |= AHC_TERM_ENB_SE_HIGH; - if (aic7xxx_verbose & VERBOSE_PROBE2) - printk(KERN_INFO "(scsi%d) SE High byte termination Enabled\n", + if (internal50_present && internal68_present && external_present) + { + printk(KERN_INFO "(scsi%d) Illegal cable configuration!! Only two\n", p->host_no); - } + printk(KERN_INFO "(scsi%d) connectors on the SCSI controller may be " + "in use at a time!\n", p->host_no); + /* + * Force termination (low and high byte) on. This is safer than + * leaving it completely off, especially since this message comes + * most often from motherboard controllers that don't even have 3 + * connectors, but instead are failing the cable detection. + */ + internal50_present = external_present = 0; + enableSE_high = enableSE_low = 1; + } - if ( (((internal50_present ? 1 : 0) + - (internal68_present ? 1 : 0) + - (external_present ? 1 : 0)) <= 1) || - (enableSE_low != 0) ) - { - if (p->features & AHC_NEW_AUTOTERM) - brddat |= BRDDAT5; - else - sxfrctl1 |= STPWEN; - p->flags |= AHC_TERM_ENB_SE_LOW; - if (aic7xxx_verbose & VERBOSE_PROBE2) - printk(KERN_INFO "(scsi%d) SE Low byte termination Enabled\n", - p->host_no); - } + if ((max_target > 8) && + ((external_present == 0) || (internal68_present == 0)) ) + { + brddat |= BRDDAT6; + p->flags |= AHC_TERM_ENB_SE_HIGH; + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) SE High byte termination Enabled\n", + p->host_no); + } - if (enableLVD_low != 0) - { - sxfrctl1 |= STPWEN; - p->flags |= AHC_TERM_ENB_LVD; - if (aic7xxx_verbose & VERBOSE_PROBE2) - printk(KERN_INFO "(scsi%d) LVD Low byte termination Enabled\n", - p->host_no); - } - - if (enableLVD_high != 0) - { - brddat |= BRDDAT4; - if (aic7xxx_verbose & VERBOSE_PROBE2) - printk(KERN_INFO "(scsi%d) LVD High byte termination Enabled\n", - p->host_no); + if ( ((internal50_present ? 1 : 0) + + (internal68_present ? 1 : 0) + + (external_present ? 1 : 0)) <= 1 ) + { + sxfrctl1 |= STPWEN; + p->flags |= AHC_TERM_ENB_SE_LOW; + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) SE Low byte termination Enabled\n", + p->host_no); + } } - } - else - { - if (p->adapter_control & CFSTERM) + else /* p->adapter_control & CFAUTOTERM */ { - if (p->features & AHC_NEW_AUTOTERM) - brddat |= BRDDAT5; - else + if (p->adapter_control & CFSTERM) + { sxfrctl1 |= STPWEN; - if (aic7xxx_verbose & VERBOSE_PROBE2) - printk(KERN_INFO "(scsi%d) SE Low byte termination Enabled\n", - p->host_no); - } + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) SE Low byte termination Enabled\n", + p->host_no); + } - if (p->adapter_control & CFWSTERM) - { - brddat |= BRDDAT6; - if (aic7xxx_verbose & VERBOSE_PROBE2) - printk(KERN_INFO "(scsi%d) SE High byte termination Enabled\n", - p->host_no); + if (p->adapter_control & CFWSTERM) + { + brddat |= BRDDAT6; + if (aic7xxx_verbose & VERBOSE_PROBE2) + printk(KERN_INFO "(scsi%d) SE High byte termination Enabled\n", + p->host_no); + } } } + aic_outb(p, sxfrctl1, SXFRCTL1); write_brdctl(p, brddat); release_seeprom(p); @@ -8236,23 +8337,8 @@ aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p, } aic_outb(p, 0, SEQ_FLAGS); - /* - * We are starting to do real work on the card....it's possible we could - * generate some spurious interrupts at this point, especially in the - * event of a PCI error or some such. If there are other devices already - * registered on the same interrupt as us, this could cause the machine - * to lock up. So, we disable the interrupt this card is on until we - * finish our card setup. We only need to do this for modules, if we are - * compiled into the kernel then interrupts are already off during this - * part of the code. - */ -#ifdef MODULE - disable_irq(p->irq); -#endif - detect_maxscb(p); - printk("%d/%d SCBs\n", p->scb_data->maxhscbs, p->scb_data->maxscbs); if (aic7xxx_verbose & VERBOSE_PROBE2) { @@ -8277,12 +8363,7 @@ aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p, { unsigned char devconfig; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) pci_read_config_byte(p->pdev, DEVCONFIG, &devconfig); -#else - pcibios_read_config_byte(p->pci_bus, p->pci_device_fn, - DEVCONFIG, &devconfig); -#endif if ( (aic7xxx_stpwlev >> p->instance) & 0x01 ) { devconfig |= STPWLEVEL; @@ -8295,12 +8376,7 @@ aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p, if (aic7xxx_verbose & VERBOSE_PROBE2) printk("(scsi%d) Force clearing STPWLEVEL bit\n", p->host_no); } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) pci_write_config_byte(p->pdev, DEVCONFIG, devconfig); -#else - pcibios_write_config_byte(p->pci_bus, p->pci_device_fn, - DEVCONFIG, devconfig); -#endif } } #endif @@ -8404,7 +8480,7 @@ aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p, * we won't have a power source for the SCSI termination, which means * we'll see infinite incoming bus resets. */ - if(p->flags & AHC_NO_STPWR) + if(p->flags & AHC_NO_STPWEN) aic_outb(p, ENSELTIMO | ENSCSIPERR, SIMODE1); else aic_outb(p, ENSELTIMO | ENSCSIRST | ENSCSIPERR, SIMODE1); @@ -8484,9 +8560,6 @@ aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p, printk("(scsi%d) Unable to allocate hardware SCB array; " "failing detection.\n", p->host_no); aic_outb(p, 0, SIMODE1); -#ifdef MODULE - enable_irq(p->irq); -#endif p->irq = 0; return(0); } @@ -8670,9 +8743,6 @@ aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p, printk(KERN_WARNING "(scsi%d) Couldn't register IRQ %d, ignoring " "controller.\n", p->host_no, p->irq); aic_outb(p, 0, SIMODE1); -#ifdef MODULE - enable_irq(p->irq); -#endif p->irq = 0; return (0); } @@ -8682,10 +8752,6 @@ aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p, p->host_no, -1, -1 , -1); aic7xxx_clear_intstat(p); -#ifdef MODULE - enable_irq(p->irq); -#endif - unpause_sequencer(p, /* unpause_always */ TRUE); return (found); @@ -8715,10 +8781,10 @@ aic7xxx_chip_reset(struct aic7xxx_host *p) * In the future, we may call this function as a last resort for * error handling. Let's be nice and not do any unecessary delays. */ - wait = 1000; /* 1 second (1000 * 1 msec) */ + wait = 1000; /* 1 msec (1000 * 1 msec) */ while (--wait && !(aic_inb(p, HCNTRL) & CHIPRSTACK)) { - udelay(1); /* 1 msec */ + udelay(1); /* 1 usec */ } pause_sequencer(p); @@ -8794,7 +8860,7 @@ aic7xxx_alloc(Scsi_Host_Template *sht, struct aic7xxx_host *temp) p->orderedtag = 0; for (i=0; i<MAX_TARGETS; i++) { - p->transinfo[i].goal_period = 0; + p->transinfo[i].goal_period = 255; p->transinfo[i].goal_offset = 0; p->transinfo[i].goal_options = 0; p->transinfo[i].goal_width = MSG_EXT_WDTR_BUS_8_BIT; @@ -9369,11 +9435,7 @@ aic7xxx_detect(Scsi_Host_Template *template) /* * PCI-bus probe. */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) if (pci_present()) -#else - if (pcibios_present()) -#endif { struct { @@ -9412,7 +9474,7 @@ aic7xxx_detect(Scsi_Host_Template *template) AHC_AIC7860_FE, 7, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7860, AHC_AIC7860, - AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED, + AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MOTHERBOARD, AHC_AIC7860_FE, 7, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7861, AHC_AIC7860, @@ -9420,7 +9482,8 @@ aic7xxx_detect(Scsi_Host_Template *template) AHC_AIC7860_FE, 8, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7870, AHC_AIC7870, - AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7870_FE, 9, + AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MOTHERBOARD, + AHC_AIC7870_FE, 9, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7871, AHC_AIC7870, AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7870_FE, 10, @@ -9437,7 +9500,8 @@ aic7xxx_detect(Scsi_Host_Template *template) AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7870_FE, 13, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7880, AHC_AIC7880, - AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 14, + AHC_PAGESCBS | AHC_BIOS_ENABLED | AHC_MOTHERBOARD, + AHC_AIC7880_FE, 14, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7881, AHC_AIC7880, AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 15, @@ -9460,106 +9524,93 @@ aic7xxx_detect(Scsi_Host_Template *template) AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7887, AHC_AIC7880, - AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE | AHC_NEW_AUTOTERM, 18, + AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE | AHC_NEW_AUTOTERM, 19, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7888, AHC_AIC7880, AHC_PAGESCBS | AHC_BIOS_ENABLED, AHC_AIC7880_FE, 18, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7895, AHC_AIC7895, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL, - AHC_AIC7895_FE, 19, + AHC_AIC7895_FE, 20, 32, C56_66 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7890, AHC_AIC7890, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED, - AHC_AIC7890_FE, 20, + AHC_AIC7890_FE, 21, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7890B, AHC_AIC7890, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED, - AHC_AIC7890_FE, 20, + AHC_AIC7890_FE, 21, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_2930U2, AHC_AIC7890, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED, - AHC_AIC7890_FE, 21, + AHC_AIC7890_FE, 22, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_2940U2, AHC_AIC7890, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED, - AHC_AIC7890_FE, 22, + AHC_AIC7890_FE, 23, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7896, AHC_AIC7896, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL, - AHC_AIC7896_FE, 23, + AHC_AIC7896_FE, 24, 32, C56_66 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_3940U2, AHC_AIC7896, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL, - AHC_AIC7896_FE, 24, + AHC_AIC7896_FE, 25, 32, C56_66 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_3950U2D, AHC_AIC7896, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL, - AHC_AIC7896_FE, 25, + AHC_AIC7896_FE, 26, 32, C56_66 }, {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_1480A, AHC_AIC7860, - AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_NO_STPWR, - AHC_AIC7860_FE, 26, + AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_NO_STPWEN, + AHC_AIC7860_FE, 27, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892A, AHC_AIC7892, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED, - AHC_AIC7892_FE, 27, + AHC_AIC7892_FE, 28, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892B, AHC_AIC7892, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED, - AHC_AIC7892_FE, 27, + AHC_AIC7892_FE, 28, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892D, AHC_AIC7892, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED, - AHC_AIC7892_FE, 27, + AHC_AIC7892_FE, 28, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7892P, AHC_AIC7892, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED, - AHC_AIC7892_FE, 27, + AHC_AIC7892_FE, 28, 32, C46 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899A, AHC_AIC7899, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL, - AHC_AIC7899_FE, 28, + AHC_AIC7899_FE, 29, 32, C56_66 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899B, AHC_AIC7899, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL, - AHC_AIC7899_FE, 28, + AHC_AIC7899_FE, 29, 32, C56_66 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899D, AHC_AIC7899, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL, - AHC_AIC7899_FE, 28, + AHC_AIC7899_FE, 29, 32, C56_66 }, {PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_7899P, AHC_AIC7899, AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED | AHC_MULTI_CHANNEL, - AHC_AIC7899_FE, 28, + AHC_AIC7899_FE, 29, 32, C56_66 }, }; unsigned short command; unsigned int devconfig, i, oldverbose; -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) struct pci_dev *pdev = NULL; -#else - int index; - unsigned int piobase, mmapbase; - unsigned char pci_bus, pci_devfn, pci_irq; -#endif for (i = 0; i < NUMBER(aic_pdevs); i++) { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) pdev = NULL; while ((pdev = pci_find_device(aic_pdevs[i].vendor_id, aic_pdevs[i].device_id, pdev))) { if (pci_enable_device(pdev)) continue; -#else - index = 0; - while (!(pcibios_find_device(aic_pdevs[i].vendor_id, - aic_pdevs[i].device_id, - index++, &pci_bus, &pci_devfn)) ) { -#endif if ( i == 0 ) /* We found one, but it's the 7810 RAID cont. */ { if (aic7xxx_verbose & (VERBOSE_PROBE|VERBOSE_PROBE2)) @@ -9583,7 +9634,6 @@ aic7xxx_detect(Scsi_Host_Template *template) /* * Read sundry information from PCI BIOS. */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) temp_p->irq = pdev->irq; temp_p->pdev = pdev; temp_p->pci_bus = pdev->bus->number; @@ -9595,7 +9645,8 @@ aic7xxx_detect(Scsi_Host_Template *template) { if ( ((current_p->pci_bus == temp_p->pci_bus) && (current_p->pci_device_fn == temp_p->pci_device_fn)) || - (current_p->base == temp_p->base) ) + (temp_p->base && (current_p->base == temp_p->base)) || + (temp_p->mbase && (current_p->mbase == temp_p->mbase)) ) { /* duplicate PCI entry, skip it */ kfree(temp_p); @@ -9635,69 +9686,8 @@ aic7xxx_detect(Scsi_Host_Template *template) devconfig |= 0x80000040; pci_write_config_dword(pdev, DEVCONFIG, devconfig); #endif /* AIC7XXX_STRICT_PCI_SETUP */ -#else /* LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) */ - temp_p->pci_bus = pci_bus; - temp_p->pci_device_fn = pci_devfn; - pcibios_read_config_byte(pci_bus, pci_devfn, PCI_INTERRUPT_LINE, - &pci_irq); - temp_p->irq = pci_irq; - pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_0, - &piobase); - temp_p->base = piobase; - pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_1, - &mmapbase); - temp_p->mbase = mmapbase; - temp_p->base &= PCI_BASE_ADDRESS_IO_MASK; - temp_p->mbase &= PCI_BASE_ADDRESS_MEM_MASK; - current_p = list_p; - while(current_p) - { - if ( ((current_p->pci_bus == temp_p->pci_bus) && - (current_p->pci_device_fn == temp_p->pci_device_fn)) || - (current_p->base == temp_p->base) ) - { - /* duplicate PCI entry, skip it */ - kfree(temp_p); - temp_p = NULL; - } - current_p = current_p->next; - } - if ( temp_p == NULL ) - continue; - if (aic7xxx_verbose & VERBOSE_PROBE2) - printk("aic7xxx: <%s> at PCI %d/%d/%d\n", - board_names[aic_pdevs[i].board_name_index], - temp_p->pci_bus, - PCI_SLOT(temp_p->pci_device_fn), - PCI_FUNC(temp_p->pci_device_fn)); - pcibios_read_config_word(pci_bus, pci_devfn, PCI_COMMAND, &command); - if (aic7xxx_verbose & VERBOSE_PROBE2) - { - printk("aic7xxx: Initial PCI_COMMAND value was 0x%x\n", - (int)command); - } -#ifdef AIC7XXX_STRICT_PCI_SETUP - command |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | - PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; -#else - command |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; -#endif - command &= ~PCI_COMMAND_INVALIDATE; - if (aic7xxx_pci_parity == 0) - command &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY); - pcibios_write_config_word(pci_bus, pci_devfn, PCI_COMMAND, command); -#ifdef AIC7XXX_STRICT_PCI_SETUP - pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG, &devconfig); - if (aic7xxx_verbose & VERBOSE_PROBE2) - { - printk("aic7xxx: Initial DEVCONFIG value was 0x%x\n", devconfig); - } - devconfig |= 0x80000040; - pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG, devconfig); -#endif /* AIC7XXX_STRICT_PCI_SETUP */ -#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) */ - if(check_region(temp_p->base, MAXREG - MINREG)) + if(temp_p->base && check_region(temp_p->base, MAXREG - MINREG)) { printk("aic7xxx: <%s> at PCI %d/%d/%d\n", board_names[aic_pdevs[i].board_name_index], @@ -9728,7 +9718,7 @@ aic7xxx_detect(Scsi_Host_Template *template) } #ifdef MMAPIO - if ( !(temp_p->flags & AHC_MULTI_CHANNEL) || + if ( !(temp_p->base) || !(temp_p->flags & AHC_MULTI_CHANNEL) || ((temp_p->chip != (AHC_AIC7870 | AHC_PCI)) && (temp_p->chip != (AHC_AIC7880 | AHC_PCI))) ) { @@ -9736,11 +9726,7 @@ aic7xxx_detect(Scsi_Host_Template *template) base = temp_p->mbase & PAGE_MASK; page_offset = temp_p->mbase - base; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) temp_p->maddr = ioremap_nocache(base, page_offset + 256); -#else - temp_p->maddr = vremap(base, page_offset + 256); -#endif if(temp_p->maddr) { temp_p->maddr += page_offset; @@ -9760,12 +9746,20 @@ aic7xxx_detect(Scsi_Host_Template *template) PCI_FUNC(temp_p->pci_device_fn)); printk(KERN_INFO "aic7xxx: MMAPed I/O failed, reverting to " "Programmed I/O.\n"); -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) iounmap((void *) (((unsigned long) temp_p->maddr) & PAGE_MASK)); -#else - vfree((void *) (((unsigned long) temp_p->maddr) & PAGE_MASK)); -#endif temp_p->maddr = 0; + if(temp_p->base == 0) + { + printk("aic7xxx: <%s> at PCI %d/%d/%d\n", + board_names[aic_pdevs[i].board_name_index], + temp_p->pci_bus, + PCI_SLOT(temp_p->pci_device_fn), + PCI_FUNC(temp_p->pci_device_fn)); + printk("aic7xxx: Controller disabled by BIOS, ignoring.\n"); + kfree(temp_p); + temp_p = NULL; + continue; + } } } } @@ -9774,7 +9768,8 @@ aic7xxx_detect(Scsi_Host_Template *template) /* * Lock out other contenders for our i/o space. */ - request_region(temp_p->base, MAXREG - MINREG, "aic7xxx"); + if(temp_p->base) + request_region(temp_p->base, MAXREG - MINREG, "aic7xxx"); /* * We HAVE to make sure the first pause_sequencer() and all other @@ -9826,12 +9821,7 @@ aic7xxx_detect(Scsi_Host_Template *template) * bit of DEVCONFIG */ aic_outb(temp_p, sxfrctl1, SXFRCTL1); -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) - pcibios_write_config_dword(temp_p->pci_bus, temp_p->pci_device_fn, - DEVCONFIG, devconfig); -#else pci_write_config_dword(temp_p->pdev, DEVCONFIG, devconfig); -#endif sxfrctl1 &= STPWEN; /* @@ -9866,7 +9856,6 @@ aic7xxx_detect(Scsi_Host_Template *template) case AHC_AIC7895: /* 7895 */ case AHC_AIC7896: /* 7896/7 */ case AHC_AIC7899: /* 7899 */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) if (PCI_FUNC(pdev->devfn) != 0) { temp_p->flags |= AHC_CHNLB; @@ -9882,25 +9871,6 @@ aic7xxx_detect(Scsi_Host_Template *template) devconfig |= SCBSIZE32; pci_write_config_dword(pdev, DEVCONFIG, devconfig); } -#else - if (PCI_FUNC(temp_p->pci_device_fn) != 0) - { - temp_p->flags |= AHC_CHNLB; - } - /* - * The 7895 is the only chipset that sets the SCBSIZE32 param - * in the DEVCONFIG register. The Ultra2 chipsets use - * the DSCOMMAND0 register instead. - */ - if ((temp_p->chip & AHC_CHIPID_MASK) == AHC_AIC7895) - { - pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG, - &devconfig); - devconfig |= SCBSIZE32; - pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG, - devconfig); - } -#endif break; default: break; @@ -9965,12 +9935,7 @@ aic7xxx_detect(Scsi_Host_Template *template) /* * Check the rev of the chipset before we change DSCOMMAND0 */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) pci_read_config_dword(pdev, DEVCONFIG, &devconfig); -#else - pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG, - &devconfig); -#endif if ((devconfig & 0xff) >= 1) { aic_outb(temp_p, (aic_inb(temp_p, DSCOMMAND0) | @@ -10040,12 +10005,7 @@ aic7xxx_detect(Scsi_Host_Template *template) case AHC_AIC7895: case AHC_AIC7896: case AHC_AIC7899: -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) pci_read_config_dword(pdev, DEVCONFIG, &devconfig); -#else - pcibios_read_config_dword(pci_bus, pci_devfn, DEVCONFIG, - &devconfig); -#endif if (temp_p->features & AHC_ULTRA2) { if ( (aic_inb(temp_p, DSCOMMAND0) & RAMPSM_ULTRA2) && @@ -10087,12 +10047,7 @@ aic7xxx_detect(Scsi_Host_Template *template) "but not enabled\n"); } } -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) pci_write_config_dword(pdev, DEVCONFIG, devconfig); -#else - pcibios_write_config_dword(pci_bus, pci_devfn, DEVCONFIG, - devconfig); -#endif if ( (temp_p->flags & AHC_EXTERNAL_SRAM) && (temp_p->flags & AHC_CHNLB) ) aic_outb(temp_p, 1, CCSCBBADDR); @@ -10687,20 +10642,59 @@ aic7xxx_negotiation_complete(Scsi_Cmnd *cmd) (!(p->features & AHC_ULTRA2) || (syncrate->sxfr_ultra2 == 0)) ) { p->transinfo[tindex].goal_period = syncrate->period; - if( !(syncrate->sxfr_ultra2 & 0x40) ) + if( p->transinfo[tindex].goal_period > 9 ) { p->transinfo[tindex].goal_options = 0; + p->needppr &= ~(1<<tindex); + p->needsdtr |= (1<<tindex); + p->needppr_copy &= ~(1<<tindex); + p->needsdtr_copy |= (1<<tindex); + if (p->transinfo[tindex].goal_width) + { + p->needwdtr |= (1<<tindex); + p->needwdtr_copy |= (1<<tindex); + } + } + } + else if (p->transinfo[tindex].goal_width) + { + p->transinfo[tindex].goal_width = 0; + p->needwdtr &= ~(1<<tindex); + p->needwdtr_copy &= ~(1<<tindex); + p->transinfo[tindex].goal_offset = + p->transinfo[tindex].user_offset; + p->transinfo[tindex].goal_period = + p->transinfo[tindex].user_period; + p->transinfo[tindex].goal_options = + p->transinfo[tindex].user_options; + if( p->transinfo[tindex].goal_period <= 9 ) + { + p->needppr |= (1<<tindex); + p->needsdtr &= ~(1<<tindex); + p->needppr_copy |= (1<<tindex); + p->needsdtr_copy &= ~(1<<tindex); + } + else + { + p->needppr &= ~(1<<tindex); + p->needsdtr |= (1<<tindex); + p->needppr_copy &= ~(1<<tindex); + p->needsdtr_copy |= (1<<tindex); } } else { p->transinfo[tindex].goal_offset = 0; - p->transinfo[tindex].goal_period = 0; + p->transinfo[tindex].goal_period = 255; p->transinfo[tindex].goal_options = 0; + p->transinfo[tindex].goal_width = 0; + p->needppr &= ~(1<<tindex); + p->needsdtr &= ~(1<<tindex); + p->needwdtr &= ~(1<<tindex); + p->needppr_copy &= ~(1<<tindex); + p->needsdtr_copy &= ~(1<<tindex); + p->needwdtr_copy &= ~(1<<tindex); } - p->needppr |= (p->needppr_copy & (1<<tindex)); - p->needsdtr |= (p->needsdtr_copy & (1<<tindex)); - p->needwdtr |= (p->needwdtr_copy & (1<<tindex)); } p->needdv &= ~(1<<tindex); } @@ -10751,8 +10745,16 @@ aic7xxx_negotiation_complete(Scsi_Cmnd *cmd) * and we didn't follow up with SDTR yet, then this will get it started. * For all other cases, this should work out to be a no-op, unless we are * doing domain validation and happen to need a new negotiation command. + * + * In case we don't want this to go any further, the cmdcmplt interrupt + * handler will NULL out the cmd->next entry so that the real SCSI command + * can be sent back to the mid layer code with SENSE data intact. We'll + * finish things up when the cmd gets sent back down to us, so no worries. */ - aic7xxx_build_negotiation_cmnd(p, cmd->next, tindex); + if(cmd->next) + { + aic7xxx_build_negotiation_cmnd(p, cmd->next, tindex); + } return; } @@ -10874,13 +10876,13 @@ aic7xxx_buildscb(struct aic7xxx_host *p, Scsi_Cmnd *cmd, */ hscb->control = 0; scb->tag_action = 0; + cmd->tag = hscb->tag; if (p->discenable & mask) { hscb->control |= DISCENB; if ( (p->tagenable & mask) && (cmd->cmnd[0] != TEST_UNIT_READY) ) { - cmd->tag = hscb->tag; p->dev_commands_sent[tindex]++; if (p->dev_commands_sent[tindex] < 200) { @@ -11322,13 +11324,6 @@ aic7xxx_bus_device_reset(struct aic7xxx_host *p, Scsi_Cmnd *cmd) void aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) - int i, mask, found, need_tag; - struct aic7xxx_scb *scb; - unsigned char qinpos, hscbp; - - found = FALSE; -#endif printk("aic7xxx driver version %s/%s\n", AIC7XXX_C_VERSION, UTS_RELEASE); @@ -11341,121 +11336,7 @@ aic7xxx_panic_abort(struct aic7xxx_host *p, Scsi_Cmnd *cmd) disable_irq(p->irq); aic7xxx_print_card(p); aic7xxx_print_scratch_ram(p); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) - for(i=0; i<MAX_TARGETS; i++) - { - if(p->dev_flags[i] & DEVICE_PRESENT) - { - mask = (0x01 << i); - printk(INFO_LEAD "dev_flags=0x%x, Pending:%c, PPR:%c/%c, WDTR:%c/%c, " - "SDTR:%c/%c, q_depth=%d:%d\n", - p->host_no, 0, i, 0, p->dev_flags[i], - (p->dtr_pending & mask) ? 'Y' : 'N', - (p->needppr & mask) ? 'Y' : 'N', - (p->needppr_copy & mask) ? 'Y' : 'N', - (p->needwdtr & mask) ? 'Y' : 'N', - (p->needwdtr_copy & mask) ? 'Y' : 'N', - (p->needsdtr & mask) ? 'Y' : 'N', - (p->needsdtr_copy & mask) ? 'Y' : 'N', - p->dev_active_cmds[i], - p->dev_max_queue_depth[i] ); - printk(INFO_LEAD "targ_scsirate=0x%x", p->host_no, 0, i, 0, - aic_inb(p, TARG_SCSIRATE + i)); - if (p->features & AHC_ULTRA2) - printk(", targ_offset=%d", aic_inb(p, TARG_OFFSET + i)); - printk("\n"); - } - } - /* - * Search for this command and see if we can't track it down, it's the - * one causing the timeout. Print out this command first, then all other - * active commands afterwords. - */ - need_tag = -1; - if ( cmd ) - { - scb = p->scb_data->scb_array[aic7xxx_position(cmd)]; - if ( (scb->flags & SCB_ACTIVE) && (scb->cmd == cmd) ) - { - printk("Timed out command is scb #%d:\n", scb->hscb->tag); - printk("Tag%d: flags=0x%x, control=0x%x, TCL=0x%x, %s\n", scb->hscb->tag, - scb->flags, scb->hscb->control, scb->hscb->target_channel_lun, - (scb->flags & SCB_WAITINGQ) ? "WAITINGQ" : "Sent" ); - need_tag = scb->hscb->tag; - if (scb->flags & SCB_WAITINGQ) found=TRUE; - } - } - printk("QINFIFO: (TAG) "); - qinpos = aic_inb(p, QINPOS); - while ( qinpos != p->qinfifonext ) - { - if (p->qinfifo[qinpos] == need_tag) - found=TRUE; - printk("%d ", p->qinfifo[qinpos++]); - } - printk("\n"); - printk("Current SCB: (SCBPTR/TAG/CONTROL) %d/%d/0x%x\n", aic_inb(p, SCBPTR), - aic_inb(p, SCB_TAG), aic_inb(p, SCB_CONTROL) ); - if (aic_inb(p, SCB_TAG) == need_tag) found=TRUE; - printk("WAITING_SCBS: (SCBPTR/TAG/CONTROL) %d->", - hscbp = aic_inb(p, WAITING_SCBH)); - while (hscbp != SCB_LIST_NULL) - { - aic_outb(p, hscbp, SCBPTR); - printk("%d/%d/0x%x ", hscbp, aic_inb(p, SCB_TAG), aic_inb(p, SCB_CONTROL)); - hscbp = aic_inb(p, SCB_NEXT); - if (aic_inb(p, SCB_TAG) == need_tag) found=TRUE; - } - printk("\n"); - printk("DISCONNECTED_SCBS: (SCBPTR/TAG/CONTROL) %d->", - hscbp = aic_inb(p, DISCONNECTED_SCBH)); - while (hscbp != SCB_LIST_NULL) - { - aic_outb(p, hscbp, SCBPTR); - printk("%d/%d/0x%x ", hscbp, aic_inb(p, SCB_TAG), aic_inb(p, SCB_CONTROL)); - hscbp = aic_inb(p, SCB_NEXT); - if (aic_inb(p, SCB_TAG) == need_tag) found=TRUE; - } - printk("\n"); - printk("FREE_SCBS: (SCBPTR/TAG/CONTROL) %d->", - hscbp = aic_inb(p, FREE_SCBH)); - while (hscbp != SCB_LIST_NULL) - { - aic_outb(p, hscbp, SCBPTR); - printk("%d/%d/0x%x ", hscbp, aic_inb(p, SCB_TAG), aic_inb(p, SCB_CONTROL)); - hscbp = aic_inb(p, SCB_NEXT); - } - printk("\n"); - - if (found == FALSE) - { - /* - * We haven't found the offending SCB yet, and it should be around - * somewhere, so go look for it in the cards SCBs. - */ - printk("SCBPTR CONTROL TAG NEXT\n"); - for(i=0; i<p->scb_data->maxhscbs; i++) - { - aic_outb(p, i, SCBPTR); - printk(" %3d %02x %02x %02x\n", i, - aic_inb(p, SCB_CONTROL), aic_inb(p, SCB_TAG), - aic_inb(p, SCB_NEXT)); - } - } - - - for (i=0; i < p->scb_data->numscbs; i++) - { - scb = p->scb_data->scb_array[i]; - if ( (scb->flags & SCB_ACTIVE) && (scb->cmd != cmd) ) - { - printk("Tag%d: flags=0x%x, control=0x%x, TCL=0x%x, %s\n", scb->hscb->tag, - scb->flags, scb->hscb->control, scb->hscb->target_channel_lun, - (scb->flags & SCB_WAITINGQ) ? "WAITINGQ" : "Sent" ); - } - } -#endif - sti(); + spin_unlock_irq(&io_request_lock); for(;;) barrier(); } @@ -11501,7 +11382,6 @@ aic7xxx_abort(Scsi_Cmnd *cmd) * we are following a straight code path without entering the scheduler * code. */ - pause_sequencer(p); while ( (aic_inb(p, INTSTAT) & INT_PEND) && !(p->flags & AHC_IN_ISR)) { @@ -12164,15 +12044,12 @@ aic7xxx_release(struct Scsi_Host *host) if(p->irq) free_irq(p->irq, p); - release_region(p->base, MAXREG - MINREG); + if(p->base) + release_region(p->base, MAXREG - MINREG); #ifdef MMAPIO if(p->maddr) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) - vfree((void *) (((unsigned long) p->maddr) & PAGE_MASK)); -#else iounmap((void *) (((unsigned long) p->maddr) & PAGE_MASK)); -#endif } #endif /* MMAPIO */ prev = NULL; @@ -12243,31 +12120,7 @@ aic7xxx_print_card(struct aic7xxx_host *p) 0x84, 0x8e, 0x90, 0x95, 0x97, 0x97, 0x9a, 0x9a, 0x9c, 0x9f, 0xe0, 0xf1, 0xf4, 0xfc} }, }; -#ifdef CONFIG_PCI - static struct register_ranges cards_ns[] = { - { 0, {0,} }, /* none */ - { 0, {0,} }, /* 7771 */ - { 7, {0x04, 0x08, 0x0c, 0x0e, 0x10, 0x17, 0x28, 0x2b, 0x30, 0x33, - 0x3c, 0x41, 0x43, 0x47} }, - { 7, {0x04, 0x08, 0x0c, 0x0e, 0x10, 0x17, 0x28, 0x2b, 0x30, 0x33, - 0x3c, 0x41, 0x43, 0x47} }, - { 5, {0x04, 0x08, 0x0c, 0x0e, 0x10, 0x17, 0x30, 0x33, 0x3c, 0x41} }, - { 5, {0x04, 0x08, 0x0c, 0x0e, 0x10, 0x17, 0x30, 0x34, 0x3c, 0x47} }, - { 5, {0x04, 0x08, 0x0c, 0x1b, 0x30, 0x34, 0x3c, 0x43, 0xdc, 0xe3} }, - { 6, {0x04, 0x08, 0x0c, 0x0e, 0x10, 0x17, 0x30, 0x34, 0x3c, 0x47, - 0xdc, 0xe3} }, - { 6, {0x04, 0x08, 0x0c, 0x1b, 0x30, 0x34, 0x3c, 0x43, 0xdc, 0xe3, - 0xff, 0xff} }, - { 6, {0x04, 0x08, 0x0c, 0x1b, 0x30, 0x34, 0x3c, 0x43, 0xdc, 0xe3, - 0xff, 0xff} }, - { 6, {0x04, 0x08, 0x0c, 0x1b, 0x30, 0x34, 0x3c, 0x43, 0xdc, 0xe3, - 0xff, 0xff} } - }; -#endif chip = p->chip & AHC_CHIPID_MASK; - /* - * Let's run through the PCI space first.... - */ printk("%s at ", board_names[p->board_name_index]); switch(p->chip & ~AHC_CHIPID_MASK) @@ -12285,38 +12138,8 @@ aic7xxx_print_card(struct aic7xxx_host *p) break; } -#ifdef CONFIG_PCI - { - unsigned char temp; - - printk("PCI Dump:\n"); - k=0; - for(i=0; i<cards_ns[chip].num_ranges; i++) - { - for(j = cards_ns[chip].range_val[ i * 2 ]; - j <= cards_ns[chip].range_val[ i * 2 + 1 ] ; - j++) - { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,92) - pci_read_config_byte(p->pdev, j, &temp); -#else - pcibios_read_config_byte(p->pci_bus, p->pci_device_fn, j, &temp); -#endif - printk("%02x:%02x ", j, temp); - if(++k == 13) - { - printk("\n"); - k = 0; - } - } - } - } - if(k != 0) - printk("\n"); -#endif /* CONFIG_PCI */ - /* - * Now the registers on the card.... + * the registers on the card.... */ printk("Card Dump:\n"); k = 0; @@ -12336,21 +12159,6 @@ aic7xxx_print_card(struct aic7xxx_host *p) } if(k != 0) printk("\n"); - if (p->flags & AHC_SEEPROM_FOUND) - { - unsigned short *sc1; - sc1 = (unsigned short *)&p->sc; - - printk("SEEPROM dump.\n"); - for(i=1; i<=32; i++) - { - printk("0x%04x", sc1[i-1]); - if ( (i % 8) == 0 ) - printk("\n"); - else - printk(" "); - } - } /* * If this was an Ultra2 controller, then we just hosed the card in terms diff --git a/drivers/scsi/aic7xxx.h b/drivers/scsi/aic7xxx.h index ffcedd96d..de438cac7 100644 --- a/drivers/scsi/aic7xxx.h +++ b/drivers/scsi/aic7xxx.h @@ -23,21 +23,7 @@ #ifndef _aic7xxx_h #define _aic7xxx_h -#define AIC7XXX_H_VERSION "3.2.4" - -#ifndef LINUX_VERSION_CODE -#include <linux/version.h> -#endif - -#ifndef KERNEL_VERSION -#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) -#endif - -#if defined(__i386__) -# define AIC7XXX_BIOSPARAM aic7xxx_biosparam -#else -# define AIC7XXX_BIOSPARAM NULL -#endif +#define AIC7XXX_H_VERSION "5.2.0" /* * Scsi_Host_Template (see hosts.h) for AIC-7xxx - some fields @@ -61,7 +47,7 @@ abort: aic7xxx_abort, \ reset: aic7xxx_reset, \ slave_attach: NULL, \ - bios_param: AIC7XXX_BIOSPARAM, \ + bios_param: aic7xxx_biosparam, \ can_queue: 255, /* max simultaneous cmds */\ this_id: -1, /* scsi id of host adapter */\ sg_tablesize: 0, /* max scatter-gather cmds */\ diff --git a/drivers/scsi/aic7xxx/aic7xxx.seq b/drivers/scsi/aic7xxx/aic7xxx.seq index de3afbf92..15c887167 100644 --- a/drivers/scsi/aic7xxx/aic7xxx.seq +++ b/drivers/scsi/aic7xxx/aic7xxx.seq @@ -60,11 +60,7 @@ reset: clr SCSISIGO; /* De-assert BSY */ and SXFRCTL1, ~BITBUCKET; /* Always allow reselection */ - if ((p->flags & AHC_TARGETMODE) != 0) { - mvi SCSISEQ, ENSELI|ENRSELI|ENAUTOATNP; - } else { - mvi SCSISEQ, ENRSELI|ENAUTOATNP; - } + mvi SCSISEQ, ENRSELI|ENAUTOATNP; if ((p->features & AHC_CMD_CHAN) != 0) { /* Ensure that no DMA operations are in progress */ @@ -182,6 +178,15 @@ initialize_scsiid: and SCSIID, OID; /* Clear old target */ or SCSIID, A; } + mov SCSIDATL, ALLZEROS; /* clear out the latched */ + /* data register, this */ + /* fixes a bug on some */ + /* controllers where the */ + /* last byte written to */ + /* this register can leak */ + /* onto the data bus at */ + /* bad times, such as during */ + /* selection timeouts */ mvi SCSISEQ, ENSELO|ENAUTOATNO|ENRSELI|ENAUTOATNP ret; /* @@ -227,118 +232,6 @@ ndx_dtr_2: selection: test SSTAT0,SELDO jnz select_out; -select_in: - if ((p->flags & AHC_TARGETMODE) != 0) { - test SSTAT0, TARGET jz initiator_reselect; - /* - * We've just been selected. Assert BSY and - * setup the phase for receiving the messages - * from the target. - */ - mvi SCSISIGO, P_MESGOUT|BSYO; - mvi CLRSINT0, CLRSELDO; - - /* - * If ATN isn't asserted, go directly to bus free. - */ - test SCSISIGI, ATNI jz target_busfree; - - /* - * Setup the DMA for sending the identify and - * command information. - */ - mov A, TMODE_CMDADDR_NEXT; - mvi DINDEX, HADDR; - mvi TMODE_CMDADDR call set_32byte_addr; - mvi DFCNTRL, FIFORESET; - - clr SINDEX; - /* Watch ATN closely now */ -message_loop: - or SXFRCTL0, SPIOEN; - test SSTAT0, SPIORDY jz .; - and SXFRCTL0, ~SPIOEN; - mov DINDEX, SCSIDATL; - mov DFDAT, DINDEX; - inc SINDEX; - - /* Message Testing... */ - test DINDEX, MSG_IDENTIFYFLAG jz . + 2; - mov ARG_1, DINDEX; - - test SCSISIGI, ATNI jnz message_loop; - add A, -4, SINDEX; - jc target_cmdphase; - mvi DFDAT, SCB_LIST_NULL; /* Terminate the message list */ - -target_cmdphase: - add HCNT[0], 1, A; - clr HCNT[1]; - clr HCNT[2]; - mvi SCSISIGO, P_COMMAND|BSYO; - or SXFRCTL0, SPIOEN; - test SSTAT0, SPIORDY jz .; - mov A, SCSIDATL; - mov DFDAT, A; /* Store for host */ - - /* - * Determine the number of bytes to read - * based on the command group code. Count is - * one less than the total since we've already - * fetched the first byte. - */ - clr SINDEX; - shr A, CMD_GROUP_CODE_SHIFT; - add SEQADDR0, A; - - add SINDEX, CMD_GROUP0_BYTE_DELTA; - nop; /* Group 1 and 2 are the same */ - add SINDEX, CMD_GROUP2_BYTE_DELTA; - nop; /* Group 3 is reserved */ - add SINDEX, CMD_GROUP4_BYTE_DELTA; - add SINDEX, CMD_GROUP5_BYTE_DELTA; - /* Group 6 and 7 are not handled yet */ - - mov A, SINDEX; - add HCNT[0], A; - -command_loop: - test SSTAT0, SPIORDY jz .; - cmp SINDEX, 1 jne . + 2; - and SXFRCTL0, ~SPIOEN; /* Last Byte */ - mov DFDAT, SCSIDATL; - dec SINDEX; - test SINDEX, 0xFF jnz command_loop; - - or DFCNTRL, HDMAEN|FIFOFLUSH; - - call dma_finish; - - test ARG_1, MSG_IDENTIFY_DISCFLAG jz selectin_post; - - mvi SCSISIGO, P_MESGIN|BSYO; - - or SXFRCTL0, SPIOEN; - - mvi MSG_DISCONNECT call target_outb; - -selectin_post: - inc TMODE_CMDADDR_NEXT; - cmp TMODE_CMDADDR_NEXT, TMODE_NUMCMDS jne . + 2; - clr TMODE_CMDADDR_NEXT; - mvi QOUTFIFO, SCB_LIST_NULL; - mvi INTSTAT,CMDCMPLT; - - test ARG_1, MSG_IDENTIFY_DISCFLAG jnz target_busfree; - - /* Busy loop on something then go to data or status phase */ - -target_busfree: - clr SCSISIGO; - jmp poll_for_work; - - } - /* * Reselection has been initiated by a target. Make a note that we've been * reselected, but haven't seen an IDENTIFY message from the target yet. @@ -444,13 +337,14 @@ clear_target_state: * STCNT may have been cleared, so restore it from the residual field. */ data_phase_reinit: - if ((p->features & AHC_CMD_CHAN) != 0) { - if ((p->features & AHC_ULTRA2) != 0) { - bmov HADDR, SHADDR, 4; - bmov HCNT, SCB_RESID_DCNT, 3; - } + if ((p->features & AHC_ULTRA2) != 0) { + bmov HADDR, SHADDR, 4; + bmov HCNT, SCB_RESID_DCNT, 3; + } + if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { bmov STCNT, SCB_RESID_DCNT, 3; - } else { + } + if ((p->features & AHC_CMD_CHAN) == 0) { mvi DINDEX, STCNT; mvi SCB_RESID_DCNT call bcopy_3; } @@ -677,10 +571,13 @@ ultra2_dmafifoflush: test DFSTATUS, FIFOEMP jz ultra2_dmafifoflush; test DFSTATUS, MREQPEND jnz .; ultra2_dmahalt: - and DFCNTRL, ~HDMAEN; - test DFCNTRL, HDMAEN jnz .; - and DFCNTRL, ~SCSIEN; - test DFCNTRL, SCSIEN jnz .; + test SCSIOFFSET, 0x7f jnz ultra2_shutdown; +ultra2_await_nreq: + test SCSISIGI, REQI jz ultra2_shutdown; + test SSTAT1, (PHASEMIS|REQINIT) jz ultra2_await_nreq; +ultra2_shutdown: + and DFCNTRL, ~(HDMAEN|SCSIEN); + test DFCNTRL, (HDMAEN|SCSIEN) jnz .; bmov SCB_RESID_DCNT, STCNT, 3; mov SCB_RESID_SGCNT, SG_COUNT; or SXFRCTL0, CLRSTCNT|CLRCHN; @@ -719,10 +616,11 @@ p_command_dma_loop: test SSTAT0, SDONE jnz p_command_ultra2_dma_done; test SSTAT1,PHASEMIS jz p_command_dma_loop; /* ie. underrun */ p_command_ultra2_dma_done: - and DFCNTRL, ~HDMAEN; - test DFCNTRL, HDMAEN jnz .; - and DFCNTRL, ~SCSIEN; - test DFCNTRL, SCSIEN jnz .; + test SCSISIGI, REQI jz p_command_ultra2_shutdown; + test SSTAT1, (PHASEMIS|REQINIT) jz p_command_ultra2_dma_done; +p_command_ultra2_shutdown: + and DFCNTRL, ~(HDMAEN|SCSIEN); + test DFCNTRL, (HDMAEN|SCSIEN) jnz .; or SXFRCTL0, CLRSTCNT|CLRCHN; } jmp ITloop; @@ -1069,25 +967,12 @@ mesgin_wide_residue: mvi ARG_1 call inb_next; /* ACK the wide_residue and get */ /* the size byte */ /* - * See if we'll ignore this wide residue (because it's an overrun byte) - */ - if ((p->features & AHC_ULTRA2) != 0) { - test SSTAT2, WIDE_RES jnz mesgin_done; - } else { - test SCB_RESID_SGCNT,0xff jnz wide_residue_int; - test SCB_RESID_DCNT[0],0xff jnz wide_residue_int; - test SCB_RESID_DCNT[1],0xff jnz wide_residue_int; - test SCB_RESID_DCNT[2],0xff jnz wide_residue_int; - jmp mesgin_done; - } -wide_residue_int: -/* * In order for this to be reliable, we have to do all sorts of horrible * magic in terms of resetting the datafifo and reloading the shadow layer * with the correct new values (so that a subsequent save data pointers * message will do the right thing). We let the kernel do that work. */ - mvi INTSTAT,WIDE_RESIDUE; + mvi INTSTAT, WIDE_RESIDUE; jmp mesgin_done; /* @@ -1136,17 +1021,6 @@ inb_first: inb_last: mov NONE,SCSIDATL ret; /*dummy read from latch to ACK*/ -if ((p->flags & AHC_TARGETMODE) != 0) { - /* - * Send a byte to an initiator in Automatic PIO mode. - * SPIOEN must be on prior to calling this routine. - */ -target_outb: - mov SCSIDATL, SINDEX; - test SSTAT0, SPIORDY jz .; - ret; -} - mesgin_phasemis: /* * We expected to receive another byte, but the target changed phase @@ -1191,6 +1065,12 @@ dma_fifoempty: * actually off first lest we get an ILLSADDR. */ dma_dmadone: + cmp LASTPHASE, P_COMMAND je dma_await_nreq; + test SCSIRATE, 0x0f jnz dma_shutdown; +dma_await_nreq: + test SCSISIGI, REQI jz dma_shutdown; + test SSTAT1, (PHASEMIS|REQINIT) jz dma_await_nreq; +dma_shutdown: and DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN); dma_halt: /* diff --git a/drivers/scsi/aic7xxx_proc.c b/drivers/scsi/aic7xxx_proc.c index ec80af90d..7320eb6b6 100644 --- a/drivers/scsi/aic7xxx_proc.c +++ b/drivers/scsi/aic7xxx_proc.c @@ -172,7 +172,6 @@ aic7xxx_proc_info ( char *buffer, char **start, off_t offset, int length, #else size += sprintf(BLS, " AIC7XXX_PROC_STATS : Disabled\n"); #endif - size += sprintf(BLS, " AIC7XXX_RESET_DELAY : %d\n", AIC7XXX_RESET_DELAY); size += sprintf(BLS, "\n"); size += sprintf(BLS, "Adapter Configuration:\n"); size += sprintf(BLS, " SCSI Adapter: %s\n", diff --git a/drivers/scsi/aic7xxx_seq.c b/drivers/scsi/aic7xxx_seq.c index 511bfcb73..047a34de0 100644 --- a/drivers/scsi/aic7xxx_seq.c +++ b/drivers/scsi/aic7xxx_seq.c @@ -4,34 +4,33 @@ static unsigned char seqprog[] = { 0xff, 0x6a, 0x06, 0x08, 0x7f, 0x02, 0x04, 0x08, - 0x32, 0x6a, 0x00, 0x00, 0x12, 0x6a, 0x00, 0x00, 0xff, 0x6a, 0xd6, 0x09, 0xff, 0x6a, 0xdc, 0x09, - 0x00, 0x65, 0x42, 0x59, + 0x00, 0x65, 0xca, 0x58, 0xf7, 0x01, 0x02, 0x08, 0xff, 0x4e, 0xc8, 0x08, 0xbf, 0x60, 0xc0, 0x08, 0x60, 0x0b, 0x86, 0x68, - 0x40, 0x00, 0x0e, 0x68, + 0x40, 0x00, 0x0c, 0x68, 0x08, 0x1f, 0x3e, 0x10, 0x60, 0x0b, 0x86, 0x68, - 0x40, 0x00, 0x0e, 0x68, + 0x40, 0x00, 0x0c, 0x68, 0x08, 0x1f, 0x3e, 0x10, - 0xff, 0x3e, 0x4a, 0x60, - 0x40, 0xfa, 0x12, 0x78, + 0xff, 0x3e, 0x48, 0x60, + 0x40, 0xfa, 0x10, 0x78, 0xff, 0xf6, 0xd4, 0x08, 0x01, 0x4e, 0x9c, 0x18, 0x40, 0x60, 0xc0, 0x00, - 0x00, 0x4d, 0x12, 0x70, + 0x00, 0x4d, 0x10, 0x70, 0x01, 0x4e, 0x9c, 0x18, 0xbf, 0x60, 0xc0, 0x08, - 0x00, 0x6a, 0xbe, 0x5c, + 0x00, 0x6a, 0x3e, 0x5c, 0xff, 0x4e, 0xc8, 0x18, - 0x02, 0x6a, 0xd4, 0x5b, + 0x02, 0x6a, 0x54, 0x5b, 0xff, 0x52, 0x20, 0x09, 0x0d, 0x6a, 0x6a, 0x00, - 0x00, 0x52, 0x4a, 0x5c, + 0x00, 0x52, 0xca, 0x5b, 0x03, 0xb0, 0x52, 0x31, 0xff, 0xb0, 0x52, 0x09, 0xff, 0xb1, 0x54, 0x09, @@ -40,8 +39,8 @@ static unsigned char seqprog[] = { 0xff, 0x3e, 0x74, 0x09, 0xff, 0x90, 0x7c, 0x08, 0xff, 0x3e, 0x20, 0x09, - 0x00, 0x65, 0x50, 0x58, - 0x00, 0x65, 0x0e, 0x40, + 0x00, 0x65, 0x4e, 0x58, + 0x00, 0x65, 0x0c, 0x40, 0xf7, 0x1f, 0xca, 0x08, 0x08, 0xa1, 0xc8, 0x08, 0x00, 0x65, 0xca, 0x00, @@ -52,6 +51,7 @@ static unsigned char seqprog[] = { 0xf0, 0xa1, 0xc8, 0x08, 0x0f, 0x05, 0x0a, 0x08, 0x00, 0x05, 0x0a, 0x00, + 0xff, 0x6a, 0x0c, 0x08, 0x5a, 0x6a, 0x00, 0x04, 0x12, 0x65, 0x02, 0x00, 0x31, 0x6a, 0xca, 0x00, @@ -69,74 +69,14 @@ static unsigned char seqprog[] = { 0xff, 0x6c, 0x0a, 0x08, 0x20, 0x64, 0xca, 0x18, 0xff, 0x6c, 0x08, 0x0c, - 0x40, 0x0b, 0x0e, 0x69, - 0x80, 0x0b, 0x00, 0x79, - 0xa4, 0x6a, 0x06, 0x00, - 0x40, 0x6a, 0x16, 0x00, - 0x10, 0x03, 0xfc, 0x78, - 0xff, 0x50, 0xc8, 0x08, - 0x88, 0x6a, 0xcc, 0x00, - 0x49, 0x6a, 0x3a, 0x5c, - 0x01, 0x6a, 0x26, 0x01, - 0xff, 0x6a, 0xca, 0x08, - 0x08, 0x01, 0x02, 0x00, - 0x02, 0x0b, 0x9c, 0x78, - 0xf7, 0x01, 0x02, 0x08, - 0xff, 0x06, 0xcc, 0x08, - 0xff, 0x66, 0x32, 0x09, - 0x01, 0x65, 0xca, 0x18, - 0x80, 0x66, 0xaa, 0x78, - 0xff, 0x66, 0xa2, 0x08, - 0x10, 0x03, 0x9a, 0x68, - 0xfc, 0x65, 0xc8, 0x18, - 0x00, 0x65, 0xb2, 0x48, - 0xff, 0x6a, 0x32, 0x01, - 0x01, 0x64, 0x18, 0x19, - 0xff, 0x6a, 0x1a, 0x09, - 0xff, 0x6a, 0x1c, 0x09, - 0x84, 0x6a, 0x06, 0x00, - 0x08, 0x01, 0x02, 0x00, - 0x02, 0x0b, 0xbc, 0x78, - 0xff, 0x06, 0xc8, 0x08, - 0xff, 0x64, 0x32, 0x09, - 0xff, 0x6a, 0xca, 0x08, - 0x5b, 0x64, 0xc8, 0x28, - 0x00, 0x62, 0xc4, 0x18, - 0xfc, 0x65, 0xca, 0x18, - 0xff, 0x6a, 0xd4, 0x08, - 0xfa, 0x65, 0xca, 0x18, - 0xff, 0x6a, 0xd4, 0x08, - 0x04, 0x65, 0xca, 0x18, - 0x0b, 0x65, 0xca, 0x18, - 0xff, 0x65, 0xc8, 0x08, - 0x00, 0x8c, 0x18, 0x19, - 0x02, 0x0b, 0xd8, 0x78, - 0x01, 0x65, 0xde, 0x60, - 0xf7, 0x01, 0x02, 0x08, - 0xff, 0x06, 0x32, 0x09, - 0xff, 0x65, 0xca, 0x18, - 0xff, 0x65, 0xd8, 0x68, - 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0xb0, 0x5c, - 0x40, 0x51, 0xf0, 0x78, - 0xe4, 0x6a, 0x06, 0x00, - 0x08, 0x01, 0x02, 0x00, - 0x04, 0x6a, 0x6c, 0x5b, - 0x01, 0x50, 0xa0, 0x18, - 0x00, 0x50, 0xf6, 0xe0, - 0xff, 0x6a, 0xa0, 0x08, - 0xff, 0x6a, 0x3a, 0x01, - 0x02, 0x6a, 0x22, 0x01, - 0x40, 0x51, 0xfc, 0x68, - 0xff, 0x6a, 0x06, 0x08, - 0x00, 0x65, 0x0e, 0x40, + 0x40, 0x0b, 0x96, 0x68, 0x20, 0x6a, 0x16, 0x00, 0xf0, 0x19, 0x6e, 0x08, 0x08, 0x6a, 0x18, 0x00, 0x08, 0x11, 0x22, 0x00, 0x08, 0x6a, 0x66, 0x58, 0x08, 0x6a, 0x68, 0x00, - 0x00, 0x65, 0x22, 0x41, + 0x00, 0x65, 0xaa, 0x40, 0x12, 0x6a, 0x00, 0x00, 0x40, 0x6a, 0x16, 0x00, 0xff, 0x3e, 0x20, 0x09, @@ -147,21 +87,21 @@ static unsigned char seqprog[] = { 0x08, 0x6a, 0x66, 0x58, 0x80, 0x6a, 0x68, 0x00, 0x80, 0x36, 0x6c, 0x00, - 0x00, 0x65, 0x1e, 0x5c, + 0x00, 0x65, 0x9e, 0x5b, 0xff, 0x3d, 0xc8, 0x08, - 0xbf, 0x64, 0x5a, 0x79, - 0x80, 0x64, 0x22, 0x72, - 0xa0, 0x64, 0x52, 0x72, - 0xc0, 0x64, 0x4a, 0x72, - 0xe0, 0x64, 0x92, 0x72, + 0xbf, 0x64, 0xe2, 0x78, + 0x80, 0x64, 0xac, 0x71, + 0xa0, 0x64, 0xdc, 0x71, + 0xc0, 0x64, 0xd4, 0x71, + 0xe0, 0x64, 0x1c, 0x72, 0x01, 0x6a, 0x22, 0x01, - 0x00, 0x65, 0x22, 0x41, + 0x00, 0x65, 0xaa, 0x40, 0xf7, 0x11, 0x22, 0x08, - 0x00, 0x65, 0x42, 0x59, + 0x00, 0x65, 0xca, 0x58, 0xff, 0x06, 0xd4, 0x08, 0xf7, 0x01, 0x02, 0x08, - 0x09, 0x0c, 0x3c, 0x79, - 0x08, 0x0c, 0x0e, 0x68, + 0x09, 0x0c, 0xc4, 0x78, + 0x08, 0x0c, 0x0c, 0x68, 0x01, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0x26, 0x09, 0x02, 0x6a, 0x08, 0x30, @@ -173,25 +113,25 @@ static unsigned char seqprog[] = { 0x03, 0xa9, 0x18, 0x31, 0x03, 0xa9, 0x10, 0x30, 0x08, 0x6a, 0xcc, 0x00, - 0xa9, 0x6a, 0x34, 0x5c, - 0x00, 0x65, 0x7a, 0x41, + 0xa9, 0x6a, 0xb4, 0x5b, + 0x00, 0x65, 0x02, 0x41, 0xa8, 0x6a, 0x6a, 0x00, 0x79, 0x6a, 0x6a, 0x00, - 0x40, 0x3d, 0x62, 0x69, + 0x40, 0x3d, 0xea, 0x68, 0x04, 0x35, 0x6a, 0x00, - 0x00, 0x65, 0x8e, 0x5b, + 0x00, 0x65, 0x0e, 0x5b, 0x80, 0x6a, 0xd4, 0x01, - 0x10, 0x36, 0x4e, 0x69, + 0x10, 0x36, 0xd6, 0x68, 0x10, 0x36, 0x6c, 0x00, 0x07, 0xac, 0x10, 0x31, 0x03, 0x8c, 0x10, 0x30, 0x05, 0xa3, 0x70, 0x30, 0x88, 0x6a, 0xcc, 0x00, - 0xac, 0x6a, 0x2c, 0x5c, - 0x00, 0x65, 0x26, 0x5c, + 0xac, 0x6a, 0xac, 0x5b, + 0x00, 0x65, 0xa6, 0x5b, 0x38, 0x6a, 0xcc, 0x00, - 0xa3, 0x6a, 0x30, 0x5c, - 0xff, 0x38, 0x8a, 0x69, + 0xa3, 0x6a, 0xb0, 0x5b, + 0xff, 0x38, 0x12, 0x69, 0x80, 0x02, 0x04, 0x00, 0xe7, 0x35, 0x6a, 0x08, 0x03, 0x69, 0x18, 0x31, @@ -199,338 +139,334 @@ static unsigned char seqprog[] = { 0xff, 0x6a, 0x10, 0x00, 0xff, 0x6a, 0x12, 0x00, 0xff, 0x6a, 0x14, 0x00, - 0x01, 0x38, 0x90, 0x61, + 0x01, 0x38, 0x18, 0x61, 0xbf, 0x35, 0x6a, 0x08, 0x02, 0x6a, 0xf8, 0x01, 0xff, 0x69, 0xca, 0x08, 0xff, 0x35, 0x26, 0x09, - 0x04, 0x0b, 0x94, 0x69, - 0x04, 0x0b, 0xa0, 0x69, - 0x10, 0x0c, 0x96, 0x79, - 0x04, 0x0b, 0xa0, 0x69, + 0x04, 0x0b, 0x1c, 0x69, + 0x04, 0x0b, 0x28, 0x69, + 0x10, 0x0c, 0x1e, 0x79, + 0x04, 0x0b, 0x28, 0x69, 0xff, 0x6a, 0xca, 0x08, - 0x00, 0x35, 0x76, 0x5b, - 0x80, 0x02, 0xf4, 0x69, - 0xff, 0x65, 0xe4, 0x79, + 0x00, 0x35, 0xee, 0x5a, + 0x80, 0x02, 0x7c, 0x69, + 0xff, 0x65, 0x6c, 0x79, 0xff, 0x38, 0x70, 0x18, - 0xff, 0x38, 0xe4, 0x79, - 0x80, 0xea, 0xc0, 0x61, + 0xff, 0x38, 0x6c, 0x79, + 0x80, 0xea, 0x48, 0x61, 0xef, 0x38, 0xc8, 0x18, 0x80, 0x6a, 0xc8, 0x00, - 0x00, 0x65, 0xb2, 0x49, + 0x00, 0x65, 0x3a, 0x49, 0x33, 0x38, 0xc8, 0x28, 0xff, 0x64, 0xd0, 0x09, 0x04, 0x39, 0xc0, 0x31, 0x09, 0x6a, 0xd6, 0x01, - 0x80, 0xeb, 0xb8, 0x79, + 0x80, 0xeb, 0x40, 0x79, 0xf7, 0xeb, 0xd6, 0x09, - 0x08, 0xeb, 0xbc, 0x69, + 0x08, 0xeb, 0x44, 0x69, 0x01, 0x6a, 0xd6, 0x01, 0x08, 0xe9, 0x10, 0x31, 0x03, 0x8c, 0x10, 0x30, 0x88, 0x6a, 0xcc, 0x00, - 0x39, 0x6a, 0x32, 0x5c, + 0x39, 0x6a, 0xb2, 0x5b, 0x08, 0x6a, 0x18, 0x01, 0xff, 0x6a, 0x1a, 0x09, 0xff, 0x6a, 0x1c, 0x09, 0x0d, 0x93, 0x26, 0x01, - 0x00, 0x65, 0xb0, 0x5c, - 0x88, 0x6a, 0xa0, 0x5c, - 0x00, 0x65, 0x26, 0x5c, + 0x00, 0x65, 0x30, 0x5c, + 0x88, 0x6a, 0x20, 0x5c, + 0x00, 0x65, 0xa6, 0x5b, 0xff, 0x6a, 0xc8, 0x08, 0x08, 0x39, 0x72, 0x18, 0x00, 0x3a, 0x74, 0x20, - 0x01, 0x0c, 0xdc, 0x79, - 0x10, 0x0c, 0x7a, 0x79, + 0x01, 0x0c, 0x64, 0x79, + 0x10, 0x0c, 0x02, 0x79, 0xff, 0x35, 0x26, 0x09, - 0x04, 0x0b, 0xe2, 0x69, - 0x00, 0x65, 0xfc, 0x59, + 0x04, 0x0b, 0x6a, 0x69, + 0x00, 0x65, 0x84, 0x59, 0x03, 0x08, 0x52, 0x31, 0xff, 0x38, 0x50, 0x09, 0xff, 0x08, 0x52, 0x09, 0xff, 0x09, 0x54, 0x09, 0xff, 0x0a, 0x56, 0x09, 0xff, 0x38, 0x50, 0x09, - 0x00, 0x65, 0x22, 0x41, - 0x00, 0x65, 0xfc, 0x59, + 0x00, 0x65, 0xaa, 0x40, + 0x00, 0x65, 0x84, 0x59, 0x7f, 0x02, 0x04, 0x08, 0xe1, 0x6a, 0x22, 0x01, - 0x00, 0x65, 0x22, 0x41, - 0x04, 0x93, 0x12, 0x6a, + 0x00, 0x65, 0xaa, 0x40, + 0x04, 0x93, 0x9a, 0x69, 0xdf, 0x93, 0x26, 0x09, - 0x20, 0x93, 0x00, 0x6a, + 0x20, 0x93, 0x88, 0x69, 0x02, 0x93, 0x26, 0x01, - 0x01, 0x94, 0x02, 0x7a, - 0x01, 0x94, 0x02, 0x7a, - 0x01, 0x94, 0x02, 0x7a, - 0x01, 0x94, 0x02, 0x7a, - 0x01, 0x94, 0x02, 0x7a, - 0x01, 0x94, 0x02, 0x7a, - 0x10, 0x94, 0x10, 0x6a, - 0xf7, 0x93, 0x26, 0x09, - 0x08, 0x93, 0x14, 0x6a, - 0xdf, 0x93, 0x26, 0x09, - 0x20, 0x93, 0x18, 0x6a, + 0x01, 0x94, 0x8a, 0x79, + 0x01, 0x94, 0x8a, 0x79, + 0x01, 0x94, 0x8a, 0x79, + 0x01, 0x94, 0x8a, 0x79, + 0x01, 0x94, 0x8a, 0x79, + 0x01, 0x94, 0x8a, 0x79, + 0x10, 0x94, 0x98, 0x69, + 0x7f, 0x05, 0xa0, 0x69, + 0x02, 0x03, 0xa0, 0x79, + 0x11, 0x0c, 0x9c, 0x79, + 0xd7, 0x93, 0x26, 0x09, + 0x28, 0x93, 0xa2, 0x69, 0x03, 0x08, 0x52, 0x31, 0xff, 0x38, 0x50, 0x09, 0x12, 0x01, 0x02, 0x00, 0xff, 0x6a, 0xd4, 0x0c, - 0x00, 0x65, 0x8e, 0x5b, + 0x00, 0x65, 0x0e, 0x5b, 0x05, 0xb4, 0x10, 0x31, 0x02, 0x6a, 0x1a, 0x31, 0x03, 0x8c, 0x10, 0x30, 0x88, 0x6a, 0xcc, 0x00, - 0xb4, 0x6a, 0x30, 0x5c, + 0xb4, 0x6a, 0xb0, 0x5b, 0xff, 0x6a, 0x1a, 0x09, 0xff, 0x6a, 0x1c, 0x09, - 0x00, 0x65, 0x26, 0x5c, - 0x3d, 0x6a, 0x76, 0x5b, + 0x00, 0x65, 0xa6, 0x5b, + 0x3d, 0x6a, 0xee, 0x5a, 0xac, 0x6a, 0x26, 0x01, - 0x04, 0x0b, 0x38, 0x6a, - 0x04, 0x0b, 0x3e, 0x6a, - 0x10, 0x0c, 0x3a, 0x7a, - 0xf7, 0x93, 0x26, 0x09, - 0x08, 0x93, 0x40, 0x6a, - 0xdf, 0x93, 0x26, 0x09, - 0x20, 0x93, 0x44, 0x6a, + 0x04, 0x0b, 0xc2, 0x69, + 0x04, 0x0b, 0xc8, 0x69, + 0x10, 0x0c, 0xc4, 0x79, + 0x02, 0x03, 0xcc, 0x79, + 0x11, 0x0c, 0xc8, 0x79, + 0xd7, 0x93, 0x26, 0x09, + 0x28, 0x93, 0xce, 0x69, 0x12, 0x01, 0x02, 0x00, - 0x00, 0x65, 0x22, 0x41, - 0x00, 0x65, 0x8e, 0x5b, + 0x00, 0x65, 0xaa, 0x40, + 0x00, 0x65, 0x0e, 0x5b, 0xff, 0x06, 0x44, 0x09, - 0x00, 0x65, 0x22, 0x41, + 0x00, 0x65, 0xaa, 0x40, 0x10, 0x3d, 0x06, 0x00, 0xff, 0x34, 0xca, 0x08, - 0x80, 0x65, 0x76, 0x62, + 0x80, 0x65, 0x00, 0x62, 0x0f, 0xa1, 0xca, 0x08, 0x07, 0xa1, 0xca, 0x08, 0x40, 0xa0, 0xc8, 0x08, 0x00, 0x65, 0xca, 0x00, 0x80, 0x65, 0xca, 0x00, - 0x80, 0xa0, 0x66, 0x7a, + 0x80, 0xa0, 0xf0, 0x79, 0xff, 0x65, 0x0c, 0x08, - 0x00, 0x65, 0x78, 0x42, - 0x20, 0xa0, 0x7e, 0x7a, + 0x00, 0x65, 0x02, 0x42, + 0x20, 0xa0, 0x08, 0x7a, 0xff, 0x65, 0x0c, 0x08, - 0x00, 0x65, 0x1e, 0x5c, - 0xa0, 0x3d, 0x86, 0x62, + 0x00, 0x65, 0x9e, 0x5b, + 0xa0, 0x3d, 0x10, 0x62, 0x23, 0xa0, 0x0c, 0x08, - 0x00, 0x65, 0x1e, 0x5c, - 0xa0, 0x3d, 0x86, 0x62, - 0x00, 0xb9, 0x7e, 0x42, - 0xff, 0x65, 0x7e, 0x62, + 0x00, 0x65, 0x9e, 0x5b, + 0xa0, 0x3d, 0x10, 0x62, + 0x00, 0xb9, 0x08, 0x42, + 0xff, 0x65, 0x08, 0x62, 0xa1, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, - 0x10, 0x51, 0x86, 0x72, + 0x10, 0x51, 0x10, 0x72, 0x40, 0x6a, 0x18, 0x00, 0xff, 0x65, 0x0c, 0x08, - 0x00, 0x65, 0x1e, 0x5c, - 0xa0, 0x3d, 0x50, 0x72, + 0x00, 0x65, 0x9e, 0x5b, + 0xa0, 0x3d, 0xda, 0x71, 0x40, 0x6a, 0x18, 0x00, 0xff, 0x34, 0xa6, 0x08, - 0x80, 0x34, 0x8e, 0x62, + 0x80, 0x34, 0x18, 0x62, 0x7f, 0xa0, 0x40, 0x09, 0x08, 0x6a, 0x68, 0x00, - 0x00, 0x65, 0x22, 0x41, - 0x64, 0x6a, 0x66, 0x5b, - 0x80, 0x64, 0x04, 0x6b, - 0x04, 0x64, 0xe6, 0x72, - 0x02, 0x64, 0xec, 0x72, - 0x00, 0x6a, 0xae, 0x72, - 0x03, 0x64, 0x00, 0x73, - 0x01, 0x64, 0xe2, 0x72, - 0x07, 0x64, 0x42, 0x73, - 0x08, 0x64, 0xaa, 0x72, - 0x23, 0x64, 0x46, 0x73, + 0x00, 0x65, 0xaa, 0x40, + 0x64, 0x6a, 0xe4, 0x5a, + 0x80, 0x64, 0x8e, 0x6a, + 0x04, 0x64, 0x70, 0x72, + 0x02, 0x64, 0x76, 0x72, + 0x00, 0x6a, 0x38, 0x72, + 0x03, 0x64, 0x8a, 0x72, + 0x01, 0x64, 0x6c, 0x72, + 0x07, 0x64, 0xcc, 0x72, + 0x08, 0x64, 0x34, 0x72, + 0x23, 0x64, 0xd0, 0x72, 0x11, 0x6a, 0x22, 0x01, - 0x07, 0x6a, 0x58, 0x5b, + 0x07, 0x6a, 0xd6, 0x5a, 0xff, 0x06, 0xd4, 0x08, - 0x00, 0x65, 0x22, 0x41, - 0xff, 0xa8, 0xb2, 0x6a, - 0xff, 0xa2, 0xca, 0x7a, + 0x00, 0x65, 0xaa, 0x40, + 0xff, 0xa8, 0x3c, 0x6a, + 0xff, 0xa2, 0x54, 0x7a, 0x01, 0x6a, 0x6a, 0x00, - 0x00, 0xb9, 0x4a, 0x5c, - 0xff, 0xa2, 0xca, 0x7a, + 0x00, 0xb9, 0xca, 0x5b, + 0xff, 0xa2, 0x54, 0x7a, 0x71, 0x6a, 0x22, 0x01, 0xff, 0x6a, 0xd4, 0x08, - 0x40, 0x51, 0xca, 0x62, + 0x40, 0x51, 0x54, 0x62, 0x0d, 0x6a, 0x6a, 0x00, - 0x00, 0xb9, 0x4a, 0x5c, + 0x00, 0xb9, 0xca, 0x5b, 0xff, 0x3e, 0x74, 0x09, 0xff, 0x90, 0x7c, 0x08, - 0x00, 0x65, 0x50, 0x58, - 0x00, 0x65, 0x34, 0x41, - 0x20, 0xa0, 0xd2, 0x6a, + 0x00, 0x65, 0x4e, 0x58, + 0x00, 0x65, 0xbc, 0x40, + 0x20, 0xa0, 0x5c, 0x6a, 0xff, 0x37, 0xc8, 0x08, - 0x00, 0x6a, 0xf4, 0x5b, - 0xff, 0x6a, 0x0a, 0x5c, + 0x00, 0x6a, 0x74, 0x5b, + 0xff, 0x6a, 0x8a, 0x5b, 0xff, 0xf8, 0xc8, 0x08, 0xff, 0x4f, 0xc8, 0x08, - 0x01, 0x6a, 0xf4, 0x5b, - 0x00, 0xb9, 0x0a, 0x5c, + 0x01, 0x6a, 0x74, 0x5b, + 0x00, 0xb9, 0x8a, 0x5b, 0x01, 0x4f, 0x9e, 0x18, 0x02, 0x6a, 0x22, 0x01, - 0x00, 0x65, 0xb8, 0x5c, - 0x00, 0x65, 0x34, 0x41, + 0x00, 0x65, 0x38, 0x5c, + 0x00, 0x65, 0xbc, 0x40, 0x41, 0x6a, 0x22, 0x01, - 0x00, 0x65, 0x22, 0x41, + 0x00, 0x65, 0xaa, 0x40, 0x04, 0xa0, 0x40, 0x01, - 0x00, 0x65, 0xd0, 0x5c, - 0x00, 0x65, 0x34, 0x41, - 0x10, 0x36, 0xaa, 0x7a, + 0x00, 0x65, 0x50, 0x5c, + 0x00, 0x65, 0xbc, 0x40, + 0x10, 0x36, 0x34, 0x7a, 0x05, 0x38, 0x46, 0x31, 0x04, 0x14, 0x58, 0x31, 0x03, 0xa9, 0x60, 0x31, 0xa3, 0x6a, 0xcc, 0x00, - 0x38, 0x6a, 0x30, 0x5c, + 0x38, 0x6a, 0xb0, 0x5b, 0xac, 0x6a, 0xcc, 0x00, - 0x14, 0x6a, 0x32, 0x5c, - 0xa9, 0x6a, 0x34, 0x5c, - 0x00, 0x65, 0xaa, 0x42, + 0x14, 0x6a, 0xb2, 0x5b, + 0xa9, 0x6a, 0xb4, 0x5b, + 0x00, 0x65, 0x34, 0x42, 0xef, 0x36, 0x6c, 0x08, - 0x00, 0x65, 0xaa, 0x42, + 0x00, 0x65, 0x34, 0x42, 0x0f, 0x64, 0xc8, 0x08, 0x07, 0x64, 0xc8, 0x08, 0x00, 0x37, 0x6e, 0x00, 0xff, 0x6a, 0xa4, 0x00, - 0x00, 0x65, 0xc4, 0x5b, - 0xff, 0x51, 0x16, 0x73, - 0x20, 0x36, 0x20, 0x7b, - 0x00, 0x90, 0xb2, 0x5b, - 0x00, 0x65, 0x22, 0x43, + 0x00, 0x65, 0x44, 0x5b, + 0xff, 0x51, 0xa0, 0x72, + 0x20, 0x36, 0xaa, 0x7a, + 0x00, 0x90, 0x32, 0x5b, + 0x00, 0x65, 0xac, 0x42, 0xff, 0x06, 0xd4, 0x08, - 0x00, 0x65, 0x1e, 0x5c, - 0xe0, 0x3d, 0x3c, 0x63, - 0x20, 0x12, 0x3c, 0x63, - 0x51, 0x6a, 0x5c, 0x5b, - 0x00, 0x65, 0xac, 0x5b, + 0x00, 0x65, 0x9e, 0x5b, + 0xe0, 0x3d, 0xc6, 0x62, + 0x20, 0x12, 0xc6, 0x62, + 0x51, 0x6a, 0xda, 0x5a, + 0x00, 0x65, 0x2c, 0x5b, 0xff, 0x37, 0xc8, 0x08, - 0x00, 0xa1, 0x34, 0x63, - 0x04, 0xa0, 0x34, 0x7b, + 0x00, 0xa1, 0xbe, 0x62, + 0x04, 0xa0, 0xbe, 0x7a, 0xfb, 0xa0, 0x40, 0x09, 0x80, 0x36, 0x6c, 0x00, - 0x80, 0xa0, 0xaa, 0x7a, + 0x80, 0xa0, 0x34, 0x7a, 0x7f, 0xa0, 0x40, 0x09, - 0xff, 0x6a, 0x58, 0x5b, - 0x00, 0x65, 0xaa, 0x42, - 0x04, 0xa0, 0x3a, 0x7b, - 0x00, 0x65, 0xd0, 0x5c, - 0x00, 0x65, 0x3c, 0x43, - 0x00, 0x65, 0xb8, 0x5c, + 0xff, 0x6a, 0xd6, 0x5a, + 0x00, 0x65, 0x34, 0x42, + 0x04, 0xa0, 0xc4, 0x7a, + 0x00, 0x65, 0x50, 0x5c, + 0x00, 0x65, 0xc6, 0x42, + 0x00, 0x65, 0x38, 0x5c, 0x31, 0x6a, 0x22, 0x01, - 0x0c, 0x6a, 0x58, 0x5b, - 0x00, 0x65, 0xaa, 0x42, + 0x0c, 0x6a, 0xd6, 0x5a, + 0x00, 0x65, 0x34, 0x42, 0x61, 0x6a, 0x22, 0x01, - 0x00, 0x65, 0xaa, 0x42, - 0x51, 0x6a, 0x5c, 0x5b, - 0x20, 0x0d, 0xaa, 0x6a, - 0xff, 0xa8, 0x54, 0x6b, - 0xff, 0xa9, 0x54, 0x6b, - 0xff, 0xaa, 0x54, 0x6b, - 0xff, 0xab, 0x54, 0x6b, - 0x00, 0x65, 0xaa, 0x42, + 0x00, 0x65, 0x34, 0x42, + 0x51, 0x6a, 0xda, 0x5a, 0x51, 0x6a, 0x22, 0x01, - 0x00, 0x65, 0xaa, 0x42, + 0x00, 0x65, 0x34, 0x42, 0x10, 0x3d, 0x06, 0x00, 0xff, 0x65, 0x68, 0x0c, 0xff, 0x06, 0xd4, 0x08, - 0x01, 0x0c, 0x5e, 0x7b, - 0x04, 0x0c, 0x60, 0x6b, + 0x01, 0x0c, 0xdc, 0x7a, + 0x04, 0x0c, 0xde, 0x6a, 0xe0, 0x03, 0x7a, 0x08, - 0xe0, 0x3d, 0x72, 0x63, + 0xe0, 0x3d, 0xea, 0x62, 0xff, 0x65, 0xcc, 0x08, 0xff, 0x12, 0xda, 0x0c, 0xff, 0x06, 0xd4, 0x0c, - 0xff, 0x65, 0x0c, 0x08, - 0x02, 0x0b, 0x6e, 0x7b, - 0xff, 0x6a, 0xd4, 0x0c, 0xd1, 0x6a, 0x22, 0x01, - 0x00, 0x65, 0x22, 0x41, + 0x00, 0x65, 0xaa, 0x40, 0xff, 0x65, 0x26, 0x09, - 0x01, 0x0b, 0x86, 0x6b, - 0x10, 0x0c, 0x78, 0x7b, - 0x04, 0x0b, 0x80, 0x6b, + 0x01, 0x0b, 0xfe, 0x6a, + 0x10, 0x0c, 0xf0, 0x7a, + 0x04, 0x0b, 0xf8, 0x6a, 0xff, 0x6a, 0xca, 0x08, - 0x04, 0x93, 0x84, 0x6b, - 0x01, 0x94, 0x82, 0x7b, - 0x10, 0x94, 0x84, 0x6b, + 0x04, 0x93, 0xfc, 0x6a, + 0x01, 0x94, 0xfa, 0x7a, + 0x10, 0x94, 0xfc, 0x6a, + 0x80, 0x3d, 0x02, 0x73, + 0x0f, 0x04, 0x06, 0x6b, + 0x02, 0x03, 0x06, 0x7b, + 0x11, 0x0c, 0x02, 0x7b, 0xc7, 0x93, 0x26, 0x09, 0xff, 0x99, 0xd4, 0x08, - 0x38, 0x93, 0x88, 0x6b, + 0x38, 0x93, 0x08, 0x6b, 0xff, 0x6a, 0xd4, 0x0c, - 0x80, 0x36, 0x8c, 0x6b, + 0x80, 0x36, 0x0c, 0x6b, 0x21, 0x6a, 0x22, 0x05, 0xff, 0x65, 0x20, 0x09, - 0xff, 0x51, 0x9a, 0x63, + 0xff, 0x51, 0x1a, 0x63, 0xff, 0x37, 0xc8, 0x08, - 0xa1, 0x6a, 0xa6, 0x43, + 0xa1, 0x6a, 0x26, 0x43, 0xff, 0x51, 0xc8, 0x08, - 0xb9, 0x6a, 0xa6, 0x43, + 0xb9, 0x6a, 0x26, 0x43, 0xff, 0x90, 0xa4, 0x08, - 0xff, 0xba, 0xaa, 0x73, + 0xff, 0xba, 0x2a, 0x73, 0xff, 0xba, 0x20, 0x09, 0xff, 0x65, 0xca, 0x18, - 0x00, 0x6c, 0x9e, 0x63, + 0x00, 0x6c, 0x1e, 0x63, 0xff, 0x90, 0xca, 0x0c, 0xff, 0x6a, 0xca, 0x04, - 0x20, 0x36, 0xbe, 0x7b, - 0x00, 0x90, 0x92, 0x5b, - 0xff, 0x65, 0xbe, 0x73, - 0xff, 0x52, 0xbc, 0x73, + 0x20, 0x36, 0x3e, 0x7b, + 0x00, 0x90, 0x12, 0x5b, + 0xff, 0x65, 0x3e, 0x73, + 0xff, 0x52, 0x3c, 0x73, 0xff, 0xba, 0xcc, 0x08, 0xff, 0x52, 0x20, 0x09, 0xff, 0x66, 0x74, 0x09, 0xff, 0x65, 0x20, 0x0d, 0xff, 0xba, 0x7e, 0x0c, - 0x00, 0x6a, 0xbe, 0x5c, + 0x00, 0x6a, 0x3e, 0x5c, 0x0d, 0x6a, 0x6a, 0x00, - 0x00, 0x51, 0x4a, 0x44, - 0xff, 0x3f, 0x18, 0x74, + 0x00, 0x51, 0xca, 0x43, + 0xff, 0x3f, 0x98, 0x73, 0xff, 0x6a, 0xa2, 0x00, - 0x00, 0x3f, 0x92, 0x5b, - 0xff, 0x65, 0x18, 0x74, + 0x00, 0x3f, 0x12, 0x5b, + 0xff, 0x65, 0x98, 0x73, 0x20, 0x36, 0x6c, 0x00, - 0x20, 0xa0, 0xd2, 0x6b, + 0x20, 0xa0, 0x52, 0x6b, 0xff, 0xb9, 0xa2, 0x0c, 0xff, 0x6a, 0xa2, 0x04, 0xff, 0x65, 0xa4, 0x08, 0xe0, 0x6a, 0xcc, 0x00, - 0x45, 0x6a, 0x3e, 0x5c, + 0x45, 0x6a, 0xbe, 0x5b, 0x01, 0x6a, 0xd0, 0x01, 0x09, 0x6a, 0xd6, 0x01, - 0x80, 0xeb, 0xde, 0x7b, + 0x80, 0xeb, 0x5e, 0x7b, 0x01, 0x6a, 0xd6, 0x01, 0x01, 0xe9, 0xa4, 0x34, 0x88, 0x6a, 0xcc, 0x00, - 0x45, 0x6a, 0x3e, 0x5c, + 0x45, 0x6a, 0xbe, 0x5b, 0x01, 0x6a, 0x18, 0x01, 0xff, 0x6a, 0x1a, 0x09, 0xff, 0x6a, 0x1c, 0x09, 0x0d, 0x6a, 0x26, 0x01, - 0x00, 0x65, 0xb0, 0x5c, + 0x00, 0x65, 0x30, 0x5c, 0xff, 0x99, 0xa4, 0x0c, 0xff, 0x65, 0xa4, 0x08, 0xe0, 0x6a, 0xcc, 0x00, - 0x45, 0x6a, 0x3e, 0x5c, + 0x45, 0x6a, 0xbe, 0x5b, 0x01, 0x6a, 0xd0, 0x01, 0x01, 0x6a, 0xdc, 0x05, 0x88, 0x6a, 0xcc, 0x00, - 0x45, 0x6a, 0x3e, 0x5c, + 0x45, 0x6a, 0xbe, 0x5b, 0x01, 0x6a, 0x18, 0x01, 0xff, 0x6a, 0x1a, 0x09, 0xff, 0x6a, 0x1c, 0x09, 0x01, 0x6a, 0x26, 0x05, 0x01, 0x65, 0xd8, 0x31, 0x09, 0xee, 0xdc, 0x01, - 0x80, 0xee, 0x0e, 0x7c, + 0x80, 0xee, 0x8e, 0x7b, 0xff, 0x6a, 0xdc, 0x0d, 0xff, 0x65, 0x32, 0x09, 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0xb0, 0x44, + 0x00, 0x65, 0x30, 0x44, 0xff, 0x37, 0xc8, 0x08, - 0x00, 0x6a, 0xd4, 0x5b, + 0x00, 0x6a, 0x54, 0x5b, 0xff, 0x52, 0xa2, 0x0c, - 0x01, 0x0c, 0x1e, 0x7c, - 0x04, 0x0c, 0x1e, 0x6c, + 0x01, 0x0c, 0x9e, 0x7b, + 0x04, 0x0c, 0x9e, 0x6b, 0xe0, 0x03, 0x06, 0x08, 0xe0, 0x03, 0x7a, 0x0c, 0xff, 0x8c, 0x10, 0x08, @@ -553,29 +489,29 @@ static unsigned char seqprog[] = { 0x00, 0x6c, 0xda, 0x24, 0xff, 0x65, 0xc8, 0x08, 0xe0, 0x6a, 0xcc, 0x00, - 0x41, 0x6a, 0x3a, 0x5c, + 0x41, 0x6a, 0xba, 0x5b, 0xff, 0x90, 0xe2, 0x09, 0x20, 0x6a, 0xd0, 0x01, - 0x04, 0x35, 0x5c, 0x7c, + 0x04, 0x35, 0xdc, 0x7b, 0x1d, 0x6a, 0xdc, 0x01, - 0xdc, 0xee, 0x58, 0x64, - 0x00, 0x65, 0x68, 0x44, + 0xdc, 0xee, 0xd8, 0x63, + 0x00, 0x65, 0xe8, 0x43, 0x01, 0x6a, 0xdc, 0x01, 0x20, 0xa0, 0xd8, 0x31, 0x09, 0xee, 0xdc, 0x01, - 0x80, 0xee, 0x62, 0x7c, + 0x80, 0xee, 0xe2, 0x7b, 0x19, 0x6a, 0xdc, 0x01, - 0xd8, 0xee, 0x66, 0x64, + 0xd8, 0xee, 0xe6, 0x63, 0xff, 0x6a, 0xdc, 0x09, - 0x18, 0xee, 0x6a, 0x6c, + 0x18, 0xee, 0xea, 0x6b, 0xff, 0x6a, 0xd4, 0x0c, 0x88, 0x6a, 0xcc, 0x00, - 0x41, 0x6a, 0x3a, 0x5c, + 0x41, 0x6a, 0xba, 0x5b, 0x20, 0x6a, 0x18, 0x01, 0xff, 0x6a, 0x1a, 0x09, 0xff, 0x6a, 0x1c, 0x09, 0xff, 0x35, 0x26, 0x09, - 0x04, 0x35, 0x94, 0x6c, + 0x04, 0x35, 0x14, 0x6c, 0xa0, 0x6a, 0xca, 0x00, 0x20, 0x65, 0xc8, 0x18, 0xff, 0x6c, 0x32, 0x09, @@ -586,14 +522,14 @@ static unsigned char seqprog[] = { 0xff, 0x6c, 0x32, 0x09, 0xff, 0x6c, 0x32, 0x09, 0xff, 0x6c, 0x32, 0x09, - 0x00, 0x65, 0x80, 0x64, + 0x00, 0x65, 0x00, 0x64, 0x0a, 0x93, 0x26, 0x01, - 0x00, 0x65, 0xb0, 0x5c, - 0x04, 0x35, 0x8c, 0x7b, - 0xa0, 0x6a, 0xa0, 0x5c, - 0x00, 0x65, 0xa2, 0x5c, - 0x00, 0x65, 0xa2, 0x5c, - 0x00, 0x65, 0xa2, 0x44, + 0x00, 0x65, 0x30, 0x5c, + 0x04, 0x35, 0x0c, 0x7b, + 0xa0, 0x6a, 0x20, 0x5c, + 0x00, 0x65, 0x22, 0x5c, + 0x00, 0x65, 0x22, 0x5c, + 0x00, 0x65, 0x22, 0x44, 0xff, 0x65, 0xcc, 0x08, 0xff, 0x99, 0xda, 0x08, 0xff, 0x99, 0xda, 0x08, @@ -602,19 +538,19 @@ static unsigned char seqprog[] = { 0xff, 0x99, 0xda, 0x08, 0xff, 0x99, 0xda, 0x08, 0xff, 0x99, 0xda, 0x0c, - 0x08, 0x94, 0xb0, 0x7c, + 0x08, 0x94, 0x30, 0x7c, 0xf7, 0x93, 0x26, 0x09, - 0x08, 0x93, 0xb4, 0x6c, + 0x08, 0x93, 0x34, 0x6c, 0xff, 0x6a, 0xd4, 0x0c, 0xff, 0x40, 0x74, 0x09, 0xff, 0x90, 0x80, 0x08, 0xff, 0x6a, 0x72, 0x05, - 0xff, 0x40, 0xcc, 0x64, - 0xff, 0x3f, 0xc4, 0x64, + 0xff, 0x40, 0x4c, 0x64, + 0xff, 0x3f, 0x44, 0x64, 0xff, 0x6a, 0xca, 0x04, 0xff, 0x3f, 0x20, 0x09, 0x01, 0x6a, 0x6a, 0x00, - 0x00, 0xb9, 0x4a, 0x5c, + 0x00, 0xb9, 0xca, 0x5b, 0xff, 0xba, 0x7e, 0x0c, 0xff, 0x40, 0x20, 0x09, 0xff, 0xba, 0x80, 0x0c, @@ -622,20 +558,12 @@ static unsigned char seqprog[] = { 0xff, 0x90, 0x7e, 0x0c, }; -static int aic7xxx_patch13_func(struct aic7xxx_host *p); - -static int -aic7xxx_patch13_func(struct aic7xxx_host *p) -{ - return ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895); -} - static int aic7xxx_patch12_func(struct aic7xxx_host *p); static int aic7xxx_patch12_func(struct aic7xxx_host *p) { - return ((p->features & AHC_CMD_CHAN) == 0); + return ((p->features & AHC_WIDE) != 0); } static int aic7xxx_patch11_func(struct aic7xxx_host *p); @@ -643,7 +571,7 @@ static int aic7xxx_patch11_func(struct aic7xxx_host *p); static int aic7xxx_patch11_func(struct aic7xxx_host *p) { - return ((p->features & AHC_WIDE) != 0); + return ((p->features & AHC_ULTRA2) == 0); } static int aic7xxx_patch10_func(struct aic7xxx_host *p); @@ -651,7 +579,7 @@ static int aic7xxx_patch10_func(struct aic7xxx_host *p); static int aic7xxx_patch10_func(struct aic7xxx_host *p) { - return ((p->features & AHC_ULTRA2) == 0); + return ((p->features & AHC_CMD_CHAN) == 0); } static int aic7xxx_patch9_func(struct aic7xxx_host *p); @@ -659,7 +587,7 @@ static int aic7xxx_patch9_func(struct aic7xxx_host *p); static int aic7xxx_patch9_func(struct aic7xxx_host *p) { - return ((p->features & AHC_ULTRA) != 0); + return ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895); } static int aic7xxx_patch8_func(struct aic7xxx_host *p); @@ -667,7 +595,7 @@ static int aic7xxx_patch8_func(struct aic7xxx_host *p); static int aic7xxx_patch8_func(struct aic7xxx_host *p) { - return ((p->features & AHC_ULTRA2) != 0); + return ((p->features & AHC_ULTRA) != 0); } static int aic7xxx_patch7_func(struct aic7xxx_host *p); @@ -675,7 +603,7 @@ static int aic7xxx_patch7_func(struct aic7xxx_host *p); static int aic7xxx_patch7_func(struct aic7xxx_host *p) { - return ((p->flags & AHC_PAGESCBS) == 0); + return ((p->features & AHC_ULTRA2) != 0); } static int aic7xxx_patch6_func(struct aic7xxx_host *p); @@ -683,7 +611,7 @@ static int aic7xxx_patch6_func(struct aic7xxx_host *p); static int aic7xxx_patch6_func(struct aic7xxx_host *p) { - return ((p->flags & AHC_PAGESCBS) != 0); + return ((p->flags & AHC_PAGESCBS) == 0); } static int aic7xxx_patch5_func(struct aic7xxx_host *p); @@ -691,7 +619,7 @@ static int aic7xxx_patch5_func(struct aic7xxx_host *p); static int aic7xxx_patch5_func(struct aic7xxx_host *p) { - return ((p->features & AHC_QUEUE_REGS) != 0); + return ((p->flags & AHC_PAGESCBS) != 0); } static int aic7xxx_patch4_func(struct aic7xxx_host *p); @@ -699,7 +627,7 @@ static int aic7xxx_patch4_func(struct aic7xxx_host *p); static int aic7xxx_patch4_func(struct aic7xxx_host *p) { - return ((p->features & AHC_TWIN) != 0); + return ((p->features & AHC_QUEUE_REGS) != 0); } static int aic7xxx_patch3_func(struct aic7xxx_host *p); @@ -707,7 +635,7 @@ static int aic7xxx_patch3_func(struct aic7xxx_host *p); static int aic7xxx_patch3_func(struct aic7xxx_host *p) { - return ((p->features & AHC_QUEUE_REGS) == 0); + return ((p->features & AHC_TWIN) != 0); } static int aic7xxx_patch2_func(struct aic7xxx_host *p); @@ -715,7 +643,7 @@ static int aic7xxx_patch2_func(struct aic7xxx_host *p); static int aic7xxx_patch2_func(struct aic7xxx_host *p) { - return ((p->features & AHC_CMD_CHAN) != 0); + return ((p->features & AHC_QUEUE_REGS) == 0); } static int aic7xxx_patch1_func(struct aic7xxx_host *p); @@ -723,7 +651,7 @@ static int aic7xxx_patch1_func(struct aic7xxx_host *p); static int aic7xxx_patch1_func(struct aic7xxx_host *p) { - return ((p->flags & AHC_TARGETMODE) != 0); + return ((p->features & AHC_CMD_CHAN) != 0); } static int aic7xxx_patch0_func(struct aic7xxx_host *p); @@ -740,84 +668,78 @@ struct sequencer_patch { skip_instr :10, skip_patch :12; } sequencer_patches[] = { - { aic7xxx_patch1_func, 2, 1, 2 }, - { aic7xxx_patch0_func, 3, 1, 1 }, - { aic7xxx_patch2_func, 4, 2, 1 }, - { aic7xxx_patch3_func, 8, 1, 1 }, - { aic7xxx_patch3_func, 9, 1, 1 }, - { aic7xxx_patch4_func, 12, 4, 1 }, - { aic7xxx_patch5_func, 17, 3, 2 }, - { aic7xxx_patch0_func, 20, 4, 1 }, - { aic7xxx_patch6_func, 24, 1, 1 }, - { aic7xxx_patch7_func, 27, 1, 1 }, - { aic7xxx_patch2_func, 30, 1, 2 }, - { aic7xxx_patch0_func, 31, 3, 1 }, - { aic7xxx_patch4_func, 40, 4, 1 }, - { aic7xxx_patch8_func, 44, 3, 2 }, - { aic7xxx_patch0_func, 47, 3, 1 }, - { aic7xxx_patch9_func, 52, 7, 1 }, - { aic7xxx_patch4_func, 60, 3, 1 }, - { aic7xxx_patch8_func, 63, 2, 1 }, - { aic7xxx_patch1_func, 68, 60, 1 }, - { aic7xxx_patch8_func, 162, 1, 2 }, - { aic7xxx_patch0_func, 163, 2, 1 }, - { aic7xxx_patch2_func, 167, 3, 3 }, - { aic7xxx_patch8_func, 167, 2, 1 }, - { aic7xxx_patch0_func, 170, 2, 1 }, - { aic7xxx_patch8_func, 173, 1, 2 }, - { aic7xxx_patch0_func, 174, 1, 1 }, - { aic7xxx_patch2_func, 178, 1, 1 }, - { aic7xxx_patch2_func, 181, 3, 2 }, - { aic7xxx_patch0_func, 184, 5, 1 }, - { aic7xxx_patch2_func, 192, 2, 3 }, - { aic7xxx_patch8_func, 192, 1, 1 }, - { aic7xxx_patch0_func, 194, 3, 1 }, - { aic7xxx_patch10_func, 198, 1, 2 }, - { aic7xxx_patch0_func, 199, 1, 1 }, - { aic7xxx_patch8_func, 200, 7, 2 }, - { aic7xxx_patch0_func, 207, 1, 1 }, - { aic7xxx_patch2_func, 212, 14, 3 }, - { aic7xxx_patch10_func, 225, 1, 1 }, - { aic7xxx_patch0_func, 226, 9, 1 }, - { aic7xxx_patch8_func, 240, 2, 1 }, - { aic7xxx_patch8_func, 242, 1, 1 }, - { aic7xxx_patch10_func, 243, 6, 3 }, - { aic7xxx_patch2_func, 243, 2, 2 }, - { aic7xxx_patch0_func, 245, 4, 1 }, - { aic7xxx_patch8_func, 250, 1, 1 }, - { aic7xxx_patch8_func, 254, 19, 1 }, - { aic7xxx_patch2_func, 274, 3, 3 }, - { aic7xxx_patch10_func, 276, 1, 1 }, - { aic7xxx_patch0_func, 277, 5, 1 }, - { aic7xxx_patch10_func, 282, 1, 2 }, - { aic7xxx_patch0_func, 283, 9, 1 }, - { aic7xxx_patch11_func, 299, 1, 2 }, - { aic7xxx_patch0_func, 300, 1, 1 }, - { aic7xxx_patch5_func, 361, 1, 2 }, - { aic7xxx_patch0_func, 362, 1, 1 }, - { aic7xxx_patch3_func, 365, 1, 1 }, - { aic7xxx_patch2_func, 375, 3, 2 }, - { aic7xxx_patch0_func, 378, 5, 1 }, - { aic7xxx_patch11_func, 386, 1, 2 }, - { aic7xxx_patch0_func, 387, 1, 1 }, - { aic7xxx_patch6_func, 392, 1, 1 }, - { aic7xxx_patch8_func, 420, 1, 2 }, - { aic7xxx_patch0_func, 421, 5, 1 }, - { aic7xxx_patch1_func, 438, 3, 1 }, - { aic7xxx_patch10_func, 443, 11, 1 }, - { aic7xxx_patch2_func, 491, 7, 2 }, - { aic7xxx_patch0_func, 498, 8, 1 }, - { aic7xxx_patch2_func, 507, 4, 2 }, - { aic7xxx_patch0_func, 511, 6, 1 }, - { aic7xxx_patch2_func, 517, 4, 2 }, - { aic7xxx_patch0_func, 521, 3, 1 }, - { aic7xxx_patch12_func, 531, 10, 1 }, - { aic7xxx_patch2_func, 550, 17, 4 }, - { aic7xxx_patch13_func, 558, 4, 2 }, - { aic7xxx_patch0_func, 562, 2, 1 }, - { aic7xxx_patch0_func, 567, 33, 1 }, - { aic7xxx_patch12_func, 600, 4, 1 }, - { aic7xxx_patch6_func, 604, 2, 1 }, - { aic7xxx_patch6_func, 607, 9, 1 }, + { aic7xxx_patch1_func, 3, 2, 1 }, + { aic7xxx_patch2_func, 7, 1, 1 }, + { aic7xxx_patch2_func, 8, 1, 1 }, + { aic7xxx_patch3_func, 11, 4, 1 }, + { aic7xxx_patch4_func, 16, 3, 2 }, + { aic7xxx_patch0_func, 19, 4, 1 }, + { aic7xxx_patch5_func, 23, 1, 1 }, + { aic7xxx_patch6_func, 26, 1, 1 }, + { aic7xxx_patch1_func, 29, 1, 2 }, + { aic7xxx_patch0_func, 30, 3, 1 }, + { aic7xxx_patch3_func, 39, 4, 1 }, + { aic7xxx_patch7_func, 43, 3, 2 }, + { aic7xxx_patch0_func, 46, 3, 1 }, + { aic7xxx_patch8_func, 52, 7, 1 }, + { aic7xxx_patch3_func, 60, 3, 1 }, + { aic7xxx_patch7_func, 63, 2, 1 }, + { aic7xxx_patch7_func, 102, 1, 2 }, + { aic7xxx_patch0_func, 103, 2, 1 }, + { aic7xxx_patch7_func, 107, 2, 1 }, + { aic7xxx_patch9_func, 109, 1, 1 }, + { aic7xxx_patch10_func, 110, 2, 1 }, + { aic7xxx_patch7_func, 113, 1, 2 }, + { aic7xxx_patch0_func, 114, 1, 1 }, + { aic7xxx_patch1_func, 118, 1, 1 }, + { aic7xxx_patch1_func, 121, 3, 2 }, + { aic7xxx_patch0_func, 124, 5, 1 }, + { aic7xxx_patch1_func, 132, 2, 3 }, + { aic7xxx_patch7_func, 132, 1, 1 }, + { aic7xxx_patch0_func, 134, 3, 1 }, + { aic7xxx_patch11_func, 138, 1, 2 }, + { aic7xxx_patch0_func, 139, 1, 1 }, + { aic7xxx_patch7_func, 140, 7, 2 }, + { aic7xxx_patch0_func, 147, 1, 1 }, + { aic7xxx_patch1_func, 152, 14, 3 }, + { aic7xxx_patch11_func, 165, 1, 1 }, + { aic7xxx_patch0_func, 166, 9, 1 }, + { aic7xxx_patch7_func, 180, 2, 1 }, + { aic7xxx_patch7_func, 182, 1, 1 }, + { aic7xxx_patch11_func, 183, 6, 3 }, + { aic7xxx_patch1_func, 183, 2, 2 }, + { aic7xxx_patch0_func, 185, 4, 1 }, + { aic7xxx_patch7_func, 190, 1, 1 }, + { aic7xxx_patch7_func, 194, 20, 1 }, + { aic7xxx_patch1_func, 215, 3, 3 }, + { aic7xxx_patch11_func, 217, 1, 1 }, + { aic7xxx_patch0_func, 218, 5, 1 }, + { aic7xxx_patch11_func, 223, 1, 2 }, + { aic7xxx_patch0_func, 224, 9, 1 }, + { aic7xxx_patch12_func, 240, 1, 2 }, + { aic7xxx_patch0_func, 241, 1, 1 }, + { aic7xxx_patch4_func, 302, 1, 2 }, + { aic7xxx_patch0_func, 303, 1, 1 }, + { aic7xxx_patch2_func, 306, 1, 1 }, + { aic7xxx_patch1_func, 316, 3, 2 }, + { aic7xxx_patch0_func, 319, 5, 1 }, + { aic7xxx_patch12_func, 327, 1, 2 }, + { aic7xxx_patch0_func, 328, 1, 1 }, + { aic7xxx_patch5_func, 333, 1, 1 }, + { aic7xxx_patch11_func, 375, 15, 1 }, + { aic7xxx_patch1_func, 427, 7, 2 }, + { aic7xxx_patch0_func, 434, 8, 1 }, + { aic7xxx_patch1_func, 443, 4, 2 }, + { aic7xxx_patch0_func, 447, 6, 1 }, + { aic7xxx_patch1_func, 453, 4, 2 }, + { aic7xxx_patch0_func, 457, 3, 1 }, + { aic7xxx_patch10_func, 467, 10, 1 }, + { aic7xxx_patch1_func, 486, 17, 4 }, + { aic7xxx_patch9_func, 494, 4, 2 }, + { aic7xxx_patch0_func, 498, 2, 1 }, + { aic7xxx_patch0_func, 503, 33, 1 }, + { aic7xxx_patch10_func, 536, 4, 1 }, + { aic7xxx_patch5_func, 540, 2, 1 }, + { aic7xxx_patch5_func, 543, 9, 1 }, }; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 6ae59e9dd..b7d3b9cc1 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -176,6 +176,8 @@ extern void scsi_old_times_out(Scsi_Cmnd * SCpnt); */ void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt) { blk_init_queue(&SDpnt->request_queue, scsi_request_fn); + blk_queue_headactive(&SDpnt->request_queue, 0); + SDpnt->request_queue.queuedata = (void *) SDpnt; } #ifdef MODULE @@ -2567,7 +2569,6 @@ static void scsi_dump_status(int level) } } } - printk("wait_for_request = %p\n", &wait_for_request); #endif /* CONFIG_SCSI_LOGGING */ /* } */ } #endif /* CONFIG_PROC_FS */ @@ -2728,8 +2729,6 @@ Scsi_Device * scsi_get_host_dev(struct Scsi_Host * SHpnt) scsi_build_commandblocks(SDpnt); scsi_initialize_queue(SDpnt, SHpnt); - blk_queue_headactive(&SDpnt->request_queue, 0); - SDpnt->request_queue.queuedata = (void *) SDpnt; SDpnt->online = TRUE; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index d4a1fd5fb..042493e3e 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -855,10 +855,9 @@ void scsi_request_fn(request_queue_t * q) * if the device itself is blocked, or if the host is fully * occupied. */ - if (SHpnt->in_recovery - || q->plugged) { + if (SHpnt->in_recovery || q->plugged) return; - } + /* * To start with, we keep looping until the queue is empty, or until * the host is no longer able to accept any more requests. @@ -869,10 +868,8 @@ void scsi_request_fn(request_queue_t * q) * released the lock and grabbed it again, so each time * we need to check to see if the queue is plugged or not. */ - if (SHpnt->in_recovery - || q->plugged) { + if (SHpnt->in_recovery || q->plugged) return; - } /* * If the device cannot accept another request, then quit. @@ -1019,8 +1016,7 @@ void scsi_request_fn(request_queue_t * q) * We have copied the data out of the request block - it is now in * a field in SCpnt. Release the request block. */ - req->rq_status = RQ_INACTIVE; - wake_up(&wait_for_request); + blkdev_release_request(req); } /* * Now it is finally safe to release the lock. We are diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 56ef67cb2..152f8afc3 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -271,8 +271,8 @@ void scan_scsis(struct Scsi_Host *shpnt, if (SDpnt) { memset(SDpnt, 0, sizeof(Scsi_Device)); /* - * Register the queue for the device. All I/O requests will come - * in through here. We also need to register a pointer to + * Register the queue for the device. All I/O requests will + * come in through here. We also need to register a pointer to * ourselves, since the queue handler won't know what device * the queue actually represents. We could look it up, but it * is pointless work. diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 71b93e379..4bfdc59f4 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1230,9 +1230,9 @@ static int sg_attach(Scsi_Device * scsidp) sdp->detached = 0; sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0; sdp->i_rdev = MKDEV(SCSI_GENERIC_MAJOR, k); - sdp->de = devfs_register (scsidp->de, "generic", 7, DEVFS_FL_NONE, + sdp->de = devfs_register (scsidp->de, "generic", DEVFS_FL_DEFAULT, SCSI_GENERIC_MAJOR, k, - S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, + S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &sg_fops, NULL); sg_template.nr_dev++; sg_dev_arr[k] = sdp; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index e568c6d1b..cd3f7a488 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -777,9 +777,9 @@ void sr_finish() sprintf(name, "sr%d", i); strcpy(scsi_CDs[i].cdi.name, name); scsi_CDs[i].cdi.de = - devfs_register (scsi_CDs[i].device->de, "cd", 2, + devfs_register (scsi_CDs[i].device->de, "cd", DEVFS_FL_DEFAULT, MAJOR_NR, i, - S_IFBLK | S_IRUGO | S_IWUGO, 0, 0, + S_IFBLK | S_IRUGO | S_IWUGO, &cdrom_fops, NULL); register_cdrom(&scsi_CDs[i].cdi); } @@ -857,7 +857,6 @@ void cleanup_module(void) } blksize_size[MAJOR_NR] = NULL; hardsect_size[MAJOR_NR] = NULL; - blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); blk_size[MAJOR_NR] = NULL; read_ahead[MAJOR_NR] = 0; diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index a9d08c165..bdc3e8002 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3509,17 +3509,17 @@ static int st_attach(Scsi_Device * SDp) /* Rewind entry */ sprintf (name, "mt%s", formats[mode]); tpnt->de_r[mode] = - devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT, + devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, MAJOR_NR, i + (mode << 5), S_IFCHR | S_IRUGO | S_IWUGO, - 0, 0, &st_fops, NULL); + &st_fops, NULL); /* No-rewind entry */ sprintf (name, "mt%sn", formats[mode]); tpnt->de_n[mode] = - devfs_register (SDp->de, name, 0, DEVFS_FL_DEFAULT, + devfs_register (SDp->de, name, DEVFS_FL_DEFAULT, MAJOR_NR, i + (mode << 5) + 128, S_IFCHR | S_IRUGO | S_IWUGO, - 0, 0, &st_fops, NULL); + &st_fops, NULL); } devfs_register_tape (tpnt->de_r[0]); tpnt->device = SDp; |