X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fsym53c8xx_2%2Fsym_hipd.c;h=21cd4c7f528997477f73458c90dda916ec8ffa9a;hb=refs%2Fheads%2Fvserver;hp=dddf88b875dbf53afaf0aae02ed9e75304c98f52;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index dddf88b87..21cd4c7f5 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -3,6 +3,7 @@ * of PCI-SCSI IO processors. * * Copyright (C) 1999-2001 Gerard Roudier + * Copyright (c) 2003-2005 Matthew Wilcox * * This driver is derived from the Linux sym53c8xx driver. * Copyright (C) 1998-2000 Gerard Roudier @@ -22,33 +23,24 @@ * *----------------------------------------------------------------------------- * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * Where this Software is combined with software released under the terms of - * the GNU Public License ("GPL") and the terms of the GPL would require the - * combined work to also be released under the terms of the GPL, the terms - * and conditions of this License will apply in addition to those of the - * GPL with the exception of any terms or conditions of this License that - * conflict with, or are expressly prohibited by, the GPL. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include /* for timeouts in units of HZ */ + #include "sym_glue.h" #include "sym_nvram.h" @@ -59,119 +51,64 @@ /* * Needed function prototypes. */ -static void sym_int_ma (hcb_p np); -static void sym_int_sir (hcb_p np); -static ccb_p sym_alloc_ccb(hcb_p np); -static ccb_p sym_ccb_from_dsa(hcb_p np, u32 dsa); -static void sym_alloc_lcb_tags (hcb_p np, u_char tn, u_char ln); -static void sym_complete_error (hcb_p np, ccb_p cp); -static void sym_complete_ok (hcb_p np, ccb_p cp); -static int sym_compute_residual(hcb_p np, ccb_p cp); +static void sym_int_ma (struct sym_hcb *np); +static void sym_int_sir (struct sym_hcb *np); +static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np); +static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa); +static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln); +static void sym_complete_error (struct sym_hcb *np, struct sym_ccb *cp); +static void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp); +static int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp); /* - * Returns the name of this driver. - */ -char *sym_driver_name(void) -{ - return SYM_DRIVER_NAME; -} -/* - * Print a buffer in hexadecimal format. + * Print a buffer in hexadecimal format with a ".\n" at end. */ -static void sym_printb_hex (u_char *p, int n) +static void sym_printl_hex(u_char *p, int n) { while (n-- > 0) printf (" %x", *p++); -} - -/* - * Same with a label at beginning and .\n at end. - */ -static void sym_printl_hex (char *label, u_char *p, int n) -{ - printf ("%s", label); - sym_printb_hex (p, n); printf (".\n"); } -/* - * Print something which allows to retrieve the controler type, - * unit, target, lun concerned by a kernel message. - */ -static void sym_print_target (hcb_p np, int target) -{ - printf ("%s:%d:", sym_name(np), target); -} - -static void sym_print_lun(hcb_p np, int target, int lun) -{ - printf ("%s:%d:%d:", sym_name(np), target, lun); -} - -/* - * Print out the content of a SCSI message. - */ -static int sym_show_msg (u_char * msg) -{ - u_char i; - printf ("%x",*msg); - if (*msg==M_EXTENDED) { - for (i=1;i<8;i++) { - if (i-1>msg[1]) break; - printf ("-%x",msg[i]); - }; - return (i+1); - } else if ((*msg & 0xf0) == 0x20) { - printf ("-%x",msg[1]); - return (2); - }; - return (1); -} - -static void sym_print_msg (ccb_p cp, char *label, u_char *msg) +static void sym_print_msg(struct sym_ccb *cp, char *label, u_char *msg) { - PRINT_ADDR(cp); if (label) - printf ("%s: ", label); + sym_print_addr(cp->cmd, "%s: ", label); + else + sym_print_addr(cp->cmd, ""); - (void) sym_show_msg (msg); - printf (".\n"); + spi_print_msg(msg); + printf("\n"); } -static void sym_print_nego_msg (hcb_p np, int target, char *label, u_char *msg) +static void sym_print_nego_msg(struct sym_hcb *np, int target, char *label, u_char *msg) { - PRINT_TARGET(np, target); - if (label) - printf ("%s: ", label); + struct sym_tcb *tp = &np->target[target]; + dev_info(&tp->starget->dev, "%s: ", label); - (void) sym_show_msg (msg); - printf (".\n"); + spi_print_msg(msg); + printf("\n"); } /* * Print something that tells about extended errors. */ -void sym_print_xerr(ccb_p cp, int x_status) +void sym_print_xerr(struct scsi_cmnd *cmd, int x_status) { if (x_status & XE_PARITY_ERR) { - PRINT_ADDR(cp); - printf ("unrecovered SCSI parity error.\n"); + sym_print_addr(cmd, "unrecovered SCSI parity error.\n"); } if (x_status & XE_EXTRA_DATA) { - PRINT_ADDR(cp); - printf ("extraneous data discarded.\n"); + sym_print_addr(cmd, "extraneous data discarded.\n"); } if (x_status & XE_BAD_PHASE) { - PRINT_ADDR(cp); - printf ("illegal scsi phase (4/5).\n"); + sym_print_addr(cmd, "illegal scsi phase (4/5).\n"); } if (x_status & XE_SODL_UNRUN) { - PRINT_ADDR(cp); - printf ("ODD transfer in DATA OUT phase.\n"); + sym_print_addr(cmd, "ODD transfer in DATA OUT phase.\n"); } if (x_status & XE_SWIDE_OVRUN) { - PRINT_ADDR(cp); - printf ("ODD transfer in DATA IN phase.\n"); + sym_print_addr(cmd, "ODD transfer in DATA IN phase.\n"); } } @@ -196,12 +133,14 @@ static char *sym_scsi_bus_mode(int mode) * On the other hand, LVD devices need some delay * to settle and report actual BUS mode in STEST4. */ -static void sym_chip_reset (hcb_p np) +static void sym_chip_reset (struct sym_hcb *np) { - OUTB (nc_istat, SRST); - UDELAY (10); - OUTB (nc_istat, 0); - UDELAY(2000); /* For BUS MODE to settle */ + OUTB(np, nc_istat, SRST); + INB(np, nc_mbox1); + udelay(10); + OUTB(np, nc_istat, 0); + INB(np, nc_mbox1); + udelay(2000); /* For BUS MODE to settle */ } /* @@ -213,32 +152,32 @@ static void sym_chip_reset (hcb_p np) * So, we need to abort the current operation prior to * soft resetting the chip. */ -static void sym_soft_reset (hcb_p np) +static void sym_soft_reset (struct sym_hcb *np) { u_char istat = 0; int i; - if (!(np->features & FE_ISTAT1) || !(INB (nc_istat1) & SCRUN)) + if (!(np->features & FE_ISTAT1) || !(INB(np, nc_istat1) & SCRUN)) goto do_chip_reset; - OUTB (nc_istat, CABRT); + OUTB(np, nc_istat, CABRT); for (i = 100000 ; i ; --i) { - istat = INB (nc_istat); + istat = INB(np, nc_istat); if (istat & SIP) { - INW (nc_sist); + INW(np, nc_sist); } else if (istat & DIP) { - if (INB (nc_dstat) & ABRT) + if (INB(np, nc_dstat) & ABRT) break; } - UDELAY(5); + udelay(5); } - OUTB (nc_istat, 0); + OUTB(np, nc_istat, 0); if (!i) printf("%s: unable to abort current chip operation, " "ISTAT=0x%02x.\n", sym_name(np), istat); do_chip_reset: - sym_chip_reset (np); + sym_chip_reset(np); } /* @@ -246,27 +185,28 @@ do_chip_reset: * * The interrupt handler will reinitialize the chip. */ -static void sym_start_reset(hcb_p np) +static void sym_start_reset(struct sym_hcb *np) { - (void) sym_reset_scsi_bus(np, 1); + sym_reset_scsi_bus(np, 1); } -int sym_reset_scsi_bus(hcb_p np, int enab_int) +int sym_reset_scsi_bus(struct sym_hcb *np, int enab_int) { u32 term; int retv = 0; sym_soft_reset(np); /* Soft reset the chip */ if (enab_int) - OUTW (nc_sien, RST); + OUTW(np, nc_sien, RST); /* * Enable Tolerant, reset IRQD if present and * properly set IRQ mode, prior to resetting the bus. */ - OUTB (nc_stest3, TE); - OUTB (nc_dcntl, (np->rv_dcntl & IRQM)); - OUTB (nc_scntl1, CRST); - UDELAY (200); + OUTB(np, nc_stest3, TE); + OUTB(np, nc_dcntl, (np->rv_dcntl & IRQM)); + OUTB(np, nc_scntl1, CRST); + INB(np, nc_mbox1); + udelay(200); if (!SYM_SETUP_SCSI_BUS_CHECK) goto out; @@ -276,12 +216,12 @@ int sym_reset_scsi_bus(hcb_p np, int enab_int) * We are expecting RESET to be TRUE and other signals to be * FALSE. */ - term = INB(nc_sstat0); + term = INB(np, nc_sstat0); term = ((term & 2) << 7) + ((term & 1) << 17); /* rst sdp0 */ - term |= ((INB(nc_sstat2) & 0x01) << 26) | /* sdp1 */ - ((INW(nc_sbdl) & 0xff) << 9) | /* d7-0 */ - ((INW(nc_sbdl) & 0xff00) << 10) | /* d15-8 */ - INB(nc_sbcl); /* req ack bsy sel atn msg cd io */ + term |= ((INB(np, nc_sstat2) & 0x01) << 26) | /* sdp1 */ + ((INW(np, nc_sbdl) & 0xff) << 9) | /* d7-0 */ + ((INW(np, nc_sbdl) & 0xff00) << 10) | /* d15-8 */ + INB(np, nc_sbcl); /* req ack bsy sel atn msg cd io */ if (!np->maxwide) term &= 0x3ffff; @@ -298,45 +238,46 @@ int sym_reset_scsi_bus(hcb_p np, int enab_int) retv = 1; } out: - OUTB (nc_scntl1, 0); - /* MDELAY(100); */ + OUTB(np, nc_scntl1, 0); return retv; } /* * Select SCSI clock frequency */ -static void sym_selectclock(hcb_p np, u_char scntl3) +static void sym_selectclock(struct sym_hcb *np, u_char scntl3) { /* * If multiplier not present or not selected, leave here. */ if (np->multiplier <= 1) { - OUTB(nc_scntl3, scntl3); + OUTB(np, nc_scntl3, scntl3); return; } if (sym_verbose >= 2) printf ("%s: enabling clock multiplier\n", sym_name(np)); - OUTB(nc_stest1, DBLEN); /* Enable clock multiplier */ + OUTB(np, nc_stest1, DBLEN); /* Enable clock multiplier */ /* * Wait for the LCKFRQ bit to be set if supported by the chip. * Otherwise wait 50 micro-seconds (at least). */ if (np->features & FE_LCKFRQ) { int i = 20; - while (!(INB(nc_stest4) & LCKFRQ) && --i > 0) - UDELAY (20); + while (!(INB(np, nc_stest4) & LCKFRQ) && --i > 0) + udelay(20); if (!i) printf("%s: the chip cannot lock the frequency\n", sym_name(np)); - } else - UDELAY ((50+10)); - OUTB(nc_stest3, HSC); /* Halt the scsi clock */ - OUTB(nc_scntl3, scntl3); - OUTB(nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier */ - OUTB(nc_stest3, 0x00); /* Restart scsi clock */ + } else { + INB(np, nc_mbox1); + udelay(50+10); + } + OUTB(np, nc_stest3, HSC); /* Halt the scsi clock */ + OUTB(np, nc_scntl3, scntl3); + OUTB(np, nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier */ + OUTB(np, nc_stest3, 0x00); /* Restart scsi clock */ } @@ -361,7 +302,7 @@ static void sym_selectclock(hcb_p np, u_char scntl3) /* * calculate SCSI clock frequency (in KHz) */ -static unsigned getfreq (hcb_p np, int gen) +static unsigned getfreq (struct sym_hcb *np, int gen) { unsigned int ms = 0; unsigned int f; @@ -381,38 +322,38 @@ static unsigned getfreq (hcb_p np, int gen) * performed trust the higher delay * (lower frequency returned). */ - OUTW (nc_sien , 0); /* mask all scsi interrupts */ - (void) INW (nc_sist); /* clear pending scsi interrupt */ - OUTB (nc_dien , 0); /* mask all dma interrupts */ - (void) INW (nc_sist); /* another one, just to be sure :) */ + OUTW(np, nc_sien, 0); /* mask all scsi interrupts */ + INW(np, nc_sist); /* clear pending scsi interrupt */ + OUTB(np, nc_dien, 0); /* mask all dma interrupts */ + INW(np, nc_sist); /* another one, just to be sure :) */ /* * The C1010-33 core does not report GEN in SIST, * if this interrupt is masked in SIEN. * I don't know yet if the C1010-66 behaves the same way. */ if (np->features & FE_C10) { - OUTW (nc_sien, GEN); - OUTB (nc_istat1, SIRQD); + OUTW(np, nc_sien, GEN); + OUTB(np, nc_istat1, SIRQD); } - OUTB (nc_scntl3, 4); /* set pre-scaler to divide by 3 */ - OUTB (nc_stime1, 0); /* disable general purpose timer */ - OUTB (nc_stime1, gen); /* set to nominal delay of 1<features & FE_C10) { - OUTW (nc_sien, 0); - OUTB (nc_istat1, 0); + OUTW(np, nc_sien, 0); + OUTB(np, nc_istat1, 0); } /* * set prescaler to divide by whatever 0 means * 0 ought to choose divide by 2, but appears * to set divide by 3.5 mode in my 53c810 ... */ - OUTB (nc_scntl3, 0); + OUTB(np, nc_scntl3, 0); /* * adjust for prescaler, and convert into KHz @@ -433,12 +374,12 @@ static unsigned getfreq (hcb_p np, int gen) return f; } -static unsigned sym_getfreq (hcb_p np) +static unsigned sym_getfreq (struct sym_hcb *np) { u_int f1, f2; int gen = 8; - (void) getfreq (np, gen); /* throw away first result */ + getfreq (np, gen); /* throw away first result */ f1 = getfreq (np, gen); f2 = getfreq (np, gen); if (f1 > f2) f1 = f2; /* trust lower result */ @@ -448,7 +389,7 @@ static unsigned sym_getfreq (hcb_p np) /* * Get/probe chip SCSI clock frequency */ -static void sym_getclock (hcb_p np, int mult) +static void sym_getclock (struct sym_hcb *np, int mult) { unsigned char scntl3 = np->sv_scntl3; unsigned char stest1 = np->sv_stest1; @@ -471,7 +412,7 @@ static void sym_getclock (hcb_p np, int mult) * Otherwise trust scntl3 BIOS setting. */ if (np->multiplier != mult || (scntl3 & 7) < 3 || !(scntl3 & 1)) { - OUTB (nc_stest1, 0); /* make sure doubler is OFF */ + OUTB(np, nc_stest1, 0); /* make sure doubler is OFF */ f1 = sym_getfreq (np); if (sym_verbose) @@ -505,7 +446,7 @@ static void sym_getclock (hcb_p np, int mult) /* * Get/probe PCI clock frequency */ -static int sym_getpciclock (hcb_p np) +static int sym_getpciclock (struct sym_hcb *np) { int f = 0; @@ -518,9 +459,9 @@ static int sym_getpciclock (hcb_p np) #else if (1) { #endif - OUTB (nc_stest1, SCLK); /* Use the PCI clock as SCSI clock */ - f = (int) sym_getfreq (np); - OUTB (nc_stest1, 0); + OUTB(np, nc_stest1, SCLK); /* Use the PCI clock as SCSI clock */ + f = sym_getfreq(np); + OUTB(np, nc_stest1, 0); } np->pciclk_khz = f; @@ -534,14 +475,14 @@ static int sym_getpciclock (hcb_p np) * calculations more simple. */ #define _5M 5000000 -static u32 div_10M[] = {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M}; +static const u32 div_10M[] = {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M}; /* * Get clock factor and sync divisor for a given * synchronous factor period. */ static int -sym_getsync(hcb_p np, u_char dt, u_char sfac, u_char *divp, u_char *fakp) +sym_getsync(struct sym_hcb *np, u_char dt, u_char sfac, u_char *divp, u_char *fakp) { u32 clk = np->clock_khz; /* SCSI clock frequency in kHz */ int div = np->clock_divn; /* Number of divisors supported */ @@ -661,7 +602,7 @@ sym_getsync(hcb_p np, u_char dt, u_char sfac, u_char *divp, u_char *fakp) /* * Set initial io register bits from burst code. */ -static __inline void sym_init_burst(hcb_p np, u_char bc) +static __inline void sym_init_burst(struct sym_hcb *np, u_char bc) { np->rv_ctest4 &= ~0x80; np->rv_dmode &= ~(0x3 << 6); @@ -677,29 +618,6 @@ static __inline void sym_init_burst(hcb_p np, u_char bc) } } - -/* - * Print out the list of targets that have some flag disabled by user. - */ -static void sym_print_targets_flag(hcb_p np, int mask, char *msg) -{ - int cnt; - int i; - - for (cnt = 0, i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) { - if (i == np->myaddr) - continue; - if (np->target[i].usrflags & mask) { - if (!cnt++) - printf("%s: %s disabled for targets", - sym_name(np), msg); - printf(" %d", i); - } - } - if (cnt) - printf(".\n"); -} - /* * Save initial settings of some IO registers. * Assumed to have been set by BIOS. @@ -709,73 +627,68 @@ static void sym_print_targets_flag(hcb_p np, int mask, char *msg) * is not safe on paper, but it seems to work quite * well. :) */ -static void sym_save_initial_setting (hcb_p np) +static void sym_save_initial_setting (struct sym_hcb *np) { - np->sv_scntl0 = INB(nc_scntl0) & 0x0a; - np->sv_scntl3 = INB(nc_scntl3) & 0x07; - np->sv_dmode = INB(nc_dmode) & 0xce; - np->sv_dcntl = INB(nc_dcntl) & 0xa8; - np->sv_ctest3 = INB(nc_ctest3) & 0x01; - np->sv_ctest4 = INB(nc_ctest4) & 0x80; - np->sv_gpcntl = INB(nc_gpcntl); - np->sv_stest1 = INB(nc_stest1); - np->sv_stest2 = INB(nc_stest2) & 0x20; - np->sv_stest4 = INB(nc_stest4); + np->sv_scntl0 = INB(np, nc_scntl0) & 0x0a; + np->sv_scntl3 = INB(np, nc_scntl3) & 0x07; + np->sv_dmode = INB(np, nc_dmode) & 0xce; + np->sv_dcntl = INB(np, nc_dcntl) & 0xa8; + np->sv_ctest3 = INB(np, nc_ctest3) & 0x01; + np->sv_ctest4 = INB(np, nc_ctest4) & 0x80; + np->sv_gpcntl = INB(np, nc_gpcntl); + np->sv_stest1 = INB(np, nc_stest1); + np->sv_stest2 = INB(np, nc_stest2) & 0x20; + np->sv_stest4 = INB(np, nc_stest4); if (np->features & FE_C10) { /* Always large DMA fifo + ultra3 */ - np->sv_scntl4 = INB(nc_scntl4); - np->sv_ctest5 = INB(nc_ctest5) & 0x04; + np->sv_scntl4 = INB(np, nc_scntl4); + np->sv_ctest5 = INB(np, nc_ctest5) & 0x04; } else - np->sv_ctest5 = INB(nc_ctest5) & 0x24; + np->sv_ctest5 = INB(np, nc_ctest5) & 0x24; } -#ifdef CONFIG_PARISC -static u32 parisc_setup_hcb(hcb_p np, u32 period) +/* + * Set SCSI BUS mode. + * - LVD capable chips (895/895A/896/1010) report the current BUS mode + * through the STEST4 IO register. + * - For previous generation chips (825/825A/875), the user has to tell us + * how to check against HVD, since a 100% safe algorithm is not possible. + */ +static void sym_set_bus_mode(struct sym_hcb *np, struct sym_nvram *nvram) { - unsigned long pdc_period; - char scsi_mode; - struct hardware_path hwpath; - - /* Host firmware (PDC) keeps a table for crippling SCSI capabilities. - * Many newer machines export one channel of 53c896 chip - * as SE, 50-pin HD. Also used for Multi-initiator SCSI clusters - * to set the SCSI Initiator ID. - */ - get_pci_node_path(np->s.device, &hwpath); - if (!pdc_get_initiator(&hwpath, &np->myaddr, &pdc_period, - &np->maxwide, &scsi_mode)) - return period; - - if (scsi_mode >= 0) { - /* C3000 PDC reports period/mode */ - SYM_SETUP_SCSI_DIFF = 0; - switch(scsi_mode) { - case 0: np->scsi_mode = SMODE_SE; break; - case 1: np->scsi_mode = SMODE_HVD; break; - case 2: np->scsi_mode = SMODE_LVD; break; - default: break; - } - } + if (np->scsi_mode) + return; - return (u32) pdc_period; + np->scsi_mode = SMODE_SE; + if (np->features & (FE_ULTRA2|FE_ULTRA3)) + np->scsi_mode = (np->sv_stest4 & SMODE); + else if (np->features & FE_DIFF) { + if (SYM_SETUP_SCSI_DIFF == 1) { + if (np->sv_scntl3) { + if (np->sv_stest2 & 0x20) + np->scsi_mode = SMODE_HVD; + } else if (nvram->type == SYM_SYMBIOS_NVRAM) { + if (!(INB(np, nc_gpreg) & 0x08)) + np->scsi_mode = SMODE_HVD; + } + } else if (SYM_SETUP_SCSI_DIFF == 2) + np->scsi_mode = SMODE_HVD; + } + if (np->scsi_mode == SMODE_HVD) + np->rv_stest2 |= 0x20; } -#else -static inline int parisc_setup_hcb(hcb_p np, u32 period) { return period; } -#endif + /* * Prepare io register values used by sym_start_up() * according to selected and supported features. */ -static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) +static int sym_prepare_setting(struct Scsi_Host *shost, struct sym_hcb *np, struct sym_nvram *nvram) { u_char burst_max; u32 period; int i; - /* - * Wide ? - */ - np->maxwide = (np->features & FE_WIDE)? 1 : 0; + np->maxwide = (np->features & FE_WIDE) ? 1 : 0; /* * Guess the frequency of the chip's clock. @@ -829,8 +742,6 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) */ period = (4 * div_10M[0] + np->clock_khz - 1) / np->clock_khz; - period = parisc_setup_hcb(np, period); - if (period <= 250) np->minsync = 10; else if (period <= 303) np->minsync = 11; else if (period <= 500) np->minsync = 12; @@ -893,7 +804,7 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) * In dual channel mode, contention occurs if internal cycles * are used. Disable internal cycles. */ - if (np->device_id == PCI_ID_LSI53C1010_33 && + if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 && np->revision_id < 0x1) np->rv_ccntl0 |= DILS; @@ -917,9 +828,9 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) * this driver. The generic ncr driver that does not use * LOAD/STORE instructions does not need this work-around. */ - if ((np->device_id == PCI_ID_SYM53C810 && + if ((np->device_id == PCI_DEVICE_ID_NCR_53C810 && np->revision_id >= 0x10 && np->revision_id <= 0x11) || - (np->device_id == PCI_ID_SYM53C860 && + (np->device_id == PCI_DEVICE_ID_NCR_53C860 && np->revision_id <= 0x1)) np->features &= ~(FE_WRIE|FE_ERL|FE_ERMP); @@ -951,22 +862,21 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) /* * Select some other */ - if (SYM_SETUP_PCI_PARITY) - np->rv_ctest4 |= MPEE; /* Master parity checking */ - if (SYM_SETUP_SCSI_PARITY) - np->rv_scntl0 |= 0x0a; /* full arb., ena parity, par->ATN */ + np->rv_ctest4 |= MPEE; /* Master parity checking */ + np->rv_scntl0 |= 0x0a; /* full arb., ena parity, par->ATN */ /* * Get parity checking, host ID and verbose mode from NVRAM */ np->myaddr = 255; - sym_nvram_setup_host (np, nvram); + np->scsi_mode = 0; + sym_nvram_setup_host(shost, np, nvram); /* * Get SCSI addr of host adapter (set by bios?). */ if (np->myaddr == 255) { - np->myaddr = INB(nc_scid) & 0x07; + np->myaddr = INB(np, nc_scid) & 0x07; if (!np->myaddr) np->myaddr = SYM_SETUP_HOST_ID; } @@ -976,33 +886,7 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) */ sym_init_burst(np, burst_max); - /* - * Set SCSI BUS mode. - * - LVD capable chips (895/895A/896/1010) report the - * current BUS mode through the STEST4 IO register. - * - For previous generation chips (825/825A/875), - * user has to tell us how to check against HVD, - * since a 100% safe algorithm is not possible. - */ - np->scsi_mode = SMODE_SE; - if (np->features & (FE_ULTRA2|FE_ULTRA3)) - np->scsi_mode = (np->sv_stest4 & SMODE); - else if (np->features & FE_DIFF) { - if (SYM_SETUP_SCSI_DIFF == 1) { - if (np->sv_scntl3) { - if (np->sv_stest2 & 0x20) - np->scsi_mode = SMODE_HVD; - } - else if (nvram->type == SYM_SYMBIOS_NVRAM) { - if (!(INB(nc_gpreg) & 0x08)) - np->scsi_mode = SMODE_HVD; - } - } - else if (SYM_SETUP_SCSI_DIFF == 2) - np->scsi_mode = SMODE_HVD; - } - if (np->scsi_mode == SMODE_HVD) - np->rv_stest2 |= 0x20; + sym_set_bus_mode(np, nvram); /* * Set LED support from SCRIPTS. @@ -1013,7 +897,7 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) if ((SYM_SETUP_SCSI_LED || (nvram->type == SYM_SYMBIOS_NVRAM || (nvram->type == SYM_TEKRAM_NVRAM && - np->device_id == PCI_ID_SYM53C895))) && + np->device_id == PCI_DEVICE_ID_NCR_53C895))) && !(np->features & FE_LEDC) && !(np->sv_gpcntl & 0x01)) np->features |= FE_LED0; @@ -1036,12 +920,14 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) * If NVRAM present get targets setup from NVRAM. */ for (i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) { - tcb_p tp = &np->target[i]; + struct sym_tcb *tp = &np->target[i]; tp->usrflags |= (SYM_DISC_ENABLED | SYM_TAGS_ENABLED); tp->usrtags = SYM_SETUP_MAX_TAG; + tp->usr_width = np->maxwide; + tp->usr_period = 9; - sym_nvram_setup_target (np, i, nvram); + sym_nvram_setup_target(tp, i, nvram); if (!tp->usrtags) tp->usrflags &= ~SYM_TAGS_ENABLED; @@ -1050,11 +936,8 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) /* * Let user know about the settings. */ - i = nvram->type; - printf("%s: %s NVRAM, ID %d, Fast-%d, %s, %s\n", sym_name(np), - i == SYM_SYMBIOS_NVRAM ? "Symbios" : - (i == SYM_TEKRAM_NVRAM ? "Tekram" : "No"), - np->myaddr, + printf("%s: %s, ID %d, Fast-%d, %s, %s\n", sym_name(np), + sym_nvram_type(nvram), np->myaddr, (np->features & FE_ULTRA3) ? 80 : (np->features & FE_ULTRA2) ? 40 : (np->features & FE_ULTRA) ? 20 : 10, @@ -1087,13 +970,6 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) sym_name(np), np->rv_scntl3, np->rv_dmode, np->rv_dcntl, np->rv_ctest3, np->rv_ctest4, np->rv_ctest5); } - /* - * Let user be aware of targets that have some disable flags set. - */ - sym_print_targets_flag(np, SYM_SCAN_BOOT_DISABLED, "SCAN AT BOOT"); - if (sym_verbose) - sym_print_targets_flag(np, SYM_SCAN_LUNS_DISABLED, - "SCAN FOR LUNS"); return 0; } @@ -1103,8 +979,8 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram) * * Has to be called with interrupts disabled. */ -#ifndef SYM_CONF_IOMAPPED -static int sym_regtest (hcb_p np) +#ifdef CONFIG_SCSI_SYM53C8XX_MMIO +static int sym_regtest(struct sym_hcb *np) { register volatile u32 data; /* @@ -1113,8 +989,8 @@ static int sym_regtest (hcb_p np) * and try to read it back. */ data = 0xffffffff; - OUTL_OFF(offsetof(struct sym_reg, nc_dstat), data); - data = INL_OFF(offsetof(struct sym_reg, nc_dstat)); + OUTL(np, nc_dstat, data); + data = INL(np, nc_dstat); #if 1 if (data == 0xffffffff) { #else @@ -1122,56 +998,61 @@ static int sym_regtest (hcb_p np) #endif printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n", (unsigned) data); - return (0x10); - }; - return (0); + return 0x10; + } + return 0; +} +#else +static inline int sym_regtest(struct sym_hcb *np) +{ + return 0; } #endif -static int sym_snooptest (hcb_p np) +static int sym_snooptest(struct sym_hcb *np) { - u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat; - int i, err=0; -#ifndef SYM_CONF_IOMAPPED - err |= sym_regtest (np); - if (err) return (err); -#endif + u32 sym_rd, sym_wr, sym_bk, host_rd, host_wr, pc, dstat; + int i, err; + + err = sym_regtest(np); + if (err) + return err; restart_test: /* * Enable Master Parity Checking as we intend * to enable it for normal operations. */ - OUTB (nc_ctest4, (np->rv_ctest4 & MPEE)); + OUTB(np, nc_ctest4, (np->rv_ctest4 & MPEE)); /* * init */ - pc = SCRIPTZ_BA (np, snooptest); + pc = SCRIPTZ_BA(np, snooptest); host_wr = 1; sym_wr = 2; /* * Set memory and register. */ np->scratch = cpu_to_scr(host_wr); - OUTL (nc_temp, sym_wr); + OUTL(np, nc_temp, sym_wr); /* * Start script (exchange values) */ - OUTL (nc_dsa, np->hcb_ba); - OUTL_DSP (pc); + OUTL(np, nc_dsa, np->hcb_ba); + OUTL_DSP(np, pc); /* * Wait 'til done (with timeout) */ for (i=0; i=SYM_SNOOP_TIMEOUT) { printf ("CACHE TEST FAILED: timeout.\n"); return (0x20); - }; + } /* * Check for fatal DMA errors. */ - dstat = INB (nc_dstat); + dstat = INB(np, nc_dstat); #if 1 /* Band aiding for broken hardwares that fail PCI parity */ if ((dstat & MDPE) && (np->rv_ctest4 & MPEE)) { printf ("%s: PCI DATA PARITY ERROR DETECTED - " @@ -1188,23 +1069,23 @@ restart_test: /* * Save termination position. */ - pc = INL (nc_dsp); + pc = INL(np, nc_dsp); /* * Read memory and register. */ host_rd = scr_to_cpu(np->scratch); - sym_rd = INL (nc_scratcha); - sym_bk = INL (nc_temp); + sym_rd = INL(np, nc_scratcha); + sym_bk = INL(np, nc_temp); /* * Check termination position. */ - if (pc != SCRIPTZ_BA (np, snoopend)+8) { + if (pc != SCRIPTZ_BA(np, snoopend)+8) { printf ("CACHE TEST FAILED: script execution failed.\n"); printf ("start=%08lx, pc=%08lx, end=%08lx\n", - (u_long) SCRIPTZ_BA (np, snooptest), (u_long) pc, - (u_long) SCRIPTZ_BA (np, snoopend) +8); + (u_long) SCRIPTZ_BA(np, snooptest), (u_long) pc, + (u_long) SCRIPTZ_BA(np, snoopend) +8); return (0x40); - }; + } /* * Show results. */ @@ -1212,19 +1093,19 @@ restart_test: printf ("CACHE TEST FAILED: host wrote %d, chip read %d.\n", (int) host_wr, (int) sym_rd); err |= 1; - }; + } if (host_rd != sym_wr) { printf ("CACHE TEST FAILED: chip wrote %d, host read %d.\n", (int) sym_wr, (int) host_rd); err |= 2; - }; + } if (sym_bk != sym_wr) { printf ("CACHE TEST FAILED: chip wrote %d, read back %d.\n", (int) sym_wr, (int) sym_bk); err |= 4; - }; + } - return (err); + return err; } /* @@ -1254,7 +1135,7 @@ restart_test: * First 24 register of the chip: * r0..rf */ -static void sym_log_hard_error(hcb_p np, u_short sist, u_char dstat) +static void sym_log_hard_error(struct sym_hcb *np, u_short sist, u_char dstat) { u32 dsp; int script_ofs; @@ -1263,7 +1144,7 @@ static void sym_log_hard_error(hcb_p np, u_short sist, u_char dstat) u_char *script_base; int i; - dsp = INL (nc_dsp); + dsp = INL(np, nc_dsp); if (dsp > np->scripta_ba && dsp <= np->scripta_ba + np->scripta_sz) { @@ -1286,12 +1167,12 @@ static void sym_log_hard_error(hcb_p np, u_short sist, u_char dstat) } printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x/%x) @ (%s %x:%08x).\n", - sym_name (np), (unsigned)INB (nc_sdid)&0x0f, dstat, sist, - (unsigned)INB (nc_socl), (unsigned)INB (nc_sbcl), - (unsigned)INB (nc_sbdl), (unsigned)INB (nc_sxfer), - (unsigned)INB (nc_scntl3), - (np->features & FE_C10) ? (unsigned)INB (nc_scntl4) : 0, - script_name, script_ofs, (unsigned)INL (nc_dbc)); + sym_name(np), (unsigned)INB(np, nc_sdid)&0x0f, dstat, sist, + (unsigned)INB(np, nc_socl), (unsigned)INB(np, nc_sbcl), + (unsigned)INB(np, nc_sbdl), (unsigned)INB(np, nc_sxfer), + (unsigned)INB(np, nc_scntl3), + (np->features & FE_C10) ? (unsigned)INB(np, nc_scntl4) : 0, + script_name, script_ofs, (unsigned)INL(np, nc_dbc)); if (((script_ofs & 3) == 0) && (unsigned)script_ofs < script_size) { @@ -1301,7 +1182,7 @@ static void sym_log_hard_error(hcb_p np, u_short sist, u_char dstat) printf ("%s: regdump:", sym_name(np)); for (i=0; i<24;i++) - printf (" %02x", (unsigned)INB_OFF(i)); + printf (" %02x", (unsigned)INB_OFF(np, i)); printf (".\n"); /* @@ -1311,92 +1192,91 @@ static void sym_log_hard_error(hcb_p np, u_short sist, u_char dstat) sym_log_bus_error(np); } -static struct sym_pci_chip sym_pci_dev_table[] = { - {PCI_ID_SYM53C810, 0x0f, "810", 4, 8, 4, 64, +static struct sym_chip sym_dev_table[] = { + {PCI_DEVICE_ID_NCR_53C810, 0x0f, "810", 4, 8, 4, 64, FE_ERL} , #ifdef SYM_DEBUG_GENERIC_SUPPORT - {PCI_ID_SYM53C810, 0xff, "810a", 4, 8, 4, 1, + {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4, 8, 4, 1, FE_BOF} , #else - {PCI_ID_SYM53C810, 0xff, "810a", 4, 8, 4, 1, + {PCI_DEVICE_ID_NCR_53C810, 0xff, "810a", 4, 8, 4, 1, FE_CACHE_SET|FE_LDSTR|FE_PFEN|FE_BOF} , #endif - {PCI_ID_SYM53C815, 0xff, "815", 4, 8, 4, 64, + {PCI_DEVICE_ID_NCR_53C815, 0xff, "815", 4, 8, 4, 64, FE_BOF|FE_ERL} , - {PCI_ID_SYM53C825, 0x0f, "825", 6, 8, 4, 64, + {PCI_DEVICE_ID_NCR_53C825, 0x0f, "825", 6, 8, 4, 64, FE_WIDE|FE_BOF|FE_ERL|FE_DIFF} , - {PCI_ID_SYM53C825, 0xff, "825a", 6, 8, 4, 2, + {PCI_DEVICE_ID_NCR_53C825, 0xff, "825a", 6, 8, 4, 2, FE_WIDE|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN|FE_RAM|FE_DIFF} , - {PCI_ID_SYM53C860, 0xff, "860", 4, 8, 5, 1, + {PCI_DEVICE_ID_NCR_53C860, 0xff, "860", 4, 8, 5, 1, FE_ULTRA|FE_CACHE_SET|FE_BOF|FE_LDSTR|FE_PFEN} , - {PCI_ID_SYM53C875, 0x01, "875", 6, 16, 5, 2, + {PCI_DEVICE_ID_NCR_53C875, 0x01, "875", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} , - {PCI_ID_SYM53C875, 0xff, "875", 6, 16, 5, 2, + {PCI_DEVICE_ID_NCR_53C875, 0xff, "875", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} , - {PCI_ID_SYM53C875_2, 0xff, "875", 6, 16, 5, 2, + {PCI_DEVICE_ID_NCR_53C875J, 0xff, "875J", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} , - {PCI_ID_SYM53C885, 0xff, "885", 6, 16, 5, 2, + {PCI_DEVICE_ID_NCR_53C885, 0xff, "885", 6, 16, 5, 2, FE_WIDE|FE_ULTRA|FE_DBLR|FE_CACHE0_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DIFF|FE_VARCLK} , #ifdef SYM_DEBUG_GENERIC_SUPPORT - {PCI_ID_SYM53C895, 0xff, "895", 6, 31, 7, 2, + {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS| FE_RAM|FE_LCKFRQ} , #else - {PCI_ID_SYM53C895, 0xff, "895", 6, 31, 7, 2, + {PCI_DEVICE_ID_NCR_53C895, 0xff, "895", 6, 31, 7, 2, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_LCKFRQ} , #endif - {PCI_ID_SYM53C896, 0xff, "896", 6, 31, 7, 4, + {PCI_DEVICE_ID_NCR_53C896, 0xff, "896", 6, 31, 7, 4, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ} , - {PCI_ID_SYM53C895A, 0xff, "895a", 6, 31, 7, 4, + {PCI_DEVICE_ID_LSI_53C895A, 0xff, "895a", 6, 31, 7, 4, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ} , - {PCI_ID_SYM53C875A, 0xff, "875a", 6, 31, 7, 4, + {PCI_DEVICE_ID_LSI_53C875A, 0xff, "875a", 6, 31, 7, 4, FE_WIDE|FE_ULTRA|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_LCKFRQ} , - {PCI_ID_LSI53C1010_33, 0x00, "1010-33", 6, 31, 7, 8, + {PCI_DEVICE_ID_LSI_53C1010_33, 0x00, "1010-33", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC| FE_C10} , - {PCI_ID_LSI53C1010_33, 0xff, "1010-33", 6, 31, 7, 8, + {PCI_DEVICE_ID_LSI_53C1010_33, 0xff, "1010-33", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_CRC| FE_C10|FE_U3EN} , - {PCI_ID_LSI53C1010_66, 0xff, "1010-66", 6, 31, 7, 8, + {PCI_DEVICE_ID_LSI_53C1010_66, 0xff, "1010-66", 6, 31, 7, 8, FE_WIDE|FE_ULTRA3|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFBC|FE_LDSTR|FE_PFEN| FE_RAM|FE_RAM8K|FE_64BIT|FE_DAC|FE_IO256|FE_NOPM|FE_LEDC|FE_66MHZ|FE_CRC| FE_C10|FE_U3EN} , - {PCI_ID_LSI53C1510D, 0xff, "1510d", 6, 31, 7, 4, + {PCI_DEVICE_ID_LSI_53C1510, 0xff, "1510d", 6, 31, 7, 4, FE_WIDE|FE_ULTRA2|FE_QUAD|FE_CACHE_SET|FE_BOF|FE_DFS|FE_LDSTR|FE_PFEN| FE_RAM|FE_IO256|FE_LEDC} }; -#define sym_pci_num_devs \ - (sizeof(sym_pci_dev_table) / sizeof(sym_pci_dev_table[0])) +#define sym_num_devs (ARRAY_SIZE(sym_dev_table)) /* * Look up the chip table. @@ -1404,14 +1284,14 @@ static struct sym_pci_chip sym_pci_dev_table[] = { * Return a pointer to the chip entry if found, * zero otherwise. */ -struct sym_pci_chip * -sym_lookup_pci_chip_table (u_short device_id, u_char revision) +struct sym_chip * +sym_lookup_chip_table (u_short device_id, u_char revision) { - struct sym_pci_chip *chip; + struct sym_chip *chip; int i; - for (i = 0; i < sym_pci_num_devs; i++) { - chip = &sym_pci_dev_table[i]; + for (i = 0; i < sym_num_devs; i++) { + chip = &sym_dev_table[i]; if (device_id != chip->device_id) continue; if (revision > chip->revision_id) @@ -1428,7 +1308,7 @@ sym_lookup_pci_chip_table (u_short device_id, u_char revision) * This is only used if the direct mapping * has been unsuccessful. */ -int sym_lookup_dmap(hcb_p np, u32 h, int s) +int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s) { int i; @@ -1461,7 +1341,7 @@ new: * Update IO registers scratch C..R so they will be * in sync. with queued CCB expectations. */ -static void sym_update_dmap_regs(hcb_p np) +static void sym_update_dmap_regs(struct sym_hcb *np) { int o, i; @@ -1469,61 +1349,61 @@ static void sym_update_dmap_regs(hcb_p np) return; o = offsetof(struct sym_reg, nc_scrx[0]); for (i = 0; i < SYM_DMAP_SIZE; i++) { - OUTL_OFF(o, np->dmap_bah[i]); + OUTL_OFF(np, o, np->dmap_bah[i]); o += 4; } np->dmap_dirty = 0; } #endif -static void sym_check_goals(struct scsi_device *sdev) +/* Enforce all the fiddly SPI rules and the chip limitations */ +static void sym_check_goals(struct sym_hcb *np, struct scsi_target *starget, + struct sym_trans *goal) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_trans *st = &np->target[sdev->id].tinfo.goal; - - /* here we enforce all the fiddly SPI rules */ - - if (!scsi_device_wide(sdev)) - st->width = 0; - - if (!scsi_device_sync(sdev)) { - st->options = 0; - st->period = 0; - st->offset = 0; + if (!spi_support_wide(starget)) + goal->width = 0; + + if (!spi_support_sync(starget)) { + goal->iu = 0; + goal->dt = 0; + goal->qas = 0; + goal->offset = 0; return; } - - if (scsi_device_dt(sdev)) { - if (scsi_device_dt_only(sdev)) - st->options |= PPR_OPT_DT; - if (st->offset == 0) - st->options &= ~PPR_OPT_DT; + if (spi_support_dt(starget)) { + if (spi_support_dt_only(starget)) + goal->dt = 1; + + if (goal->offset == 0) + goal->dt = 0; } else { - st->options &= ~PPR_OPT_DT; + goal->dt = 0; } - if (!(np->features & FE_ULTRA3)) - st->options &= ~PPR_OPT_DT; + /* Some targets fail to properly negotiate DT in SE mode */ + if ((np->scsi_mode != SMODE_LVD) || !(np->features & FE_U3EN)) + goal->dt = 0; - if (st->options & PPR_OPT_DT) { + if (goal->dt) { /* all DT transfers must be wide */ - st->width = 1; - if (st->offset > np->maxoffs_dt) - st->offset = np->maxoffs_dt; - if (st->period < np->minsync_dt) - st->period = np->minsync_dt; - if (st->period > np->maxsync_dt) - st->period = np->maxsync_dt; + goal->width = 1; + if (goal->offset > np->maxoffs_dt) + goal->offset = np->maxoffs_dt; + if (goal->period < np->minsync_dt) + goal->period = np->minsync_dt; + if (goal->period > np->maxsync_dt) + goal->period = np->maxsync_dt; } else { - if (st->offset > np->maxoffs) - st->offset = np->maxoffs; - if (st->period < np->minsync) - st->period = np->minsync; - if (st->period > np->maxsync) - st->period = np->maxsync; + goal->iu = goal->qas = 0; + if (goal->offset > np->maxoffs) + goal->offset = np->maxoffs; + if (goal->period < np->minsync) + goal->period = np->minsync; + if (goal->period > np->maxsync) + goal->period = np->maxsync; } -} +} /* * Prepare the next negotiation message if needed. @@ -1532,65 +1412,49 @@ static void sym_check_goals(struct scsi_device *sdev) * negotiation and the nego_status field of the CCB. * Returns the size of the message in bytes. */ -static int sym_prepare_nego(hcb_p np, ccb_p cp, int nego, u_char *msgptr) +static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgptr) { - tcb_p tp = &np->target[cp->target]; + struct sym_tcb *tp = &np->target[cp->target]; + struct scsi_target *starget = tp->starget; + struct sym_trans *goal = &tp->tgoal; int msglen = 0; - struct scsi_device *sdev = tp->sdev; + int nego; - if (likely(sdev)) - sym_check_goals(sdev); + sym_check_goals(np, starget, goal); /* - * Early C1010 chips need a work-around for DT - * data transfer to work. - */ - if (!(np->features & FE_U3EN)) - tp->tinfo.goal.options = 0; - /* - * negotiate using PPR ? + * Many devices implement PPR in a buggy way, so only use it if we + * really want to. */ - if (scsi_device_dt(sdev)) { + if (goal->offset && + (goal->iu || goal->dt || goal->qas || (goal->period < 0xa))) { nego = NS_PPR; + } else if (spi_width(starget) != goal->width) { + nego = NS_WIDE; + } else if (spi_period(starget) != goal->period || + spi_offset(starget) != goal->offset) { + nego = NS_SYNC; } else { - /* - * negotiate wide transfers ? - */ - if (tp->tinfo.curr.width != tp->tinfo.goal.width) - nego = NS_WIDE; - /* - * negotiate synchronous transfers? - */ - else if (tp->tinfo.curr.period != tp->tinfo.goal.period || - tp->tinfo.curr.offset != tp->tinfo.goal.offset) - nego = NS_SYNC; + goal->check_nego = 0; + nego = 0; } switch (nego) { case NS_SYNC: - msgptr[msglen++] = M_EXTENDED; - msgptr[msglen++] = 3; - msgptr[msglen++] = M_X_SYNC_REQ; - msgptr[msglen++] = tp->tinfo.goal.period; - msgptr[msglen++] = tp->tinfo.goal.offset; + msglen += spi_populate_sync_msg(msgptr + msglen, goal->period, + goal->offset); break; case NS_WIDE: - msgptr[msglen++] = M_EXTENDED; - msgptr[msglen++] = 2; - msgptr[msglen++] = M_X_WIDE_REQ; - msgptr[msglen++] = tp->tinfo.goal.width; + msglen += spi_populate_width_msg(msgptr + msglen, goal->width); break; case NS_PPR: - msgptr[msglen++] = M_EXTENDED; - msgptr[msglen++] = 6; - msgptr[msglen++] = M_X_PPR_REQ; - msgptr[msglen++] = tp->tinfo.goal.period; - msgptr[msglen++] = 0; - msgptr[msglen++] = tp->tinfo.goal.offset; - msgptr[msglen++] = tp->tinfo.goal.width; - msgptr[msglen++] = tp->tinfo.goal.options & PPR_OPT_DT; + msglen += spi_populate_ppr_msg(msgptr + msglen, goal->period, + goal->offset, goal->width, + (goal->iu ? PPR_OPT_IU : 0) | + (goal->dt ? PPR_OPT_DT : 0) | + (goal->qas ? PPR_OPT_QAS : 0)); break; - }; + } cp->nego_status = nego; @@ -1601,8 +1465,8 @@ static int sym_prepare_nego(hcb_p np, ccb_p cp, int nego, u_char *msgptr) nego == NS_SYNC ? "sync msgout" : nego == NS_WIDE ? "wide msgout" : "ppr msgout", msgptr); - }; - }; + } + } return msglen; } @@ -1610,7 +1474,7 @@ static int sym_prepare_nego(hcb_p np, ccb_p cp, int nego, u_char *msgptr) /* * Insert a job into the start queue. */ -void sym_put_start_queue(hcb_p np, ccb_p cp) +void sym_put_start_queue(struct sym_hcb *np, struct sym_ccb *cp) { u_short qidx; @@ -1641,13 +1505,6 @@ void sym_put_start_queue(hcb_p np, ccb_p cp) cp->host_xflags |= HX_DMAP_DIRTY; #endif - /* - * Optionnaly, set the IO timeout condition. - */ -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - sym_timeout_ccb(np, cp, sym_cam_timeout(cp->cam_ccb)); -#endif - /* * Insert first the idle task and then our job. * The MBs should ensure proper ordering. @@ -1669,17 +1526,17 @@ void sym_put_start_queue(hcb_p np, ccb_p cp) * Wake it up. */ MEMORY_WRITE_BARRIER(); - OUTB (nc_istat, SIGP|np->istat_sem); + OUTB(np, nc_istat, SIGP|np->istat_sem); } #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING /* * Start next ready-to-start CCBs. */ -void sym_start_next_ccbs(hcb_p np, lcb_p lp, int maxn) +void sym_start_next_ccbs(struct sym_hcb *np, struct sym_lcb *lp, int maxn) { SYM_QUEHEAD *qp; - ccb_p cp; + struct sym_ccb *cp; /* * Paranoia, as usual. :-) @@ -1704,7 +1561,7 @@ void sym_start_next_ccbs(hcb_p np, lcb_p lp, int maxn) } lp->itlq_tbl[cp->tag] = cpu_to_scr(cp->ccb_ba); lp->head.resel_sa = - cpu_to_scr(SCRIPTA_BA (np, resel_tag)); + cpu_to_scr(SCRIPTA_BA(np, resel_tag)); ++lp->started_tags; } else { if (lp->started_no_tag || lp->started_tags) { @@ -1713,7 +1570,7 @@ void sym_start_next_ccbs(hcb_p np, lcb_p lp, int maxn) } lp->head.itl_task_sa = cpu_to_scr(cp->ccb_ba); lp->head.resel_sa = - cpu_to_scr(SCRIPTA_BA (np, resel_no_tag)); + cpu_to_scr(SCRIPTA_BA(np, resel_no_tag)); ++lp->started_no_tag; } cp->started = 1; @@ -1730,9 +1587,9 @@ void sym_start_next_ccbs(hcb_p np, lcb_p lp, int maxn) * prevent out of order LOADs by the CPU from having * prefetched stale data prior to DMA having occurred. */ -static int sym_wakeup_done (hcb_p np) +static int sym_wakeup_done (struct sym_hcb *np) { - ccb_p cp; + struct sym_ccb *cp; int i, n; u32 dsa; @@ -1763,11 +1620,64 @@ static int sym_wakeup_done (hcb_p np) return n; } +/* + * Complete all CCBs queued to the COMP queue. + * + * These CCBs are assumed: + * - Not to be referenced either by devices or + * SCRIPTS-related queues and datas. + * - To have to be completed with an error condition + * or requeued. + * + * The device queue freeze count is incremented + * for each CCB that does not prevent this. + * This function is called when all CCBs involved + * in error handling/recovery have been reaped. + */ +static void sym_flush_comp_queue(struct sym_hcb *np, int cam_status) +{ + SYM_QUEHEAD *qp; + struct sym_ccb *cp; + + while ((qp = sym_remque_head(&np->comp_ccbq)) != 0) { + struct scsi_cmnd *cmd; + cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); + sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq); + /* Leave quiet CCBs waiting for resources */ + if (cp->host_status == HS_WAIT) + continue; + cmd = cp->cmd; + if (cam_status) + sym_set_cam_status(cmd, cam_status); +#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING + if (sym_get_cam_status(cmd) == DID_SOFT_ERROR) { + struct sym_tcb *tp = &np->target[cp->target]; + struct sym_lcb *lp = sym_lp(tp, cp->lun); + if (lp) { + sym_remque(&cp->link2_ccbq); + sym_insque_tail(&cp->link2_ccbq, + &lp->waiting_ccbq); + if (cp->started) { + if (cp->tag != NO_TAG) + --lp->started_tags; + else + --lp->started_no_tag; + } + } + cp->started = 0; + continue; + } +#endif + sym_free_ccb(np, cp); + sym_xpt_done(np, cmd); + } +} + /* * Complete all active CCBs with error. * Used on CHIP/SCSI RESET. */ -static void sym_flush_busy_queue (hcb_p np, int cam_status) +static void sym_flush_busy_queue (struct sym_hcb *np, int cam_status) { /* * Move all active CCBs to the COMP queue @@ -1786,7 +1696,7 @@ static void sym_flush_busy_queue (hcb_p np, int cam_status) * 1: SCSI BUS RESET delivered or received. * 2: SCSI BUS MODE changed. */ -void sym_start_up (hcb_p np, int reason) +void sym_start_up (struct sym_hcb *np, int reason) { int i; u32 phys; @@ -1797,8 +1707,8 @@ void sym_start_up (hcb_p np, int reason) if (reason == 1) sym_soft_reset(np); else { - OUTB (nc_stest3, TE|CSF); - OUTONB (nc_ctest3, CLF); + OUTB(np, nc_stest3, TE|CSF); + OUTONB(np, nc_ctest3, CLF); } /* @@ -1841,44 +1751,45 @@ void sym_start_up (hcb_p np, int reason) /* * Wakeup all pending jobs. */ - sym_flush_busy_queue(np, CAM_SCSI_BUS_RESET); + sym_flush_busy_queue(np, DID_RESET); /* * Init chip. */ - OUTB (nc_istat, 0x00 ); /* Remove Reset, abort */ - UDELAY (2000); /* The 895 needs time for the bus mode to settle */ + OUTB(np, nc_istat, 0x00); /* Remove Reset, abort */ + INB(np, nc_mbox1); + udelay(2000); /* The 895 needs time for the bus mode to settle */ - OUTB (nc_scntl0, np->rv_scntl0 | 0xc0); + OUTB(np, nc_scntl0, np->rv_scntl0 | 0xc0); /* full arb., ena parity, par->ATN */ - OUTB (nc_scntl1, 0x00); /* odd parity, and remove CRST!! */ + OUTB(np, nc_scntl1, 0x00); /* odd parity, and remove CRST!! */ sym_selectclock(np, np->rv_scntl3); /* Select SCSI clock */ - OUTB (nc_scid , RRE|np->myaddr); /* Adapter SCSI address */ - OUTW (nc_respid, 1ul<myaddr); /* Id to respond to */ - OUTB (nc_istat , SIGP ); /* Signal Process */ - OUTB (nc_dmode , np->rv_dmode); /* Burst length, dma mode */ - OUTB (nc_ctest5, np->rv_ctest5); /* Large fifo + large burst */ + OUTB(np, nc_scid , RRE|np->myaddr); /* Adapter SCSI address */ + OUTW(np, nc_respid, 1ul<myaddr); /* Id to respond to */ + OUTB(np, nc_istat , SIGP ); /* Signal Process */ + OUTB(np, nc_dmode , np->rv_dmode); /* Burst length, dma mode */ + OUTB(np, nc_ctest5, np->rv_ctest5); /* Large fifo + large burst */ - OUTB (nc_dcntl , NOCOM|np->rv_dcntl); /* Protect SFBR */ - OUTB (nc_ctest3, np->rv_ctest3); /* Write and invalidate */ - OUTB (nc_ctest4, np->rv_ctest4); /* Master parity checking */ + OUTB(np, nc_dcntl , NOCOM|np->rv_dcntl); /* Protect SFBR */ + OUTB(np, nc_ctest3, np->rv_ctest3); /* Write and invalidate */ + OUTB(np, nc_ctest4, np->rv_ctest4); /* Master parity checking */ /* Extended Sreq/Sack filtering not supported on the C10 */ if (np->features & FE_C10) - OUTB (nc_stest2, np->rv_stest2); + OUTB(np, nc_stest2, np->rv_stest2); else - OUTB (nc_stest2, EXT|np->rv_stest2); + OUTB(np, nc_stest2, EXT|np->rv_stest2); - OUTB (nc_stest3, TE); /* TolerANT enable */ - OUTB (nc_stime0, 0x0c); /* HTH disabled STO 0.25 sec */ + OUTB(np, nc_stest3, TE); /* TolerANT enable */ + OUTB(np, nc_stime0, 0x0c); /* HTH disabled STO 0.25 sec */ /* * For now, disable AIP generation on C1010-66. */ - if (np->device_id == PCI_ID_LSI53C1010_66) - OUTB (nc_aipcntl1, DISAIP); + if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66) + OUTB(np, nc_aipcntl1, DISAIP); /* * C10101 rev. 0 errata. @@ -1887,18 +1798,18 @@ void sym_start_up (hcb_p np, int reason) * that from SCRIPTS for each selection/reselection, but * I just don't want. :) */ - if (np->device_id == PCI_ID_LSI53C1010_33 && + if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_33 && np->revision_id < 1) - OUTB (nc_stest1, INB(nc_stest1) | 0x30); + OUTB(np, nc_stest1, INB(np, nc_stest1) | 0x30); /* * DEL 441 - 53C876 Rev 5 - Part Number 609-0392787/2788 - ITEM 2. * Disable overlapped arbitration for some dual function devices, * regardless revision id (kind of post-chip-design feature. ;-)) */ - if (np->device_id == PCI_ID_SYM53C875) - OUTB (nc_ctest0, (1<<5)); - else if (np->device_id == PCI_ID_SYM53C896) + if (np->device_id == PCI_DEVICE_ID_NCR_53C875) + OUTB(np, nc_ctest0, (1<<5)); + else if (np->device_id == PCI_DEVICE_ID_NCR_53C896) np->rv_ccntl0 |= DPR; /* @@ -1907,8 +1818,8 @@ void sym_start_up (hcb_p np, int reason) * seem to support those IO registers. */ if (np->features & (FE_DAC|FE_NOPM)) { - OUTB (nc_ccntl0, np->rv_ccntl0); - OUTB (nc_ccntl1, np->rv_ccntl1); + OUTB(np, nc_ccntl0, np->rv_ccntl0); + OUTB(np, nc_ccntl1, np->rv_ccntl1); } #if SYM_CONF_DMA_ADDRESSING_MODE == 2 @@ -1918,8 +1829,8 @@ void sym_start_up (hcb_p np, int reason) */ if (np->use_dac) { np->dmap_bah[0] = 0; /* ??? */ - OUTL (nc_scrx[0], np->dmap_bah[0]); - OUTL (nc_drs, np->dmap_bah[0]); + OUTL(np, nc_scrx[0], np->dmap_bah[0]); + OUTL(np, nc_drs, np->dmap_bah[0]); } #endif @@ -1928,8 +1839,8 @@ void sym_start_up (hcb_p np, int reason) * set PM jump addresses. */ if (np->features & FE_NOPM) { - OUTL (nc_pmjad1, SCRIPTB_BA (np, pm_handle)); - OUTL (nc_pmjad2, SCRIPTB_BA (np, pm_handle)); + OUTL(np, nc_pmjad1, SCRIPTB_BA(np, pm_handle)); + OUTL(np, nc_pmjad2, SCRIPTB_BA(np, pm_handle)); } /* @@ -1937,15 +1848,15 @@ void sym_start_up (hcb_p np, int reason) * Also set GPIO5 and clear GPIO6 if hardware LED control. */ if (np->features & FE_LED0) - OUTB(nc_gpcntl, INB(nc_gpcntl) & ~0x01); + OUTB(np, nc_gpcntl, INB(np, nc_gpcntl) & ~0x01); else if (np->features & FE_LEDC) - OUTB(nc_gpcntl, (INB(nc_gpcntl) & ~0x41) | 0x20); + OUTB(np, nc_gpcntl, (INB(np, nc_gpcntl) & ~0x41) | 0x20); /* * enable ints */ - OUTW (nc_sien , STO|HTH|MA|SGE|UDC|RST|PAR); - OUTB (nc_dien , MDPE|BF|SSI|SIR|IID); + OUTW(np, nc_sien , STO|HTH|MA|SGE|UDC|RST|PAR); + OUTB(np, nc_dien , MDPE|BF|SSI|SIR|IID); /* * For 895/6 enable SBMC interrupt and save current SCSI bus mode. @@ -1953,12 +1864,13 @@ void sym_start_up (hcb_p np, int reason) * we reset the chip but not the SCSI BUS (at initialization). */ if (np->features & (FE_ULTRA2|FE_ULTRA3)) { - OUTONW (nc_sien, SBMC); + OUTONW(np, nc_sien, SBMC); if (reason == 0) { - MDELAY(100); - INW (nc_sist); + INB(np, nc_mbox1); + mdelay(100); + INW(np, nc_sist); } - np->scsi_mode = INB (nc_stest4) & SMODE; + np->scsi_mode = INB(np, nc_stest4) & SMODE; } /* @@ -1968,17 +1880,12 @@ void sym_start_up (hcb_p np, int reason) * Prepare sync negotiation according to actual SCSI bus mode. */ for (i=0;itarget[i]; + struct sym_tcb *tp = &np->target[i]; tp->to_reset = 0; tp->head.sval = 0; tp->head.wval = np->rv_scntl3; tp->head.uval = 0; - - tp->tinfo.curr.period = 0; - tp->tinfo.curr.offset = 0; - tp->tinfo.curr.width = BUS_8_BIT; - tp->tinfo.curr.options = 0; } /* @@ -1988,29 +1895,25 @@ void sym_start_up (hcb_p np, int reason) * For platforms that may not support PCI memory mapping, * we use simple SCRIPTS that performs MEMORY MOVEs. */ + phys = SCRIPTA_BA(np, init); if (np->ram_ba) { if (sym_verbose >= 2) - printf ("%s: Downloading SCSI SCRIPTS.\n", - sym_name(np)); + printf("%s: Downloading SCSI SCRIPTS.\n", sym_name(np)); + memcpy_toio(np->s.ramaddr, np->scripta0, np->scripta_sz); if (np->ram_ws == 8192) { - OUTRAM_OFF(4096, np->scriptb0, np->scriptb_sz); - phys = scr_to_cpu(np->scr_ram_seg); - OUTL (nc_mmws, phys); - OUTL (nc_mmrs, phys); - OUTL (nc_sfs, phys); - phys = SCRIPTB_BA (np, start64); + memcpy_toio(np->s.ramaddr + 4096, np->scriptb0, np->scriptb_sz); + phys = scr_to_cpu(np->scr_ram_seg); + OUTL(np, nc_mmws, phys); + OUTL(np, nc_mmrs, phys); + OUTL(np, nc_sfs, phys); + phys = SCRIPTB_BA(np, start64); } - else - phys = SCRIPTA_BA (np, init); - OUTRAM_OFF(0, np->scripta0, np->scripta_sz); } - else - phys = SCRIPTA_BA (np, init); np->istat_sem = 0; - OUTL (nc_dsa, np->hcb_ba); - OUTL_DSP (phys); + OUTL(np, nc_dsa, np->hcb_ba); + OUTL_DSP(np, phys); /* * Notify the XPT about the RESET condition. @@ -2020,16 +1923,16 @@ void sym_start_up (hcb_p np, int reason) } /* - * Switch trans mode for current job and it's target. + * Switch trans mode for current job and its target. */ -static void sym_settrans(hcb_p np, int target, u_char dt, u_char ofs, +static void sym_settrans(struct sym_hcb *np, int target, u_char opts, u_char ofs, u_char per, u_char wide, u_char div, u_char fak) { SYM_QUEHEAD *qp; u_char sval, wval, uval; - tcb_p tp = &np->target[target]; + struct sym_tcb *tp = &np->target[target]; - assert(target == (INB (nc_sdid) & 0x0f)); + assert(target == (INB(np, nc_sdid) & 0x0f)); sval = tp->head.sval; wval = tp->head.wval; @@ -2073,12 +1976,11 @@ static void sym_settrans(hcb_p np, int target, u_char dt, u_char ofs, */ if (np->features & FE_C10) { uval = uval & ~(U3EN|AIPCKEN); - if (dt) { + if (opts) { assert(np->features & FE_U3EN); uval |= U3EN; } - } - else { + } else { wval = wval & ~ULTRA; if (per <= 12) wval |= ULTRA; } @@ -2099,23 +2001,23 @@ static void sym_settrans(hcb_p np, int target, u_char dt, u_char ofs, * Not supported on the C1010. */ if (per < 50 && !(np->features & FE_C10)) - OUTOFFB (nc_stest2, EXT); + OUTOFFB(np, nc_stest2, EXT); /* * set actual value and sync_status */ - OUTB (nc_sxfer, tp->head.sval); - OUTB (nc_scntl3, tp->head.wval); + OUTB(np, nc_sxfer, tp->head.sval); + OUTB(np, nc_scntl3, tp->head.wval); if (np->features & FE_C10) { - OUTB (nc_scntl4, tp->head.uval); + OUTB(np, nc_scntl4, tp->head.uval); } /* * patch ALL busy ccbs of this target. */ FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { - ccb_p cp; + struct sym_ccb *cp; cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); if (cp->target != target) continue; @@ -2131,18 +2033,26 @@ static void sym_settrans(hcb_p np, int target, u_char dt, u_char ofs, * We received a WDTR. * Let everything be aware of the changes. */ -static void sym_setwide(hcb_p np, int target, u_char wide) +static void sym_setwide(struct sym_hcb *np, int target, u_char wide) { - tcb_p tp = &np->target[target]; + struct sym_tcb *tp = &np->target[target]; + struct scsi_target *starget = tp->starget; + + if (spi_width(starget) == wide) + return; sym_settrans(np, target, 0, 0, 0, wide, 0, 0); - tp->tinfo.goal.width = tp->tinfo.curr.width = wide; - tp->tinfo.curr.offset = 0; - tp->tinfo.curr.period = 0; - tp->tinfo.curr.options = 0; + tp->tgoal.width = wide; + spi_offset(starget) = 0; + spi_period(starget) = 0; + spi_width(starget) = wide; + spi_iu(starget) = 0; + spi_dt(starget) = 0; + spi_qas(starget) = 0; - sym_xpt_async_nego_wide(np, target); + if (sym_verbose >= 3) + spi_display_xfer_agreement(starget); } /* @@ -2150,25 +2060,26 @@ static void sym_setwide(hcb_p np, int target, u_char wide) * Let everything be aware of the changes. */ static void -sym_setsync(hcb_p np, int target, +sym_setsync(struct sym_hcb *np, int target, u_char ofs, u_char per, u_char div, u_char fak) { - tcb_p tp = &np->target[target]; + struct sym_tcb *tp = &np->target[target]; + struct scsi_target *starget = tp->starget; u_char wide = (tp->head.wval & EWS) ? BUS_16_BIT : BUS_8_BIT; sym_settrans(np, target, 0, ofs, per, wide, div, fak); - tp->tinfo.curr.period = per; - tp->tinfo.curr.offset = ofs; - tp->tinfo.curr.options = 0; + spi_period(starget) = per; + spi_offset(starget) = ofs; + spi_iu(starget) = spi_dt(starget) = spi_qas(starget) = 0; - if (!(tp->tinfo.goal.options & PPR_OPT_MASK)) { - tp->tinfo.goal.period = per; - tp->tinfo.goal.offset = ofs; - tp->tinfo.goal.options = 0; + if (!tp->tgoal.dt && !tp->tgoal.iu && !tp->tgoal.qas) { + tp->tgoal.period = per; + tp->tgoal.offset = ofs; + tp->tgoal.check_nego = 0; } - sym_xpt_async_nego_sync(np, target); + spi_display_xfer_agreement(starget); } /* @@ -2176,19 +2087,23 @@ sym_setsync(hcb_p np, int target, * Let everything be aware of the changes. */ static void -sym_setpprot(hcb_p np, int target, u_char dt, u_char ofs, +sym_setpprot(struct sym_hcb *np, int target, u_char opts, u_char ofs, u_char per, u_char wide, u_char div, u_char fak) { - tcb_p tp = &np->target[target]; + struct sym_tcb *tp = &np->target[target]; + struct scsi_target *starget = tp->starget; - sym_settrans(np, target, dt, ofs, per, wide, div, fak); + sym_settrans(np, target, opts, ofs, per, wide, div, fak); - tp->tinfo.goal.width = tp->tinfo.curr.width = wide; - tp->tinfo.goal.period = tp->tinfo.curr.period = per; - tp->tinfo.goal.offset = tp->tinfo.curr.offset = ofs; - tp->tinfo.goal.options = tp->tinfo.curr.options = dt; + spi_width(starget) = tp->tgoal.width = wide; + spi_period(starget) = tp->tgoal.period = per; + spi_offset(starget) = tp->tgoal.offset = ofs; + spi_iu(starget) = tp->tgoal.iu = !!(opts & PPR_OPT_IU); + spi_dt(starget) = tp->tgoal.dt = !!(opts & PPR_OPT_DT); + spi_qas(starget) = tp->tgoal.qas = !!(opts & PPR_OPT_QAS); + tp->tgoal.check_nego = 0; - sym_xpt_async_nego_ppr(np, target); + spi_display_xfer_agreement(starget); } /* @@ -2217,27 +2132,27 @@ sym_setpprot(hcb_p np, int target, u_char dt, u_char ofs, * pushes a DSA into a queue, we can trust it when it * points to a CCB. */ -static void sym_recover_scsi_int (hcb_p np, u_char hsts) +static void sym_recover_scsi_int (struct sym_hcb *np, u_char hsts) { - u32 dsp = INL (nc_dsp); - u32 dsa = INL (nc_dsa); - ccb_p cp = sym_ccb_from_dsa(np, dsa); + u32 dsp = INL(np, nc_dsp); + u32 dsa = INL(np, nc_dsa); + struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa); /* * If we haven't been interrupted inside the SCRIPTS * critical pathes, we can safely restart the SCRIPTS * and trust the DSA value if it matches a CCB. */ - if ((!(dsp > SCRIPTA_BA (np, getjob_begin) && - dsp < SCRIPTA_BA (np, getjob_end) + 1)) && - (!(dsp > SCRIPTA_BA (np, ungetjob) && - dsp < SCRIPTA_BA (np, reselect) + 1)) && - (!(dsp > SCRIPTB_BA (np, sel_for_abort) && - dsp < SCRIPTB_BA (np, sel_for_abort_1) + 1)) && - (!(dsp > SCRIPTA_BA (np, done) && - dsp < SCRIPTA_BA (np, done_end) + 1))) { - OUTB (nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ - OUTB (nc_stest3, TE|CSF); /* clear scsi fifo */ + if ((!(dsp > SCRIPTA_BA(np, getjob_begin) && + dsp < SCRIPTA_BA(np, getjob_end) + 1)) && + (!(dsp > SCRIPTA_BA(np, ungetjob) && + dsp < SCRIPTA_BA(np, reselect) + 1)) && + (!(dsp > SCRIPTB_BA(np, sel_for_abort) && + dsp < SCRIPTB_BA(np, sel_for_abort_1) + 1)) && + (!(dsp > SCRIPTA_BA(np, done) && + dsp < SCRIPTA_BA(np, done_end) + 1))) { + OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ + OUTB(np, nc_stest3, TE|CSF); /* clear scsi fifo */ /* * If we have a CCB, let the SCRIPTS call us back for * the handling of the error with SCRATCHA filled with @@ -2246,14 +2161,14 @@ static void sym_recover_scsi_int (hcb_p np, u_char hsts) */ if (cp) { cp->host_status = hsts; - OUTL_DSP (SCRIPTA_BA (np, complete_error)); + OUTL_DSP(np, SCRIPTA_BA(np, complete_error)); } /* * Otherwise just restart the SCRIPTS. */ else { - OUTL (nc_dsa, 0xffffff); - OUTL_DSP (SCRIPTA_BA (np, start)); + OUTL(np, nc_dsa, 0xffffff); + OUTL_DSP(np, SCRIPTA_BA(np, start)); } } else @@ -2268,13 +2183,13 @@ reset_all: /* * chip exception handler for selection timeout */ -static void sym_int_sto (hcb_p np) +static void sym_int_sto (struct sym_hcb *np) { - u32 dsp = INL (nc_dsp); + u32 dsp = INL(np, nc_dsp); if (DEBUG_FLAGS & DEBUG_TINY) printf ("T"); - if (dsp == SCRIPTA_BA (np, wf_sel_done) + 8) + if (dsp == SCRIPTA_BA(np, wf_sel_done) + 8) sym_recover_scsi_int(np, HS_SEL_TIMEOUT); else sym_start_reset(np); @@ -2283,7 +2198,7 @@ static void sym_int_sto (hcb_p np) /* * chip exception handler for unexpected disconnect */ -static void sym_int_udc (hcb_p np) +static void sym_int_udc (struct sym_hcb *np) { printf ("%s: unexpected disconnect\n", sym_name(np)); sym_recover_scsi_int(np, HS_UNEXPECTED); @@ -2299,9 +2214,9 @@ static void sym_int_udc (hcb_p np) * mode to eight bit asynchronous, etc... * So, just reinitializing all except chip should be enough. */ -static void sym_int_sbmc (hcb_p np) +static void sym_int_sbmc (struct sym_hcb *np) { - u_char scsi_mode = INB (nc_stest4) & SMODE; + u_char scsi_mode = INB(np, nc_stest4) & SMODE; /* * Notify user. @@ -2340,16 +2255,16 @@ static void sym_int_sbmc (hcb_p np) * The chip will load the DSP with the phase mismatch * JUMP address and interrupt the host processor. */ -static void sym_int_par (hcb_p np, u_short sist) +static void sym_int_par (struct sym_hcb *np, u_short sist) { - u_char hsts = INB (HS_PRT); - u32 dsp = INL (nc_dsp); - u32 dbc = INL (nc_dbc); - u32 dsa = INL (nc_dsa); - u_char sbcl = INB (nc_sbcl); + u_char hsts = INB(np, HS_PRT); + u32 dsp = INL(np, nc_dsp); + u32 dbc = INL(np, nc_dbc); + u32 dsa = INL(np, nc_dsa); + u_char sbcl = INB(np, nc_sbcl); u_char cmd = dbc >> 24; int phase = cmd & 7; - ccb_p cp = sym_ccb_from_dsa(np, dsa); + struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa); printf("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n", sym_name(np), hsts, dbc, sbcl); @@ -2357,7 +2272,7 @@ static void sym_int_par (hcb_p np, u_short sist) /* * Check that the chip is connected to the SCSI BUS. */ - if (!(INB (nc_scntl1) & ISCON)) { + if (!(INB(np, nc_scntl1) & ISCON)) { sym_recover_scsi_int(np, HS_UNEXPECTED); return; } @@ -2379,7 +2294,7 @@ static void sym_int_par (hcb_p np, u_short sist) /* * Keep track of the parity error. */ - OUTONB (HF_PRT, HF_EXT_ERR); + OUTONB(np, HF_PRT, HF_EXT_ERR); cp->xerr_status |= XE_PARITY_ERR; /* @@ -2396,25 +2311,25 @@ static void sym_int_par (hcb_p np, u_short sist) */ if (phase == 1 || phase == 5) { /* Phase mismatch handled by SCRIPTS */ - if (dsp == SCRIPTB_BA (np, pm_handle)) - OUTL_DSP (dsp); + if (dsp == SCRIPTB_BA(np, pm_handle)) + OUTL_DSP(np, dsp); /* Phase mismatch handled by the C code */ else if (sist & MA) sym_int_ma (np); /* No phase mismatch occurred */ else { sym_set_script_dp (np, cp, dsp); - OUTL_DSP (SCRIPTA_BA (np, dispatch)); + OUTL_DSP(np, SCRIPTA_BA(np, dispatch)); } } else if (phase == 7) /* We definitely cannot handle parity errors */ #if 1 /* in message-in phase due to the relection */ goto reset_all; /* path and various message anticipations. */ #else - OUTL_DSP (SCRIPTA_BA (np, clrack)); + OUTL_DSP(np, SCRIPTA_BA(np, clrack)); #endif else - OUTL_DSP (SCRIPTA_BA (np, dispatch)); + OUTL_DSP(np, SCRIPTA_BA(np, dispatch)); return; reset_all: @@ -2428,7 +2343,7 @@ reset_all: * We have to construct a new transfer descriptor, * to transfer the rest of the current block. */ -static void sym_int_ma (hcb_p np) +static void sym_int_ma (struct sym_hcb *np) { u32 dbc; u32 rest; @@ -2443,11 +2358,11 @@ static void sym_int_ma (hcb_p np) u_char cmd; u_char hflags, hflags0; struct sym_pmc *pm; - ccb_p cp; + struct sym_ccb *cp; - dsp = INL (nc_dsp); - dbc = INL (nc_dbc); - dsa = INL (nc_dsa); + dsp = INL(np, nc_dsp); + dbc = INL(np, nc_dbc); + dsa = INL(np, nc_dsa); cmd = dbc >> 24; rest = dbc & 0xffffff; @@ -2468,14 +2383,14 @@ static void sym_int_ma (hcb_p np) u_char ss0, ss2; if (np->features & FE_DFBC) - delta = INW (nc_dfbc); + delta = INW(np, nc_dfbc); else { u32 dfifo; /* * Read DFIFO, CTEST[4-6] using 1 PCI bus ownership. */ - dfifo = INL(nc_dfifo); + dfifo = INL(np, nc_dfifo); /* * Calculate remaining bytes in DMA fifo. @@ -2495,29 +2410,29 @@ static void sym_int_ma (hcb_p np) * Check the sstat2 register in case of wide transfer. */ rest += delta; - ss0 = INB (nc_sstat0); + ss0 = INB(np, nc_sstat0); if (ss0 & OLF) rest++; if (!(np->features & FE_C10)) if (ss0 & ORF) rest++; if (cp && (cp->phys.select.sel_scntl3 & EWS)) { - ss2 = INB (nc_sstat2); + ss2 = INB(np, nc_sstat2); if (ss2 & OLF1) rest++; if (!(np->features & FE_C10)) if (ss2 & ORF1) rest++; - }; + } /* * Clear fifos. */ - OUTB (nc_ctest3, np->rv_ctest3 | CLF); /* dma fifo */ - OUTB (nc_stest3, TE|CSF); /* scsi fifo */ + OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* dma fifo */ + OUTB(np, nc_stest3, TE|CSF); /* scsi fifo */ } /* * log the information */ if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_PHASE)) - printf ("P%x%x RL=%d D=%d ", cmd&7, INB(nc_sbcl)&7, + printf ("P%x%x RL=%d D=%d ", cmd&7, INB(np, nc_sbcl)&7, (unsigned) rest, (unsigned) delta); /* @@ -2543,7 +2458,7 @@ static void sym_int_ma (hcb_p np) if (DEBUG_FLAGS & DEBUG_PHASE) { printf ("\nCP=%p DSP=%x NXT=%x VDSP=%p CMD=%x ", cp, (unsigned)dsp, (unsigned)nxtdsp, vdsp, cmd); - }; + } if (!vdsp) { printf ("%s: interrupted SCRIPT address not found.\n", @@ -2569,7 +2484,7 @@ static void sym_int_ma (hcb_p np) } else { tblp = (u32 *) 0; olen = scr_to_cpu(vdsp[0]) & 0xffffff; - }; + } if (DEBUG_FLAGS & DEBUG_PHASE) { printf ("OCMD=%x\nTBLP=%p OLEN=%x OADR=%x\n", @@ -2577,7 +2492,7 @@ static void sym_int_ma (hcb_p np) tblp, (unsigned) olen, (unsigned) oadr); - }; + } /* * check cmd against assumed interrupted script command. @@ -2585,23 +2500,23 @@ static void sym_int_ma (hcb_p np) * the phase. */ if (((cmd & 2) ? cmd : (cmd & ~4)) != (scr_to_cpu(vdsp[0]) >> 24)) { - PRINT_ADDR(cp); - printf ("internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n", - (unsigned)cmd, (unsigned)scr_to_cpu(vdsp[0]) >> 24); + sym_print_addr(cp->cmd, + "internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n", + cmd, scr_to_cpu(vdsp[0]) >> 24); goto reset_all; - }; + } /* * if old phase not dataphase, leave here. */ if (cmd & 2) { - PRINT_ADDR(cp); - printf ("phase change %x-%x %d@%08x resid=%d.\n", - cmd&7, INB(nc_sbcl)&7, (unsigned)olen, + sym_print_addr(cp->cmd, + "phase change %x-%x %d@%08x resid=%d.\n", + cmd&7, INB(np, nc_sbcl)&7, (unsigned)olen, (unsigned)oadr, (unsigned)rest); goto unexpected_phase; - }; + } /* * Choose the correct PM save area. @@ -2611,7 +2526,7 @@ static void sym_int_ma (hcb_p np) * SCRIPTS for the 895A, 896 and 1010 that are able to * handle PM from the SCRIPTS processor. */ - hflags0 = INB (HF_PRT); + hflags0 = INB(np, HF_PRT); hflags = hflags0; if (hflags & (HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED)) { @@ -2626,16 +2541,16 @@ static void sym_int_ma (hcb_p np) if (!(hflags & HF_ACT_PM)) { pm = &cp->phys.pm0; - newcmd = SCRIPTA_BA (np, pm0_data); + newcmd = SCRIPTA_BA(np, pm0_data); } else { pm = &cp->phys.pm1; - newcmd = SCRIPTA_BA (np, pm1_data); + newcmd = SCRIPTA_BA(np, pm1_data); } hflags &= ~(HF_IN_PM0 | HF_IN_PM1 | HF_DP_SAVED); if (hflags != hflags0) - OUTB (HF_PRT, hflags); + OUTB(np, HF_PRT, hflags); /* * fillin the phase mismatch context @@ -2650,9 +2565,9 @@ static void sym_int_ma (hcb_p np) * - compute the SCRIPTS address to restart from, * - move current data pointer context by one byte. */ - nxtdsp = SCRIPTA_BA (np, dispatch); + nxtdsp = SCRIPTA_BA(np, dispatch); if ((cmd & 7) == 1 && cp && (cp->phys.select.sel_scntl3 & EWS) && - (INB (nc_scntl2) & WSR)) { + (INB(np, nc_scntl2) & WSR)) { u32 tmp; /* @@ -2678,12 +2593,11 @@ static void sym_int_ma (hcb_p np) * Prepare the address of SCRIPTS that will * move the residual byte to memory. */ - nxtdsp = SCRIPTB_BA (np, wsr_ma_helper); + nxtdsp = SCRIPTB_BA(np, wsr_ma_helper); } if (DEBUG_FLAGS & DEBUG_PHASE) { - PRINT_ADDR(cp); - printf ("PM %x %x %x / %x %x %x.\n", + sym_print_addr(cp->cmd, "PM %x %x %x / %x %x %x.\n", hflags0, hflags, newcmd, (unsigned)scr_to_cpu(pm->sg.addr), (unsigned)scr_to_cpu(pm->sg.size), @@ -2694,7 +2608,7 @@ static void sym_int_ma (hcb_p np) * Restart the SCRIPTS processor. */ sym_set_script_dp (np, cp, newcmd); - OUTL_DSP (nxtdsp); + OUTL_DSP(np, nxtdsp); return; /* @@ -2730,11 +2644,11 @@ unexpected_phase: switch (cmd & 7) { case 2: /* COMMAND phase */ - nxtdsp = SCRIPTA_BA (np, dispatch); + nxtdsp = SCRIPTA_BA(np, dispatch); break; #if 0 case 3: /* STATUS phase */ - nxtdsp = SCRIPTA_BA (np, dispatch); + nxtdsp = SCRIPTA_BA(np, dispatch); break; #endif case 6: /* MSG OUT phase */ @@ -2744,30 +2658,34 @@ unexpected_phase: * since we will not be able to handle reselect. * Otherwise, we just don't care. */ - if (dsp == SCRIPTA_BA (np, send_ident)) { + if (dsp == SCRIPTA_BA(np, send_ident)) { if (cp->tag != NO_TAG && olen - rest <= 3) { cp->host_status = HS_BUSY; - np->msgout[0] = M_IDENTIFY | cp->lun; - nxtdsp = SCRIPTB_BA (np, ident_break_atn); + np->msgout[0] = IDENTIFY(0, cp->lun); + nxtdsp = SCRIPTB_BA(np, ident_break_atn); } else - nxtdsp = SCRIPTB_BA (np, ident_break); + nxtdsp = SCRIPTB_BA(np, ident_break); } - else if (dsp == SCRIPTB_BA (np, send_wdtr) || - dsp == SCRIPTB_BA (np, send_sdtr) || - dsp == SCRIPTB_BA (np, send_ppr)) { - nxtdsp = SCRIPTB_BA (np, nego_bad_phase); + else if (dsp == SCRIPTB_BA(np, send_wdtr) || + dsp == SCRIPTB_BA(np, send_sdtr) || + dsp == SCRIPTB_BA(np, send_ppr)) { + nxtdsp = SCRIPTB_BA(np, nego_bad_phase); + if (dsp == SCRIPTB_BA(np, send_ppr)) { + struct scsi_device *dev = cp->cmd->device; + dev->ppr = 0; + } } break; #if 0 case 7: /* MSG IN phase */ - nxtdsp = SCRIPTA_BA (np, clrack); + nxtdsp = SCRIPTA_BA(np, clrack); break; #endif } if (nxtdsp) { - OUTL_DSP (nxtdsp); + OUTL_DSP(np, nxtdsp); return; } @@ -2838,7 +2756,7 @@ reset_all: * Use at your own decision and risk. */ -void sym_interrupt (hcb_p np) +void sym_interrupt (struct sym_hcb *np) { u_char istat, istatc; u_char dstat; @@ -2855,20 +2773,20 @@ void sym_interrupt (hcb_p np) * Note that SCRIPTS also (dummy) read to memory * prior to deliver the INTF interrupt condition. */ - istat = INB (nc_istat); + istat = INB(np, nc_istat); if (istat & INTF) { - OUTB (nc_istat, (istat & SIGP) | INTF | np->istat_sem); - istat = INB (nc_istat); /* DUMMY READ */ + OUTB(np, nc_istat, (istat & SIGP) | INTF | np->istat_sem); + istat = INB(np, nc_istat); /* DUMMY READ */ if (DEBUG_FLAGS & DEBUG_TINY) printf ("F "); - (void)sym_wakeup_done (np); - }; + sym_wakeup_done(np); + } if (!(istat & (SIP|DIP))) return; #if 0 /* We should never get this one */ if (istat & CABRT) - OUTB (nc_istat, CABRT); + OUTB(np, nc_istat, CABRT); #endif /* @@ -2886,19 +2804,19 @@ void sym_interrupt (hcb_p np) istatc = istat; do { if (istatc & SIP) - sist |= INW (nc_sist); + sist |= INW(np, nc_sist); if (istatc & DIP) - dstat |= INB (nc_dstat); - istatc = INB (nc_istat); + dstat |= INB(np, nc_dstat); + istatc = INB(np, nc_istat); istat |= istatc; } while (istatc & (SIP|DIP)); if (DEBUG_FLAGS & DEBUG_TINY) printf ("<%d|%x:%x|%x:%x>", - (int)INB(nc_scr0), + (int)INB(np, nc_scr0), dstat,sist, - (unsigned)INL(nc_dsp), - (unsigned)INL(nc_dbc)); + (unsigned)INL(np, nc_dsp), + (unsigned)INL(np, nc_dbc)); /* * On paper, a memory read barrier may be needed here to * prevent out of order LOADs by the CPU from having @@ -2925,10 +2843,10 @@ void sym_interrupt (hcb_p np) if (sist & PAR) sym_int_par (np, sist); else if (sist & MA) sym_int_ma (np); else if (dstat & SIR) sym_int_sir (np); - else if (dstat & SSI) OUTONB_STD (); + else if (dstat & SSI) OUTONB_STD(); else goto unknown_int; return; - }; + } /* * Now, interrupts that donnot happen in normal @@ -2945,10 +2863,10 @@ void sym_interrupt (hcb_p np) printf("%s: SCSI BUS reset detected.\n", sym_name(np)); sym_start_up (np, 1); return; - }; + } - OUTB (nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ - OUTB (nc_stest3, TE|CSF); /* clear scsi fifo */ + OUTB(np, nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ + OUTB(np, nc_stest3, TE|CSF); /* clear scsi fifo */ if (!(sist & (GEN|HTH|SGE)) && !(dstat & (MDPE|BF|ABRT|IID))) { @@ -2957,7 +2875,7 @@ void sym_interrupt (hcb_p np) else if (sist & UDC) sym_int_udc (np); else goto unknown_int; return; - }; + } /* * Now, interrupts we are not able to recover cleanly. @@ -2972,7 +2890,7 @@ void sym_interrupt (hcb_p np) (dstat & (MDPE|BF|ABRT|IID))) { sym_start_reset(np); return; - }; + } unknown_int: /* @@ -2988,15 +2906,15 @@ unknown_int: * Dequeue from the START queue all CCBs that match * a given target/lun/task condition (-1 means all), * and move them from the BUSY queue to the COMP queue - * with CAM_REQUEUE_REQ status condition. + * with DID_SOFT_ERROR status condition. * This function is used during error handling/recovery. * It is called with SCRIPTS not running. */ static int -sym_dequeue_from_squeue(hcb_p np, int i, int target, int lun, int task) +sym_dequeue_from_squeue(struct sym_hcb *np, int i, int target, int lun, int task) { int j; - ccb_p cp; + struct sym_ccb *cp; /* * Make sure the starting index is within range. @@ -3018,7 +2936,7 @@ sym_dequeue_from_squeue(hcb_p np, int i, int target, int lun, int task) if ((target == -1 || cp->target == target) && (lun == -1 || cp->lun == lun) && (task == -1 || cp->tag == task)) { - sym_set_cam_status(cp->cam_ccb, CAM_REQUEUE_REQ); + sym_set_cam_status(cp->cmd, DID_SOFT_ERROR); sym_remque(&cp->link_ccbq); sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq); } @@ -3036,60 +2954,6 @@ sym_dequeue_from_squeue(hcb_p np, int i, int target, int lun, int task) return (i - j) / 2; } -/* - * Complete all CCBs queued to the COMP queue. - * - * These CCBs are assumed: - * - Not to be referenced either by devices or - * SCRIPTS-related queues and datas. - * - To have to be completed with an error condition - * or requeued. - * - * The device queue freeze count is incremented - * for each CCB that does not prevent this. - * This function is called when all CCBs involved - * in error handling/recovery have been reaped. - */ -void sym_flush_comp_queue(hcb_p np, int cam_status) -{ - SYM_QUEHEAD *qp; - ccb_p cp; - - while ((qp = sym_remque_head(&np->comp_ccbq)) != 0) { - cam_ccb_p ccb; - cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); - sym_insque_tail(&cp->link_ccbq, &np->busy_ccbq); - /* Leave quiet CCBs waiting for resources */ - if (cp->host_status == HS_WAIT) - continue; - ccb = cp->cam_ccb; - if (cam_status) - sym_set_cam_status(ccb, cam_status); -#ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING - if (sym_get_cam_status(ccb) == CAM_REQUEUE_REQ) { - tcb_p tp = &np->target[cp->target]; - lcb_p lp = sym_lp(np, tp, cp->lun); - if (lp) { - sym_remque(&cp->link2_ccbq); - sym_insque_tail(&cp->link2_ccbq, - &lp->waiting_ccbq); - if (cp->started) { - if (cp->tag != NO_TAG) - --lp->started_tags; - else - --lp->started_no_tag; - } - } - cp->started = 0; - continue; - } -#endif - sym_free_ccb(np, cp); - sym_freeze_cam_ccb(ccb); - sym_xpt_done(np, ccb); - } -} - /* * chip handler for bad SCSI status condition * @@ -3108,20 +2972,18 @@ void sym_flush_comp_queue(hcb_p np, int cam_status) * SCRATCHA is assumed to have been loaded with STARTPOS * before the SCRIPTS called the C code. */ -static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) +static void sym_sir_bad_scsi_status(struct sym_hcb *np, int num, struct sym_ccb *cp) { - tcb_p tp = &np->target[cp->target]; u32 startp; u_char s_status = cp->ssss_status; u_char h_flags = cp->host_flags; int msglen; - int nego; int i; /* * Compute the index of the next job to start from SCRIPTS. */ - i = (INL (nc_scratcha) - np->squeue_ba) / 4; + i = (INL(np, nc_scratcha) - np->squeue_ba) / 4; /* * The last CCB queued used for IARB hint may be @@ -3139,8 +3001,7 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) case S_BUSY: case S_QUEUE_FULL: if (sym_verbose >= 2) { - PRINT_ADDR(cp); - printf ("%s\n", + sym_print_addr(cp->cmd, "%s\n", s_status == S_BUSY ? "BUSY" : "QUEUE FULL\n"); } default: /* S_INT, S_INT_COND_MET, S_CONFLICT */ @@ -3160,8 +3021,8 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) * Dequeue all queued CCBs for that device not yet started, * and restart the SCRIPTS processor immediately. */ - (void) sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1); - OUTL_DSP (SCRIPTA_BA (np, start)); + sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1); + OUTL_DSP(np, SCRIPTA_BA(np, start)); /* * Save some info of the actual IO. @@ -3176,10 +3037,7 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) * requesting sense data. */ - /* - * identify message - */ - cp->scsi_smsg2[0] = M_IDENTIFY | cp->lun; + cp->scsi_smsg2[0] = IDENTIFY(0, cp->lun); msglen = 1; /* @@ -3193,26 +3051,17 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) * cp->nego_status is filled by sym_prepare_nego(). */ cp->nego_status = 0; - nego = 0; - if (tp->tinfo.curr.options & PPR_OPT_MASK) - nego = NS_PPR; - else if (tp->tinfo.curr.width != BUS_8_BIT) - nego = NS_WIDE; - else if (tp->tinfo.curr.offset != 0) - nego = NS_SYNC; - if (nego) - msglen += - sym_prepare_nego (np,cp, nego, &cp->scsi_smsg2[msglen]); + msglen += sym_prepare_nego(np, cp, &cp->scsi_smsg2[msglen]); /* * Message table indirect structure. */ - cp->phys.smsg.addr = cpu_to_scr(CCB_BA (cp, scsi_smsg2)); + cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg2); cp->phys.smsg.size = cpu_to_scr(msglen); /* * sense command */ - cp->phys.cmd.addr = cpu_to_scr(CCB_BA (cp, sensecmd)); + cp->phys.cmd.addr = CCB_BA(cp, sensecmd); cp->phys.cmd.size = cpu_to_scr(6); /* @@ -3220,7 +3069,7 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) */ cp->sensecmd[0] = REQUEST_SENSE; cp->sensecmd[1] = 0; - if (tp->tinfo.curr.scsi_version <= 2 && cp->lun <= 7) + if (cp->cmd->device->scsi_level <= SCSI_2 && cp->lun <= 7) cp->sensecmd[1] = cp->lun << 5; cp->sensecmd[4] = SYM_SNS_BBUF_LEN; cp->data_len = SYM_SNS_BBUF_LEN; @@ -3228,14 +3077,14 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) /* * sense data */ - bzero(cp->sns_bbuf, SYM_SNS_BBUF_LEN); - cp->phys.sense.addr = cpu_to_scr(vtobus(cp->sns_bbuf)); + memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN); + cp->phys.sense.addr = CCB_BA(cp, sns_bbuf); cp->phys.sense.size = cpu_to_scr(SYM_SNS_BBUF_LEN); /* * requeue the command. */ - startp = SCRIPTB_BA (np, sdata_in); + startp = SCRIPTB_BA(np, sdata_in); cp->phys.head.savep = cpu_to_scr(startp); cp->phys.head.lastp = cpu_to_scr(startp); @@ -3249,7 +3098,7 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) cp->xerr_status = 0; cp->extra_bytes = 0; - cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA (np, select)); + cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, select)); /* * Requeue the command. @@ -3278,11 +3127,11 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp) * - lun=-1 means any logical UNIT otherwise a given one. * - task=-1 means any task, otherwise a given one. */ -int sym_clear_tasks(hcb_p np, int cam_status, int target, int lun, int task) +int sym_clear_tasks(struct sym_hcb *np, int cam_status, int target, int lun, int task) { SYM_QUEHEAD qtmp, *qp; int i = 0; - ccb_p cp; + struct sym_ccb *cp; /* * Move the entire BUSY queue to our temporary queue. @@ -3297,9 +3146,9 @@ int sym_clear_tasks(hcb_p np, int cam_status, int target, int lun, int task) * the BUSY queue. */ while ((qp = sym_remque_head(&qtmp)) != 0) { - cam_ccb_p ccb; + struct scsi_cmnd *cmd; cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); - ccb = cp->cam_ccb; + cmd = cp->cmd; if (cp->host_status != HS_DISCONNECT || cp->target != target || (lun != -1 && cp->lun != lun) || @@ -3311,8 +3160,8 @@ int sym_clear_tasks(hcb_p np, int cam_status, int target, int lun, int task) sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq); /* Preserve the software timeout condition */ - if (sym_get_cam_status(ccb) != CAM_CMD_TIMEOUT) - sym_set_cam_status(ccb, cam_status); + if (sym_get_cam_status(cmd) != DID_TIME_OUT) + sym_set_cam_status(cmd, cam_status); ++i; #if 0 printf("XXXX TASK @%p CLEARED\n", cp); @@ -3361,11 +3210,12 @@ printf("XXXX TASK @%p CLEARED\n", cp); * all the CCBs that should have been aborted by the * target according to our message. */ -static void sym_sir_task_recovery(hcb_p np, int num) +static void sym_sir_task_recovery(struct sym_hcb *np, int num) { SYM_QUEHEAD *qp; - ccb_p cp; - tcb_p tp; + struct sym_ccb *cp; + struct sym_tcb *tp = NULL; /* gcc isn't quite smart enough yet */ + struct scsi_target *starget; int target=-1, lun=-1, task; int i, k; @@ -3423,8 +3273,8 @@ static void sym_sir_task_recovery(hcb_p np, int num) np->abrt_sel.sel_id = target; np->abrt_sel.sel_scntl3 = tp->head.wval; np->abrt_sel.sel_sxfer = tp->head.sval; - OUTL(nc_dsa, np->hcb_ba); - OUTL_DSP (SCRIPTB_BA (np, sel_for_abort)); + OUTL(np, nc_dsa, np->hcb_ba); + OUTL_DSP(np, SCRIPTB_BA(np, sel_for_abort)); return; } @@ -3463,7 +3313,7 @@ static void sym_sir_task_recovery(hcb_p np, int num) * Remove the SEM flag from the ISTAT. */ np->istat_sem = 0; - OUTB (nc_istat, SIGP); + OUTB(np, nc_istat, SIGP); break; } /* @@ -3471,14 +3321,14 @@ static void sym_sir_task_recovery(hcb_p np, int num) * queue the SCRIPTS intends to start and dequeue * all CCBs for that device that haven't been started. */ - i = (INL (nc_scratcha) - np->squeue_ba) / 4; + i = (INL(np, nc_scratcha) - np->squeue_ba) / 4; i = sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1); /* * Make sure at least our IO to abort has been dequeued. */ #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING - assert(i && sym_get_cam_status(cp->cam_ccb) == CAM_REQUEUE_REQ); + assert(i && sym_get_cam_status(cp->cmd) == DID_SOFT_ERROR); #else sym_remque(&cp->link_ccbq); sym_insque_tail(&cp->link_ccbq, &np->comp_ccbq); @@ -3487,9 +3337,9 @@ static void sym_sir_task_recovery(hcb_p np, int num) * Keep track in cam status of the reason of the abort. */ if (cp->to_abort == 2) - sym_set_cam_status(cp->cam_ccb, CAM_CMD_TIMEOUT); + sym_set_cam_status(cp->cmd, DID_TIME_OUT); else - sym_set_cam_status(cp->cam_ccb, CAM_REQ_ABORTED); + sym_set_cam_status(cp->cmd, DID_ABORT); /* * Complete with error everything that we have dequeued. @@ -3501,7 +3351,7 @@ static void sym_sir_task_recovery(hcb_p np, int num) * we may have some manual recovery to perform for. */ case SIR_TARGET_SELECTED: - target = (INB (nc_sdid) & 0xf); + target = INB(np, nc_sdid) & 0xf; tp = &np->target[target]; np->abrt_tbl.addr = cpu_to_scr(vtobus(np->abrt_msg)); @@ -3537,9 +3387,9 @@ static void sym_sir_task_recovery(hcb_p np, int num) * an IDENTIFY(lun) + ABORT MESSAGE. */ if (lun != -1) { - lcb_p lp = sym_lp(np, tp, lun); - lp->to_clear = 0; /* We donnot expect to fail here */ - np->abrt_msg[0] = M_IDENTIFY | lun; + struct sym_lcb *lp = sym_lp(tp, lun); + lp->to_clear = 0; /* We don't expect to fail here */ + np->abrt_msg[0] = IDENTIFY(0, lun); np->abrt_msg[1] = M_ABORT; np->abrt_tbl.size = 2; break; @@ -3580,7 +3430,7 @@ static void sym_sir_task_recovery(hcb_p np, int num) * We have some task to abort. * Set the IDENTIFY(lun) */ - np->abrt_msg[0] = M_IDENTIFY | cp->lun; + np->abrt_msg[0] = IDENTIFY(0, cp->lun); /* * If we want to abort an untagged command, we @@ -3591,8 +3441,7 @@ static void sym_sir_task_recovery(hcb_p np, int num) if (cp->tag == NO_TAG) { np->abrt_msg[1] = M_ABORT; np->abrt_tbl.size = 2; - } - else { + } else { np->abrt_msg[1] = cp->scsi_smsg[1]; np->abrt_msg[2] = cp->scsi_smsg[2]; np->abrt_msg[3] = M_ABORT_TAG; @@ -3604,7 +3453,7 @@ static void sym_sir_task_recovery(hcb_p np, int num) * conditions not due to timeout. */ if (cp->to_abort == 2) - sym_set_cam_status(cp->cam_ccb, CAM_CMD_TIMEOUT); + sym_set_cam_status(cp->cmd, DID_TIME_OUT); cp->to_abort = 0; /* We donnot expect to fail here */ break; @@ -3613,8 +3462,9 @@ static void sym_sir_task_recovery(hcb_p np, int num) * to BUS FREE phase as we expected. */ case SIR_ABORT_SENT: - target = (INB (nc_sdid) & 0xf); + target = INB(np, nc_sdid) & 0xf; tp = &np->target[target]; + starget = tp->starget; /* ** If we didn't abort anything, leave here. @@ -3636,10 +3486,13 @@ static void sym_sir_task_recovery(hcb_p np, int num) tp->head.sval = 0; tp->head.wval = np->rv_scntl3; tp->head.uval = 0; - tp->tinfo.curr.period = 0; - tp->tinfo.curr.offset = 0; - tp->tinfo.curr.width = BUS_8_BIT; - tp->tinfo.curr.options = 0; + spi_period(starget) = 0; + spi_offset(starget) = 0; + spi_width(starget) = 0; + spi_iu(starget) = 0; + spi_dt(starget) = 0; + spi_qas(starget) = 0; + tp->tgoal.check_nego = 1; } /* @@ -3658,9 +3511,9 @@ static void sym_sir_task_recovery(hcb_p np, int num) * Complete all the CCBs the device should have * aborted due to our 'kiss of death' message. */ - i = (INL (nc_scratcha) - np->squeue_ba) / 4; - (void) sym_dequeue_from_squeue(np, i, target, lun, -1); - (void) sym_clear_tasks(np, CAM_REQ_ABORTED, target, lun, task); + i = (INL(np, nc_scratcha) - np->squeue_ba) / 4; + sym_dequeue_from_squeue(np, i, target, lun, -1); + sym_clear_tasks(np, DID_ABORT, target, lun, task); sym_flush_comp_queue(np, 0); /* @@ -3675,16 +3528,15 @@ static void sym_sir_task_recovery(hcb_p np, int num) * Print to the log the message we intend to send. */ if (num == SIR_TARGET_SELECTED) { - PRINT_TARGET(np, target); - sym_printl_hex("control msgout:", np->abrt_msg, - np->abrt_tbl.size); + dev_info(&tp->starget->dev, "control msgout:"); + sym_printl_hex(np->abrt_msg, np->abrt_tbl.size); np->abrt_tbl.size = cpu_to_scr(np->abrt_tbl.size); } /* * Let the SCRIPTS processor continue. */ - OUTONB_STD (); + OUTONB_STD(); } /* @@ -3692,7 +3544,7 @@ static void sym_sir_task_recovery(hcb_p np, int num) * pointer for both MDP and the residual calculation. * * I didn't want to bloat the code by more than 200 - * lignes for the handling of both MDP and the residual. + * lines for the handling of both MDP and the residual. * This has been achieved by using a data pointer * representation consisting in an index in the data * array (dp_sg) and a negative offset (dp_ofs) that @@ -3714,7 +3566,7 @@ static void sym_sir_task_recovery(hcb_p np, int num) * the corresponding values of dp_sg and dp_ofs. */ -static int sym_evaluate_dp(hcb_p np, ccb_p cp, u32 scr, int *ofs) +static int sym_evaluate_dp(struct sym_hcb *np, struct sym_ccb *cp, u32 scr, int *ofs) { u32 dp_scr; int dp_ofs, dp_sg, dp_sgmin; @@ -3727,16 +3579,16 @@ static int sym_evaluate_dp(hcb_p np, ccb_p cp, u32 scr, int *ofs) */ dp_scr = scr; dp_ofs = *ofs; - if (dp_scr == SCRIPTA_BA (np, pm0_data)) + if (dp_scr == SCRIPTA_BA(np, pm0_data)) pm = &cp->phys.pm0; - else if (dp_scr == SCRIPTA_BA (np, pm1_data)) + else if (dp_scr == SCRIPTA_BA(np, pm1_data)) pm = &cp->phys.pm1; else pm = NULL; if (pm) { dp_scr = scr_to_cpu(pm->ret); - dp_ofs -= scr_to_cpu(pm->sg.size); + dp_ofs -= scr_to_cpu(pm->sg.size) & 0x00ffffff; } /* @@ -3753,7 +3605,7 @@ static int sym_evaluate_dp(hcb_p np, ccb_p cp, u32 scr, int *ofs) * If result is dp_sg = SYM_CONF_MAX_SG, then we are at the * end of the data. */ - tmp = scr_to_cpu(sym_goalp(cp)); + tmp = scr_to_cpu(cp->goalp); dp_sg = SYM_CONF_MAX_SG; if (dp_scr != tmp) dp_sg -= (tmp - 8 - (int)dp_scr) / (2*4); @@ -3832,7 +3684,7 @@ out_err: * is equivalent to a MODIFY DATA POINTER (offset=-1). */ -static void sym_modify_dp(hcb_p np, tcb_p tp, ccb_p cp, int ofs) +static void sym_modify_dp(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp, int ofs) { int dp_ofs = ofs; u32 dp_scr = sym_get_script_dp (np, cp); @@ -3860,7 +3712,7 @@ static void sym_modify_dp(hcb_p np, tcb_p tp, ccb_p cp, int ofs) * And our alchemy:) allows to easily calculate the data * script address we want to return for the next data phase. */ - dp_ret = cpu_to_scr(sym_goalp(cp)); + dp_ret = cpu_to_scr(cp->goalp); dp_ret = dp_ret - 8 - (SYM_CONF_MAX_SG - dp_sg) * (2*4); /* @@ -3875,23 +3727,23 @@ static void sym_modify_dp(hcb_p np, tcb_p tp, ccb_p cp, int ofs) /* * Get a context for the new current data pointer. */ - hflags = INB (HF_PRT); + hflags = INB(np, HF_PRT); if (hflags & HF_DP_SAVED) hflags ^= HF_ACT_PM; if (!(hflags & HF_ACT_PM)) { pm = &cp->phys.pm0; - dp_scr = SCRIPTA_BA (np, pm0_data); + dp_scr = SCRIPTA_BA(np, pm0_data); } else { pm = &cp->phys.pm1; - dp_scr = SCRIPTA_BA (np, pm1_data); + dp_scr = SCRIPTA_BA(np, pm1_data); } hflags &= ~(HF_DP_SAVED); - OUTB (HF_PRT, hflags); + OUTB(np, HF_PRT, hflags); /* * Set up the new current data pointer. @@ -3908,11 +3760,11 @@ static void sym_modify_dp(hcb_p np, tcb_p tp, ccb_p cp, int ofs) out_ok: sym_set_script_dp (np, cp, dp_scr); - OUTL_DSP (SCRIPTA_BA (np, clrack)); + OUTL_DSP(np, SCRIPTA_BA(np, clrack)); return; out_reject: - OUTL_DSP (SCRIPTB_BA (np, msg_bad)); + OUTL_DSP(np, SCRIPTB_BA(np, msg_bad)); } @@ -3931,7 +3783,7 @@ out_reject: * a relevant information. :) */ -int sym_compute_residual(hcb_p np, ccb_p cp) +int sym_compute_residual(struct sym_hcb *np, struct sym_ccb *cp) { int dp_sg, dp_sgmin, resid = 0; int dp_ofs = 0; @@ -3956,7 +3808,7 @@ int sym_compute_residual(hcb_p np, ccb_p cp) * If all data has been transferred, * there is no residual. */ - if (cp->phys.head.lastp == sym_goalp(cp)) + if (cp->phys.head.lastp == cp->goalp) return resid; /* @@ -3987,6 +3839,8 @@ int sym_compute_residual(hcb_p np, ccb_p cp) resid += (tmp & 0xffffff); } + resid -= cp->odd_byte_adjustment; + /* * Hopefully, the result is not too wrong. */ @@ -4031,13 +3885,14 @@ int sym_compute_residual(hcb_p np, ccb_p cp) * chip handler for SYNCHRONOUS DATA TRANSFER REQUEST (SDTR) message. */ static int -sym_sync_nego_check(hcb_p np, int req, int target) +sym_sync_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp) { + int target = cp->target; u_char chg, ofs, per, fak, div; if (DEBUG_FLAGS & DEBUG_NEGO) { sym_print_nego_msg(np, target, "sync msgin", np->msgin); - }; + } /* * Get requested values. @@ -4067,9 +3922,9 @@ sym_sync_nego_check(hcb_p np, int req, int target) goto reject_it; if (DEBUG_FLAGS & DEBUG_NEGO) { - PRINT_TARGET(np, target); - printf ("sdtr: ofs=%d per=%d div=%d fak=%d chg=%d.\n", - ofs, per, div, fak, chg); + sym_print_addr(cp->cmd, + "sdtr: ofs=%d per=%d div=%d fak=%d chg=%d.\n", + ofs, per, div, fak, chg); } /* @@ -4093,11 +3948,7 @@ sym_sync_nego_check(hcb_p np, int req, int target) /* * It was a request. Prepare an answer message. */ - np->msgout[0] = M_EXTENDED; - np->msgout[1] = 3; - np->msgout[2] = M_X_SYNC_REQ; - np->msgout[3] = per; - np->msgout[4] = ofs; + spi_populate_sync_msg(np->msgout, per, ofs); if (DEBUG_FLAGS & DEBUG_NEGO) { sym_print_nego_msg(np, target, "sync msgout", np->msgout); @@ -4112,7 +3963,7 @@ reject_it: return -1; } -static void sym_sync_nego(hcb_p np, tcb_p tp, ccb_p cp) +static void sym_sync_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp) { int req = 1; int result; @@ -4120,8 +3971,8 @@ static void sym_sync_nego(hcb_p np, tcb_p tp, ccb_p cp) /* * Request or answer ? */ - if (INB (HS_PRT) == HS_NEGOTIATE) { - OUTB (HS_PRT, HS_BUSY); + if (INB(np, HS_PRT) == HS_NEGOTIATE) { + OUTB(np, HS_PRT, HS_BUSY); if (cp->nego_status && cp->nego_status != NS_SYNC) goto reject_it; req = 0; @@ -4130,42 +3981,39 @@ static void sym_sync_nego(hcb_p np, tcb_p tp, ccb_p cp) /* * Check and apply new values. */ - result = sym_sync_nego_check(np, req, cp->target); + result = sym_sync_nego_check(np, req, cp); if (result) /* Not acceptable, reject it */ goto reject_it; if (req) { /* Was a request, send response. */ cp->nego_status = NS_SYNC; - OUTL_DSP (SCRIPTB_BA (np, sdtr_resp)); + OUTL_DSP(np, SCRIPTB_BA(np, sdtr_resp)); } else /* Was a response, we are done. */ - OUTL_DSP (SCRIPTA_BA (np, clrack)); + OUTL_DSP(np, SCRIPTA_BA(np, clrack)); return; reject_it: - OUTL_DSP (SCRIPTB_BA (np, msg_bad)); + OUTL_DSP(np, SCRIPTB_BA(np, msg_bad)); } /* * chip handler for PARALLEL PROTOCOL REQUEST (PPR) message. */ static int -sym_ppr_nego_check(hcb_p np, int req, int target) +sym_ppr_nego_check(struct sym_hcb *np, int req, int target) { - tcb_p tp = &np->target[target]; - u_char chg, ofs, per, fak, dt, div, wide; + struct sym_tcb *tp = &np->target[target]; + unsigned char fak, div; + int dt, chg = 0; + + unsigned char per = np->msgin[3]; + unsigned char ofs = np->msgin[5]; + unsigned char wide = np->msgin[6]; + unsigned char opts = np->msgin[7] & PPR_OPT_MASK; if (DEBUG_FLAGS & DEBUG_NEGO) { sym_print_nego_msg(np, target, "ppr msgin", np->msgin); - }; - - /* - * Get requested values. - */ - chg = 0; - per = np->msgin[3]; - ofs = np->msgin[5]; - wide = np->msgin[6]; - dt = np->msgin[7] & PPR_OPT_DT; + } /* * Check values against our limits. @@ -4174,30 +4022,28 @@ sym_ppr_nego_check(hcb_p np, int req, int target) chg = 1; wide = np->maxwide; } - if (!wide || !(np->features & FE_ULTRA3)) - dt &= ~PPR_OPT_DT; + if (!wide || !(np->features & FE_U3EN)) + opts = 0; - if (!(np->features & FE_U3EN)) /* Broken U3EN bit not supported */ - dt &= ~PPR_OPT_DT; + if (opts != (np->msgin[7] & PPR_OPT_MASK)) + chg = 1; - if (dt != (np->msgin[7] & PPR_OPT_MASK)) chg = 1; + dt = opts & PPR_OPT_DT; if (ofs) { - if (dt) { - if (ofs > np->maxoffs_dt) - {chg = 1; ofs = np->maxoffs_dt;} + unsigned char maxoffs = dt ? np->maxoffs_dt : np->maxoffs; + if (ofs > maxoffs) { + chg = 1; + ofs = maxoffs; } - else if (ofs > np->maxoffs) - {chg = 1; ofs = np->maxoffs;} } if (ofs) { - if (dt) { - if (per < np->minsync_dt) - {chg = 1; per = np->minsync_dt;} + unsigned char minsync = dt ? np->minsync_dt : np->minsync; + if (per < minsync) { + chg = 1; + per = minsync; } - else if (per < np->minsync) - {chg = 1; per = np->minsync;} } /* @@ -4217,7 +4063,7 @@ sym_ppr_nego_check(hcb_p np, int req, int target) /* * Apply new values. */ - sym_setpprot (np, target, dt, ofs, per, wide, div, fak); + sym_setpprot(np, target, opts, ofs, per, wide, div, fak); /* * It was an answer. We are done. @@ -4228,14 +4074,7 @@ sym_ppr_nego_check(hcb_p np, int req, int target) /* * It was a request. Prepare an answer message. */ - np->msgout[0] = M_EXTENDED; - np->msgout[1] = 6; - np->msgout[2] = M_X_PPR_REQ; - np->msgout[3] = per; - np->msgout[4] = 0; - np->msgout[5] = ofs; - np->msgout[6] = wide; - np->msgout[7] = dt; + spi_populate_ppr_msg(np->msgout, per, ofs, wide, opts); if (DEBUG_FLAGS & DEBUG_NEGO) { sym_print_nego_msg(np, target, "ppr msgout", np->msgout); @@ -4251,16 +4090,17 @@ reject_it: * If it is a device response that should result in * ST, we may want to try a legacy negotiation later. */ - if (!req && !dt) { - tp->tinfo.goal.options = 0; - tp->tinfo.goal.width = wide; - tp->tinfo.goal.period = per; - tp->tinfo.goal.offset = ofs; + if (!req && !opts) { + tp->tgoal.period = per; + tp->tgoal.offset = ofs; + tp->tgoal.width = wide; + tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0; + tp->tgoal.check_nego = 1; } return -1; } -static void sym_ppr_nego(hcb_p np, tcb_p tp, ccb_p cp) +static void sym_ppr_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp) { int req = 1; int result; @@ -4268,8 +4108,8 @@ static void sym_ppr_nego(hcb_p np, tcb_p tp, ccb_p cp) /* * Request or answer ? */ - if (INB (HS_PRT) == HS_NEGOTIATE) { - OUTB (HS_PRT, HS_BUSY); + if (INB(np, HS_PRT) == HS_NEGOTIATE) { + OUTB(np, HS_PRT, HS_BUSY); if (cp->nego_status && cp->nego_status != NS_PPR) goto reject_it; req = 0; @@ -4283,27 +4123,28 @@ static void sym_ppr_nego(hcb_p np, tcb_p tp, ccb_p cp) goto reject_it; if (req) { /* Was a request, send response. */ cp->nego_status = NS_PPR; - OUTL_DSP (SCRIPTB_BA (np, ppr_resp)); + OUTL_DSP(np, SCRIPTB_BA(np, ppr_resp)); } else /* Was a response, we are done. */ - OUTL_DSP (SCRIPTA_BA (np, clrack)); + OUTL_DSP(np, SCRIPTA_BA(np, clrack)); return; reject_it: - OUTL_DSP (SCRIPTB_BA (np, msg_bad)); + OUTL_DSP(np, SCRIPTB_BA(np, msg_bad)); } /* * chip handler for WIDE DATA TRANSFER REQUEST (WDTR) message. */ static int -sym_wide_nego_check(hcb_p np, int req, int target) +sym_wide_nego_check(struct sym_hcb *np, int req, struct sym_ccb *cp) { + int target = cp->target; u_char chg, wide; if (DEBUG_FLAGS & DEBUG_NEGO) { sym_print_nego_msg(np, target, "wide msgin", np->msgin); - }; + } /* * Get requested values. @@ -4320,8 +4161,8 @@ sym_wide_nego_check(hcb_p np, int req, int target) } if (DEBUG_FLAGS & DEBUG_NEGO) { - PRINT_TARGET(np, target); - printf ("wdtr: wide=%d chg=%d.\n", wide, chg); + sym_print_addr(cp->cmd, "wdtr: wide=%d chg=%d.\n", + wide, chg); } /* @@ -4345,10 +4186,7 @@ sym_wide_nego_check(hcb_p np, int req, int target) /* * It was a request. Prepare an answer message. */ - np->msgout[0] = M_EXTENDED; - np->msgout[1] = 2; - np->msgout[2] = M_X_WIDE_REQ; - np->msgout[3] = wide; + spi_populate_width_msg(np->msgout, wide); np->msgin [0] = M_NOOP; @@ -4362,7 +4200,7 @@ reject_it: return -1; } -static void sym_wide_nego(hcb_p np, tcb_p tp, ccb_p cp) +static void sym_wide_nego(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp) { int req = 1; int result; @@ -4370,8 +4208,8 @@ static void sym_wide_nego(hcb_p np, tcb_p tp, ccb_p cp) /* * Request or answer ? */ - if (INB (HS_PRT) == HS_NEGOTIATE) { - OUTB (HS_PRT, HS_BUSY); + if (INB(np, HS_PRT) == HS_NEGOTIATE) { + OUTB(np, HS_PRT, HS_BUSY); if (cp->nego_status && cp->nego_status != NS_WIDE) goto reject_it; req = 0; @@ -4380,25 +4218,21 @@ static void sym_wide_nego(hcb_p np, tcb_p tp, ccb_p cp) /* * Check and apply new values. */ - result = sym_wide_nego_check(np, req, cp->target); + result = sym_wide_nego_check(np, req, cp); if (result) /* Not acceptable, reject it */ goto reject_it; if (req) { /* Was a request, send response. */ cp->nego_status = NS_WIDE; - OUTL_DSP (SCRIPTB_BA (np, wdtr_resp)); - } - else { /* Was a response. */ + OUTL_DSP(np, SCRIPTB_BA(np, wdtr_resp)); + } else { /* Was a response. */ /* * Negotiate for SYNC immediately after WIDE response. * This allows to negotiate for both WIDE and SYNC on * a single SCSI command (Suggested by Justin Gibbs). */ - if (tp->tinfo.goal.offset) { - np->msgout[0] = M_EXTENDED; - np->msgout[1] = 3; - np->msgout[2] = M_X_SYNC_REQ; - np->msgout[3] = tp->tinfo.goal.period; - np->msgout[4] = tp->tinfo.goal.offset; + if (tp->tgoal.offset) { + spi_populate_sync_msg(np->msgout, tp->tgoal.period, + tp->tgoal.offset); if (DEBUG_FLAGS & DEBUG_NEGO) { sym_print_nego_msg(np, cp->target, @@ -4406,18 +4240,17 @@ static void sym_wide_nego(hcb_p np, tcb_p tp, ccb_p cp) } cp->nego_status = NS_SYNC; - OUTB (HS_PRT, HS_NEGOTIATE); - OUTL_DSP (SCRIPTB_BA (np, sdtr_resp)); + OUTB(np, HS_PRT, HS_NEGOTIATE); + OUTL_DSP(np, SCRIPTB_BA(np, sdtr_resp)); return; - } - else - OUTL_DSP (SCRIPTA_BA (np, clrack)); - }; + } else + OUTL_DSP(np, SCRIPTA_BA(np, clrack)); + } return; reject_it: - OUTL_DSP (SCRIPTB_BA (np, msg_bad)); + OUTL_DSP(np, SCRIPTB_BA(np, msg_bad)); } /* @@ -4431,18 +4264,19 @@ reject_it: * So, if a PPR makes problems, we may just want to * try a legacy negotiation later. */ -static void sym_nego_default(hcb_p np, tcb_p tp, ccb_p cp) +static void sym_nego_default(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp) { switch (cp->nego_status) { case NS_PPR: #if 0 sym_setpprot (np, cp->target, 0, 0, 0, 0, 0, 0); #else - tp->tinfo.goal.options = 0; - if (tp->tinfo.goal.period < np->minsync) - tp->tinfo.goal.period = np->minsync; - if (tp->tinfo.goal.offset > np->maxoffs) - tp->tinfo.goal.offset = np->maxoffs; + if (tp->tgoal.period < np->minsync) + tp->tgoal.period = np->minsync; + if (tp->tgoal.offset > np->maxoffs) + tp->tgoal.offset = np->maxoffs; + tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0; + tp->tgoal.check_nego = 1; #endif break; case NS_SYNC: @@ -4451,7 +4285,7 @@ static void sym_nego_default(hcb_p np, tcb_p tp, ccb_p cp) case NS_WIDE: sym_setwide (np, cp->target, 0); break; - }; + } np->msgin [0] = M_NOOP; np->msgout[0] = M_NOOP; cp->nego_status = 0; @@ -4461,22 +4295,22 @@ static void sym_nego_default(hcb_p np, tcb_p tp, ccb_p cp) * chip handler for MESSAGE REJECT received in response to * PPR, WIDE or SYNCHRONOUS negotiation. */ -static void sym_nego_rejected(hcb_p np, tcb_p tp, ccb_p cp) +static void sym_nego_rejected(struct sym_hcb *np, struct sym_tcb *tp, struct sym_ccb *cp) { sym_nego_default(np, tp, cp); - OUTB (HS_PRT, HS_BUSY); + OUTB(np, HS_PRT, HS_BUSY); } /* * chip exception handler for programmed interrupts. */ -static void sym_int_sir (hcb_p np) +static void sym_int_sir (struct sym_hcb *np) { - u_char num = INB (nc_dsps); - u32 dsa = INL (nc_dsa); - ccb_p cp = sym_ccb_from_dsa(np, dsa); - u_char target = INB (nc_sdid) & 0x0f; - tcb_p tp = &np->target[target]; + u_char num = INB(np, nc_dsps); + u32 dsa = INL(np, nc_dsa); + struct sym_ccb *cp = sym_ccb_from_dsa(np, dsa); + u_char target = INB(np, nc_sdid) & 0x0f; + struct sym_tcb *tp = &np->target[target]; int tmp; if (DEBUG_FLAGS & DEBUG_TINY) printf ("I#%d", num); @@ -4574,7 +4408,7 @@ static void sym_int_sir (hcb_p np) if (cp) { cp->xerr_status &= ~XE_PARITY_ERR; if (!cp->xerr_status) - OUTOFFB (HF_PRT, HF_EXT_ERR); + OUTOFFB(np, HF_PRT, HF_EXT_ERR); } } goto out; @@ -4604,7 +4438,7 @@ static void sym_int_sir (hcb_p np) */ case SIR_SWIDE_OVERRUN: if (cp) { - OUTONB (HF_PRT, HF_EXT_ERR); + OUTONB(np, HF_PRT, HF_EXT_ERR); cp->xerr_status |= XE_SWIDE_OVRUN; } goto out; @@ -4615,7 +4449,7 @@ static void sym_int_sir (hcb_p np) */ case SIR_SODL_UNDERRUN: if (cp) { - OUTONB (HF_PRT, HF_EXT_ERR); + OUTONB(np, HF_PRT, HF_EXT_ERR); cp->xerr_status |= XE_SODL_UNRUN; } goto out; @@ -4627,9 +4461,9 @@ static void sym_int_sir (hcb_p np) */ case SIR_DATA_OVERRUN: if (cp) { - OUTONB (HF_PRT, HF_EXT_ERR); + OUTONB(np, HF_PRT, HF_EXT_ERR); cp->xerr_status |= XE_EXTRA_DATA; - cp->extra_bytes += INL (nc_scratcha); + cp->extra_bytes += INL(np, nc_scratcha); } goto out; /* @@ -4637,7 +4471,7 @@ static void sym_int_sir (hcb_p np) */ case SIR_BAD_PHASE: if (cp) { - OUTONB (HF_PRT, HF_EXT_ERR); + OUTONB(np, HF_PRT, HF_EXT_ERR); cp->xerr_status |= XE_BAD_PHASE; } goto out; @@ -4657,7 +4491,7 @@ static void sym_int_sir (hcb_p np) switch (np->msgin [2]) { case M_X_MODIFY_DP: if (DEBUG_FLAGS & DEBUG_POINTER) - sym_print_msg(cp,"modify DP",np->msgin); + sym_print_msg(cp, NULL, np->msgin); tmp = (np->msgin[3]<<24) + (np->msgin[4]<<16) + (np->msgin[5]<<8) + (np->msgin[6]); sym_modify_dp(np, tp, cp, tmp); @@ -4684,18 +4518,18 @@ static void sym_int_sir (hcb_p np) */ case M_IGN_RESIDUE: if (DEBUG_FLAGS & DEBUG_POINTER) - sym_print_msg(cp,"ign wide residue", np->msgin); + sym_print_msg(cp, NULL, np->msgin); if (cp->host_flags & HF_SENSE) - OUTL_DSP (SCRIPTA_BA (np, clrack)); + OUTL_DSP(np, SCRIPTA_BA(np, clrack)); else sym_modify_dp(np, tp, cp, -1); return; case M_REJECT: - if (INB (HS_PRT) == HS_NEGOTIATE) + if (INB(np, HS_PRT) == HS_NEGOTIATE) sym_nego_rejected(np, tp, cp); else { - PRINT_ADDR(cp); - printf ("M_REJECT received (%x:%x).\n", + sym_print_addr(cp->cmd, + "M_REJECT received (%x:%x).\n", scr_to_cpu(np->lastmsg), np->msgout[0]); } goto out_clrack; @@ -4710,7 +4544,7 @@ static void sym_int_sir (hcb_p np) */ case SIR_MSG_WEIRD: sym_print_msg(cp, "WEIRD message received", np->msgin); - OUTL_DSP (SCRIPTB_BA (np, msg_weird)); + OUTL_DSP(np, SCRIPTB_BA(np, msg_weird)); return; /* * Negotiation failed. @@ -4718,7 +4552,7 @@ static void sym_int_sir (hcb_p np) * Remove the HS_NEGOTIATE status. */ case SIR_NEGO_FAILED: - OUTB (HS_PRT, HS_BUSY); + OUTB(np, HS_PRT, HS_BUSY); /* * Negotiation failed. * Target does not want answer message. @@ -4726,16 +4560,16 @@ static void sym_int_sir (hcb_p np) case SIR_NEGO_PROTO: sym_nego_default(np, tp, cp); goto out; - }; + } out: - OUTONB_STD (); + OUTONB_STD(); return; out_reject: - OUTL_DSP (SCRIPTB_BA (np, msg_bad)); + OUTL_DSP(np, SCRIPTB_BA(np, msg_bad)); return; out_clrack: - OUTL_DSP (SCRIPTA_BA (np, clrack)); + OUTL_DSP(np, SCRIPTA_BA(np, clrack)); return; out_stuck: return; @@ -4744,48 +4578,27 @@ out_stuck: /* * Acquire a control block */ -ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order) +struct sym_ccb *sym_get_ccb (struct sym_hcb *np, struct scsi_cmnd *cmd, u_char tag_order) { - tcb_p tp = &np->target[tn]; - lcb_p lp = sym_lp(np, tp, ln); + u_char tn = cmd->device->id; + u_char ln = cmd->device->lun; + struct sym_tcb *tp = &np->target[tn]; + struct sym_lcb *lp = sym_lp(tp, ln); u_short tag = NO_TAG; SYM_QUEHEAD *qp; - ccb_p cp = (ccb_p) 0; + struct sym_ccb *cp = NULL; /* * Look for a free CCB */ if (sym_que_empty(&np->free_ccbq)) - (void) sym_alloc_ccb(np); + sym_alloc_ccb(np); qp = sym_remque_head(&np->free_ccbq); if (!qp) goto out; cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); -#ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING - /* - * If the LCB is not yet available and the LUN - * has been probed ok, try to allocate the LCB. - */ - if (!lp && sym_is_bit(tp->lun_map, ln)) { - lp = sym_alloc_lcb(np, tn, ln); - if (!lp) - goto out_free; - } -#endif - - /* - * If the LCB is not available here, then the - * logical unit is not yet discovered. For those - * ones only accept 1 SCSI IO per logical unit, - * since we cannot allow disconnections. - */ - if (!lp) { - if (!sym_is_bit(tp->busy0_map, ln)) - sym_set_bit(tp->busy0_map, ln); - else - goto out_free; - } else { + { /* * If we have been asked for a tagged command. */ @@ -4794,7 +4607,8 @@ ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order) * Debugging purpose. */ #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING - assert(lp->busy_itl == 0); + if (lp->busy_itl != 0) + goto out_free; #endif /* * Allocate resources for tags if not yet. @@ -4818,7 +4632,7 @@ ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order) #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING lp->itlq_tbl[tag] = cpu_to_scr(cp->ccb_ba); lp->head.resel_sa = - cpu_to_scr(SCRIPTA_BA (np, resel_tag)); + cpu_to_scr(SCRIPTA_BA(np, resel_tag)); #endif #ifdef SYM_OPT_LIMIT_COMMAND_REORDERING cp->tags_si = lp->tags_si; @@ -4839,7 +4653,8 @@ ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order) * Debugging purpose. */ #ifndef SYM_OPT_HANDLE_DEVICE_QUEUEING - assert(lp->busy_itl == 0 && lp->busy_itlq == 0); + if (lp->busy_itl != 0 || lp->busy_itlq != 0) + goto out_free; #endif /* * Count this nexus for this LUN. @@ -4851,7 +4666,7 @@ ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order) if (lp->busy_itl == 1) { lp->head.itl_task_sa = cpu_to_scr(cp->ccb_ba); lp->head.resel_sa = - cpu_to_scr(SCRIPTA_BA (np, resel_no_tag)); + cpu_to_scr(SCRIPTA_BA(np, resel_no_tag)); } else goto out_free; @@ -4869,38 +4684,35 @@ ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order) } #endif - /* - * Remember all informations needed to free this CCB. - */ cp->to_abort = 0; + cp->odd_byte_adjustment = 0; cp->tag = tag; cp->order = tag_order; cp->target = tn; cp->lun = ln; if (DEBUG_FLAGS & DEBUG_TAGS) { - PRINT_LUN(np, tn, ln); - printf ("ccb @%p using tag %d.\n", cp, tag); + sym_print_addr(cmd, "ccb @%p using tag %d.\n", cp, tag); } out: return cp; out_free: sym_insque_head(&cp->link_ccbq, &np->free_ccbq); - return (ccb_p) 0; + return NULL; } /* * Release one control block */ -void sym_free_ccb (hcb_p np, ccb_p cp) +void sym_free_ccb (struct sym_hcb *np, struct sym_ccb *cp) { - tcb_p tp = &np->target[cp->target]; - lcb_p lp = sym_lp(np, tp, cp->lun); + struct sym_tcb *tp = &np->target[cp->target]; + struct sym_lcb *lp = sym_lp(tp, cp->lun); if (DEBUG_FLAGS & DEBUG_TAGS) { - PRINT_LUN(np, cp->target, cp->lun); - printf ("ccb @%p freeing tag %d.\n", cp, cp->tag); + sym_print_addr(cp->cmd, "ccb @%p freeing tag %d.\n", + cp, cp->tag); } /* @@ -4939,14 +4751,8 @@ void sym_free_ccb (hcb_p np, ccb_p cp) */ if (lp->busy_itlq == 0 && lp->busy_itl == 0) lp->head.resel_sa = - cpu_to_scr(SCRIPTB_BA (np, resel_bad_lun)); + cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun)); } - /* - * Otherwise, we only accept 1 IO per LUN. - * Clear the bit that keeps track of this IO. - */ - else - sym_clr_bit(tp->busy0_map, cp->lun); /* * We donnot queue more than 1 ccb per target @@ -4965,26 +4771,14 @@ void sym_free_ccb (hcb_p np, ccb_p cp) np->last_cp = 0; #endif - /* - * Unmap user data from DMA map if needed. - */ - sym_data_dmamap_unload(np, cp); - /* * Make this CCB available. */ - cp->cam_ccb = NULL; + cp->cmd = NULL; cp->host_status = HS_IDLE; sym_remque(&cp->link_ccbq); sym_insque_head(&cp->link_ccbq, &np->free_ccbq); -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - /* - * Cancel any pending timeout condition. - */ - sym_untimeout_ccb(np, cp); -#endif - #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING if (lp) { sym_remque(&cp->link2_ccbq); @@ -5003,9 +4797,9 @@ void sym_free_ccb (hcb_p np, ccb_p cp) /* * Allocate a CCB from memory and initialize its fixed part. */ -static ccb_p sym_alloc_ccb(hcb_p np) +static struct sym_ccb *sym_alloc_ccb(struct sym_hcb *np) { - ccb_p cp = NULL; + struct sym_ccb *cp = NULL; int hcode; /* @@ -5022,19 +4816,6 @@ static ccb_p sym_alloc_ccb(hcb_p np) if (!cp) goto out_free; - /* - * Allocate a bounce buffer for sense data. - */ - cp->sns_bbuf = sym_calloc_dma(SYM_SNS_BBUF_LEN, "SNS_BBUF"); - if (!cp->sns_bbuf) - goto out_free; - - /* - * Allocate a map for the DMA of user data. - */ - if (sym_data_dmamap_create(np, cp)) - goto out_free; - /* * Count it. */ @@ -5055,8 +4836,8 @@ static ccb_p sym_alloc_ccb(hcb_p np) /* * Initialyze the start and restart actions. */ - cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA (np, idle)); - cp->phys.head.go.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l)); + cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, idle)); + cp->phys.head.go.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l)); /* * Initilialyze some other fields. @@ -5071,29 +4852,23 @@ static ccb_p sym_alloc_ccb(hcb_p np) /* * Chain into optionnal lists. */ -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - sym_insque_head(&cp->tmo_linkq, &np->tmo0_ccbq); -#endif #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING sym_insque_head(&cp->link2_ccbq, &np->dummy_ccbq); #endif return cp; out_free: - if (cp) { - if (cp->sns_bbuf) - sym_mfree_dma(cp->sns_bbuf,SYM_SNS_BBUF_LEN,"SNS_BBUF"); + if (cp) sym_mfree_dma(cp, sizeof(*cp), "CCB"); - } return NULL; } /* * Look up a CCB from a DSA value. */ -static ccb_p sym_ccb_from_dsa(hcb_p np, u32 dsa) +static struct sym_ccb *sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa) { int hcode; - ccb_p cp; + struct sym_ccb *cp; hcode = CCB_HASH_CODE(dsa); cp = np->ccbh[hcode]; @@ -5110,7 +4885,7 @@ static ccb_p sym_ccb_from_dsa(hcb_p np, u32 dsa) * Target control block initialisation. * Nothing important to do at the moment. */ -static void sym_init_tcb (hcb_p np, u_char tn) +static void sym_init_tcb (struct sym_hcb *np, u_char tn) { #if 0 /* Hmmm... this checking looks paranoid. */ /* @@ -5126,23 +4901,10 @@ static void sym_init_tcb (hcb_p np, u_char tn) /* * Lun control block allocation and initialization. */ -lcb_p sym_alloc_lcb (hcb_p np, u_char tn, u_char ln) +struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln) { - tcb_p tp = &np->target[tn]; - lcb_p lp = sym_lp(np, tp, ln); - - /* - * Already done, just return. - */ - if (lp) - return lp; - - /* - * Donnot allow LUN control block - * allocation for not probed LUNs. - */ - if (!sym_is_bit(tp->lun_map, ln)) - return NULL; + struct sym_tcb *tp = &np->target[tn]; + struct sym_lcb *lp = NULL; /* * Initialize the target control block if not yet. @@ -5168,8 +4930,8 @@ lcb_p sym_alloc_lcb (hcb_p np, u_char tn, u_char ln) * Allocate the table of pointers for LUN(s) > 0, if needed. */ if (ln && !tp->lunmp) { - tp->lunmp = sym_calloc(SYM_CONF_MAX_LUN * sizeof(lcb_p), - "LUNMP"); + tp->lunmp = kcalloc(SYM_CONF_MAX_LUN, sizeof(struct sym_lcb *), + GFP_KERNEL); if (!tp->lunmp) goto fail; } @@ -5198,7 +4960,7 @@ lcb_p sym_alloc_lcb (hcb_p np, u_char tn, u_char ln) /* * Set the reselect pattern to our default. :) */ - lp->head.resel_sa = cpu_to_scr(SCRIPTB_BA (np, resel_bad_lun)); + lp->head.resel_sa = cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun)); /* * Set user capabilities. @@ -5214,13 +4976,7 @@ lcb_p sym_alloc_lcb (hcb_p np, u_char tn, u_char ln) lp->started_max = SYM_CONF_MAX_TASK; lp->started_limit = SYM_CONF_MAX_TASK; #endif - /* - * If we are busy, count the IO. - */ - if (sym_is_bit(tp->busy0_map, ln)) { - lp->busy_itl = 1; - sym_clr_bit(tp->busy0_map, ln); - } + fail: return lp; } @@ -5228,18 +4984,12 @@ fail: /* * Allocate LCB resources for tagged command queuing. */ -static void sym_alloc_lcb_tags (hcb_p np, u_char tn, u_char ln) +static void sym_alloc_lcb_tags (struct sym_hcb *np, u_char tn, u_char ln) { - tcb_p tp = &np->target[tn]; - lcb_p lp = sym_lp(np, tp, ln); + struct sym_tcb *tp = &np->target[tn]; + struct sym_lcb *lp = sym_lp(tp, ln); int i; - /* - * If LCB not available, try to allocate it. - */ - if (!lp && !(lp = sym_alloc_lcb(np, tn, ln))) - goto fail; - /* * Allocate the task table and and the tag allocation * circular buffer. We want both or none. @@ -5247,7 +4997,7 @@ static void sym_alloc_lcb_tags (hcb_p np, u_char tn, u_char ln) lp->itlq_tbl = sym_calloc_dma(SYM_CONF_MAX_TASK*4, "ITLQ_TBL"); if (!lp->itlq_tbl) goto fail; - lp->cb_tags = sym_calloc(SYM_CONF_MAX_TASK, "CB_TAGS"); + lp->cb_tags = kcalloc(SYM_CONF_MAX_TASK, 1, GFP_ATOMIC); if (!lp->cb_tags) { sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, "ITLQ_TBL"); lp->itlq_tbl = NULL; @@ -5280,38 +5030,36 @@ fail: /* * Queue a SCSI IO to the controller. */ -int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp) +int sym_queue_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp) { - tcb_p tp; - lcb_p lp; - u_char idmsg, *msgptr; + struct scsi_device *sdev = cmd->device; + struct sym_tcb *tp; + struct sym_lcb *lp; + u_char *msgptr; u_int msglen; + int can_disconnect; /* * Keep track of the IO in our CCB. */ - cp->cam_ccb = (cam_ccb_p) csio; + cp->cmd = cmd; /* - * Retreive the target descriptor. + * Retrieve the target descriptor. */ tp = &np->target[cp->target]; /* - * Retreive the lun descriptor. + * Retrieve the lun descriptor. */ - lp = sym_lp(np, tp, cp->lun); + lp = sym_lp(tp, sdev->lun); - /* - * Build the IDENTIFY message. - */ - idmsg = M_IDENTIFY | cp->lun; - if (cp->tag != NO_TAG || (lp && (lp->curr_flags & SYM_DISC_ENABLED))) - idmsg |= 0x40; + can_disconnect = (cp->tag != NO_TAG) || + (lp && (lp->curr_flags & SYM_DISC_ENABLED)); msgptr = cp->scsi_smsg; msglen = 0; - msgptr[msglen++] = idmsg; + msgptr[msglen++] = IDENTIFY(can_disconnect, sdev->lun); /* * Build the tag message if present. @@ -5339,8 +5087,8 @@ int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp) if (lp->tags_sum[lp->tags_si]) { order = M_ORDERED_TAG; if ((DEBUG_FLAGS & DEBUG_TAGS)||sym_verbose>1) { - PRINT_ADDR(cp); - printf("ordered tag forced.\n"); + sym_print_addr(cmd, + "ordered tag forced.\n"); } } lp->tags_since = 0; @@ -5367,19 +5115,15 @@ int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp) * (nego_status is filled by sym_prepare_nego()) */ cp->nego_status = 0; - if (tp->tinfo.curr.width != tp->tinfo.goal.width || - tp->tinfo.curr.period != tp->tinfo.goal.period || - tp->tinfo.curr.offset != tp->tinfo.goal.offset || - tp->tinfo.curr.options != tp->tinfo.goal.options) { - if (!tp->nego_cp && lp) - msglen += sym_prepare_nego(np, cp, 0, msgptr + msglen); + if (tp->tgoal.check_nego && !tp->nego_cp && lp) { + msglen += sym_prepare_nego(np, cp, msgptr + msglen); } /* * Startqueue */ - cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA (np, select)); - cp->phys.head.go.restart = cpu_to_scr(SCRIPTA_BA (np, resel_dsa)); + cp->phys.head.go.start = cpu_to_scr(SCRIPTA_BA(np, select)); + cp->phys.head.go.restart = cpu_to_scr(SCRIPTA_BA(np, resel_dsa)); /* * select @@ -5392,7 +5136,7 @@ int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp) /* * message */ - cp->phys.smsg.addr = cpu_to_scr(CCB_BA (cp, scsi_smsg)); + cp->phys.smsg.addr = CCB_BA(cp, scsi_smsg); cp->phys.smsg.size = cpu_to_scr(msglen); /* @@ -5416,15 +5160,15 @@ int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp) * Build the CDB and DATA descriptor block * and start the IO. */ - return sym_setup_data_and_start(np, csio, cp); + return sym_setup_data_and_start(np, cmd, cp); } /* * Reset a SCSI target (all LUNs of this target). */ -int sym_reset_scsi_target(hcb_p np, int target) +int sym_reset_scsi_target(struct sym_hcb *np, int target) { - tcb_p tp; + struct sym_tcb *tp; if (target == np->myaddr || (u_int)target >= SYM_CONF_MAX_TARGET) return -1; @@ -5433,7 +5177,7 @@ int sym_reset_scsi_target(hcb_p np, int target) tp->to_reset = 1; np->istat_sem = SEM; - OUTB (nc_istat, SIGP|SEM); + OUTB(np, nc_istat, SIGP|SEM); return 0; } @@ -5441,7 +5185,7 @@ int sym_reset_scsi_target(hcb_p np, int target) /* * Abort a SCSI IO. */ -int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out) +static int sym_abort_ccb(struct sym_hcb *np, struct sym_ccb *cp, int timed_out) { /* * Check that the IO is active. @@ -5467,13 +5211,13 @@ int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out) * Tell the SCRIPTS processor to stop and synchronize with us. */ np->istat_sem = SEM; - OUTB (nc_istat, SIGP|SEM); + OUTB(np, nc_istat, SIGP|SEM); return 0; } -int sym_abort_scsiio(hcb_p np, cam_ccb_p ccb, int timed_out) +int sym_abort_scsiio(struct sym_hcb *np, struct scsi_cmnd *cmd, int timed_out) { - ccb_p cp; + struct sym_ccb *cp; SYM_QUEHEAD *qp; /* @@ -5481,8 +5225,8 @@ int sym_abort_scsiio(hcb_p np, cam_ccb_p ccb, int timed_out) */ cp = NULL; FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { - ccb_p cp2 = sym_que_entry(qp, struct sym_ccb, link_ccbq); - if (cp2->cam_ccb == ccb) { + struct sym_ccb *cp2 = sym_que_entry(qp, struct sym_ccb, link_ccbq); + if (cp2->cmd == cmd) { cp = cp2; break; } @@ -5492,7 +5236,7 @@ int sym_abort_scsiio(hcb_p np, cam_ccb_p ccb, int timed_out) } /* - * Complete execution of a SCSI command with extented + * Complete execution of a SCSI command with extended * error, SCSI status error, or having been auto-sensed. * * The SCRIPTS processor is not running there, so we @@ -5501,38 +5245,40 @@ int sym_abort_scsiio(hcb_p np, cam_ccb_p ccb, int timed_out) * SCRATCHA is assumed to have been loaded with STARTPOS * before the SCRIPTS called the C code. */ -void sym_complete_error (hcb_p np, ccb_p cp) +void sym_complete_error(struct sym_hcb *np, struct sym_ccb *cp) { - tcb_p tp; - lcb_p lp; + struct scsi_device *sdev; + struct scsi_cmnd *cmd; + struct sym_tcb *tp; + struct sym_lcb *lp; int resid; int i; /* * Paranoid check. :) */ - if (!cp || !cp->cam_ccb) + if (!cp || !cp->cmd) return; + cmd = cp->cmd; + sdev = cmd->device; if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_RESULT)) { - printf ("CCB=%lx STAT=%x/%x/%x DEV=%d/%d\n", (unsigned long)cp, - cp->host_status, cp->ssss_status, cp->host_flags, - cp->target, cp->lun); - MDELAY(100); + dev_info(&sdev->sdev_gendev, "CCB=%p STAT=%x/%x/%x\n", cp, + cp->host_status, cp->ssss_status, cp->host_flags); } /* * Get target and lun pointers. */ tp = &np->target[cp->target]; - lp = sym_lp(np, tp, cp->lun); + lp = sym_lp(tp, sdev->lun); /* * Check for extended errors. */ if (cp->xerr_status) { if (sym_verbose) - sym_print_xerr(cp, cp->xerr_status); + sym_print_xerr(cmd, cp->xerr_status); if (cp->host_status == HS_COMPLETE) cp->host_status = HS_COMP_ERR; } @@ -5555,13 +5301,13 @@ if (resid) * Dequeue all queued CCBs for that device * not yet started by SCRIPTS. */ - i = (INL (nc_scratcha) - np->squeue_ba) / 4; - i = sym_dequeue_from_squeue(np, i, cp->target, cp->lun, -1); + i = (INL(np, nc_scratcha) - np->squeue_ba) / 4; + i = sym_dequeue_from_squeue(np, i, cp->target, sdev->lun, -1); /* * Restart the SCRIPTS processor. */ - OUTL_DSP (SCRIPTA_BA (np, start)); + OUTL_DSP(np, SCRIPTA_BA(np, start)); #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING if (cp->host_status == HS_COMPLETE && @@ -5575,8 +5321,8 @@ if (resid) lp->num_sgood = 0; if (sym_verbose >= 2) { - PRINT_LUN(np, cp->target, cp->lun); - printf(" queue depth is now %d\n", lp->started_max); + sym_print_addr(cmd, " queue depth is now %d\n", + lp->started_max); } /* @@ -5588,16 +5334,11 @@ if (resid) /* * Let's requeue it to device. */ - sym_set_cam_status(cp->cam_ccb, CAM_REQUEUE_REQ); + sym_set_cam_status(cmd, DID_SOFT_ERROR); goto finish; } weirdness: #endif - /* - * Synchronize DMA map if needed. - */ - sym_data_dmamap_postsync(np, cp); - /* * Build result in CAM ccb. */ @@ -5622,8 +5363,7 @@ finish: /* * Donnot start more than 1 command after an error. */ - if (lp) - sym_start_next_ccbs(np, lp, 1); + sym_start_next_ccbs(np, lp, 1); #endif } @@ -5636,49 +5376,43 @@ finish: * The SCRIPTS processor is running while we are * completing successful commands. */ -void sym_complete_ok (hcb_p np, ccb_p cp) +void sym_complete_ok (struct sym_hcb *np, struct sym_ccb *cp) { - tcb_p tp; - lcb_p lp; - cam_ccb_p ccb; + struct sym_tcb *tp; + struct sym_lcb *lp; + struct scsi_cmnd *cmd; int resid; /* * Paranoid check. :) */ - if (!cp || !cp->cam_ccb) + if (!cp || !cp->cmd) return; assert (cp->host_status == HS_COMPLETE); /* * Get user command. */ - ccb = cp->cam_ccb; + cmd = cp->cmd; /* * Get target and lun pointers. */ tp = &np->target[cp->target]; - lp = sym_lp(np, tp, cp->lun); - - /* - * Assume device discovered on first success. - */ - if (!lp) - sym_set_bit(tp->lun_map, cp->lun); + lp = sym_lp(tp, cp->lun); /* * If all data have been transferred, given than no * extended error did occur, there is no residual. */ resid = 0; - if (cp->phys.head.lastp != sym_goalp(cp)) + if (cp->phys.head.lastp != cp->goalp) resid = sym_compute_residual(np, cp); /* * Wrong transfer residuals may be worse than just always - * returning zero. User can disable this feature from - * sym_conf.h. Residual support is enabled by default. + * returning zero. User can disable this feature in + * sym53c8xx.h. Residual support is enabled by default. */ if (!SYM_SETUP_RESIDUAL_SUPPORT) resid = 0; @@ -5687,24 +5421,10 @@ if (resid) printf("XXXX RESID= %d - 0x%x\n", resid, resid); #endif - /* - * Synchronize DMA map if needed. - */ - sym_data_dmamap_postsync(np, cp); - /* * Build result in CAM ccb. */ - sym_set_cam_result_ok(np, cp, resid); - -#ifdef SYM_OPT_SNIFF_INQUIRY - /* - * On standard INQUIRY response (EVPD and CmDt - * not set), sniff out device capabilities. - */ - if (cp->cdb_buf[0] == INQUIRY && !(cp->cdb_buf[1] & 0x3)) - sym_sniff_inquiry(np, cp->cam_ccb, resid); -#endif + sym_set_cam_result_ok(cp, cmd, resid); #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING /* @@ -5717,8 +5437,7 @@ if (resid) lp->num_sgood = 0; ++lp->started_max; if (sym_verbose >= 2) { - PRINT_LUN(np, cp->target, cp->lun); - printf(" queue depth is now %d\n", + sym_print_addr(cmd, " queue depth is now %d\n", lp->started_max); } } @@ -5734,27 +5453,21 @@ if (resid) /* * Requeue a couple of awaiting scsi commands. */ - if (lp && !sym_que_empty(&lp->waiting_ccbq)) + if (!sym_que_empty(&lp->waiting_ccbq)) sym_start_next_ccbs(np, lp, 2); #endif /* * Complete the command. */ - sym_xpt_done(np, ccb); + sym_xpt_done(np, cmd); } /* * Soft-attach the controller. */ -#ifdef SYM_OPT_NVRAM_PRE_READ -int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram) -#else -int sym_hcb_attach(hcb_p np, struct sym_fw *fw) -#endif +int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram *nvram) { -#ifndef SYM_OPT_NVRAM_PRE_READ - struct sym_nvram nvram_buf, *nvram = &nvram_buf; -#endif + struct sym_hcb *np = sym_get_hcb(shost); int i; /* @@ -5778,20 +5491,13 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw) * that SCSI clock calibration may not work properly * if the chip is currently active. */ - sym_chip_reset (np); - - /* - * Try to read the user set-up. - */ -#ifndef SYM_OPT_NVRAM_PRE_READ - (void) sym_read_nvram(np, nvram); -#endif + sym_chip_reset(np); /* * Prepare controller and devices settings, according * to chip features, user set-up and driver set-up. */ - (void) sym_prepare_setting(np, nvram); + sym_prepare_setting(shost, np, nvram); /* * Check the PCI clock frequency. @@ -5806,7 +5512,7 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw) /* * Allocate the start queue. */ - np->squeue = (u32 *) sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"SQUEUE"); + np->squeue = sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"SQUEUE"); if (!np->squeue) goto attach_failed; np->squeue_ba = vtobus(np->squeue); @@ -5814,7 +5520,7 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw) /* * Allocate the done queue. */ - np->dqueue = (u32 *) sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"DQUEUE"); + np->dqueue = sym_calloc_dma(sizeof(u32)*(MAX_QUEUE*2),"DQUEUE"); if (!np->dqueue) goto attach_failed; np->dqueue_ba = vtobus(np->dqueue); @@ -5822,7 +5528,7 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw) /* * Allocate the target bus address array. */ - np->targtbl = (u32 *) sym_calloc_dma(256, "TARGTBL"); + np->targtbl = sym_calloc_dma(256, "TARGTBL"); if (!np->targtbl) goto attach_failed; np->targtbl_ba = vtobus(np->targtbl); @@ -5839,7 +5545,7 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw) /* * Allocate the array of lists of CCBs hashed by DSA. */ - np->ccbh = sym_calloc(sizeof(ccb_p *)*CCB_HASH_SIZE, "CCBH"); + np->ccbh = kcalloc(CCB_HASH_SIZE, sizeof(struct sym_ccb **), GFP_KERNEL); if (!np->ccbh) goto attach_failed; @@ -5851,17 +5557,9 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw) sym_que_init(&np->comp_ccbq); /* - * Initializations for optional handling - * of IO timeouts and device queueing. + * Initialization for optional handling + * of device queueing. */ -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - sym_que_init(&np->tmo0_ccbq); - np->tmo_ccbq = - sym_calloc(2*SYM_CONF_TIMEOUT_ORDER_MAX*sizeof(SYM_QUEHEAD), - "TMO_CCBQ"); - for (i = 0 ; i < 2*SYM_CONF_TIMEOUT_ORDER_MAX ; i++) - sym_que_init(&np->tmo_ccbq[i]); -#endif #ifdef SYM_OPT_HANDLE_DEVICE_QUEUEING sym_que_init(&np->dummy_ccbq); #endif @@ -5930,20 +5628,20 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw) /* * Prepare the idle and invalid task actions. */ - np->idletask.start = cpu_to_scr(SCRIPTA_BA (np, idle)); - np->idletask.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l)); + np->idletask.start = cpu_to_scr(SCRIPTA_BA(np, idle)); + np->idletask.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l)); np->idletask_ba = vtobus(&np->idletask); - np->notask.start = cpu_to_scr(SCRIPTA_BA (np, idle)); - np->notask.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l)); + np->notask.start = cpu_to_scr(SCRIPTA_BA(np, idle)); + np->notask.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l)); np->notask_ba = vtobus(&np->notask); - np->bad_itl.start = cpu_to_scr(SCRIPTA_BA (np, idle)); - np->bad_itl.restart = cpu_to_scr(SCRIPTB_BA (np, bad_i_t_l)); + np->bad_itl.start = cpu_to_scr(SCRIPTA_BA(np, idle)); + np->bad_itl.restart = cpu_to_scr(SCRIPTB_BA(np, bad_i_t_l)); np->bad_itl_ba = vtobus(&np->bad_itl); - np->bad_itlq.start = cpu_to_scr(SCRIPTA_BA (np, idle)); - np->bad_itlq.restart = cpu_to_scr(SCRIPTB_BA (np,bad_i_t_l_q)); + np->bad_itlq.start = cpu_to_scr(SCRIPTA_BA(np, idle)); + np->bad_itlq.restart = cpu_to_scr(SCRIPTB_BA(np,bad_i_t_l_q)); np->bad_itlq_ba = vtobus(&np->bad_itlq); /* @@ -5956,7 +5654,7 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw) if (!np->badluntbl) goto attach_failed; - np->badlun_sa = cpu_to_scr(SCRIPTB_BA (np, resel_bad_lun)); + np->badlun_sa = cpu_to_scr(SCRIPTB_BA(np, resel_bad_lun)); for (i = 0 ; i < 64 ; i++) /* 64 luns/target, no less */ np->badluntbl[i] = cpu_to_scr(vtobus(&np->badlun_sa)); @@ -5979,7 +5677,7 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw) if (sym_snooptest (np)) { printf("%s: CACHE INCORRECTLY CONFIGURED.\n", sym_name(np)); goto attach_failed; - }; + } /* * Sigh! we are done. @@ -5993,13 +5691,12 @@ attach_failed: /* * Free everything that has been allocated for this device. */ -void sym_hcb_free(hcb_p np) +void sym_hcb_free(struct sym_hcb *np) { SYM_QUEHEAD *qp; - ccb_p cp; - tcb_p tp; - lcb_p lp; - int target, lun; + struct sym_ccb *cp; + struct sym_tcb *tp; + int target; if (np->scriptz0) sym_mfree_dma(np->scriptz0, np->scriptz_sz, "SCRIPTZ0"); @@ -6007,12 +5704,6 @@ void sym_hcb_free(hcb_p np) sym_mfree_dma(np->scriptb0, np->scriptb_sz, "SCRIPTB0"); if (np->scripta0) sym_mfree_dma(np->scripta0, np->scripta_sz, "SCRIPTA0"); -#ifdef SYM_OPT_HANDLE_IO_TIMEOUT - if (np->tmo_ccbq) - sym_mfree(np->tmo_ccbq, - 2*SYM_CONF_TIMEOUT_ORDER_MAX*sizeof(SYM_QUEHEAD), - "TMO_CCBQ"); -#endif if (np->squeue) sym_mfree_dma(np->squeue, sizeof(u32)*(MAX_QUEUE*2), "SQUEUE"); if (np->dqueue) @@ -6021,36 +5712,18 @@ void sym_hcb_free(hcb_p np) if (np->actccbs) { while ((qp = sym_remque_head(&np->free_ccbq)) != 0) { cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); - sym_data_dmamap_destroy(np, cp); - sym_mfree_dma(cp->sns_bbuf, SYM_SNS_BBUF_LEN, - "SNS_BBUF"); sym_mfree_dma(cp, sizeof(*cp), "CCB"); } } - if (np->ccbh) - sym_mfree(np->ccbh, sizeof(ccb_p *)*CCB_HASH_SIZE, "CCBH"); + kfree(np->ccbh); if (np->badluntbl) sym_mfree_dma(np->badluntbl, 256,"BADLUNTBL"); for (target = 0; target < SYM_CONF_MAX_TARGET ; target++) { tp = &np->target[target]; - for (lun = 0 ; lun < SYM_CONF_MAX_LUN ; lun++) { - lp = sym_lp(np, tp, lun); - if (!lp) - continue; - if (lp->itlq_tbl) - sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK*4, - "ITLQ_TBL"); - if (lp->cb_tags) - sym_mfree(lp->cb_tags, SYM_CONF_MAX_TASK, - "CB_TAGS"); - sym_mfree_dma(lp, sizeof(*lp), "LCB"); - } #if SYM_CONF_MAX_LUN > 1 - if (tp->lunmp) - sym_mfree(tp->lunmp, SYM_CONF_MAX_LUN*sizeof(lcb_p), - "LUNMP"); + kfree(tp->lunmp); #endif } if (np->targtbl)