X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fsym53c8xx_2%2Fsym_hipd.c;h=8b7aa921e487aa6b78195b5cdadc9b7c3e6625b2;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;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..8b7aa921e 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-2004 Matthew Wilcox * * This driver is derived from the Linux sym53c8xx driver. * Copyright (C) 1998-2000 Gerard Roudier @@ -22,32 +23,19 @@ * *----------------------------------------------------------------------------- * - * 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 "sym_glue.h" #include "sym_nvram.h" @@ -59,14 +47,14 @@ /* * 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 ccb_p sym_alloc_ccb(struct sym_hcb *np); +static ccb_p 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, ccb_p cp); +static void sym_complete_ok (struct sym_hcb *np, ccb_p cp); +static int sym_compute_residual(struct sym_hcb *np, ccb_p cp); /* * Returns the name of this driver. @@ -98,12 +86,12 @@ static void sym_printl_hex (char *label, u_char *p, int 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) +static void sym_print_target (struct sym_hcb *np, int target) { printf ("%s:%d:", sym_name(np), target); } -static void sym_print_lun(hcb_p np, int target, int lun) +static void sym_print_lun(struct sym_hcb *np, int target, int lun) { printf ("%s:%d:%d:", sym_name(np), target, lun); } @@ -138,7 +126,7 @@ static void sym_print_msg (ccb_p cp, char *label, u_char *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) @@ -196,7 +184,7 @@ 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); @@ -213,7 +201,7 @@ 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; @@ -246,12 +234,12 @@ 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); } -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; @@ -299,14 +287,13 @@ int sym_reset_scsi_bus(hcb_p np, int enab_int) } out: OUTB (nc_scntl1, 0); - /* MDELAY(100); */ 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. @@ -361,7 +348,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; @@ -433,7 +420,7 @@ 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; @@ -448,7 +435,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; @@ -505,7 +492,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; @@ -541,7 +528,7 @@ static u32 div_10M[] = {2*_5M, 3*_5M, 4*_5M, 6*_5M, 8*_5M, 12*_5M, 16*_5M}; * 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 +648,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); @@ -681,7 +668,7 @@ 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) +static void sym_print_targets_flag(struct sym_hcb *np, int mask, char *msg) { int cnt; int i; @@ -709,7 +696,7 @@ 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; @@ -729,44 +716,11 @@ static void sym_save_initial_setting (hcb_p np) np->sv_ctest5 = INB(nc_ctest5) & 0x24; } -#ifdef CONFIG_PARISC -static u32 parisc_setup_hcb(hcb_p np, u32 period) -{ - 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; - } - } - - return (u32) pdc_period; -} -#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 sym_hcb *np, struct sym_nvram *nvram) { u_char burst_max; u32 period; @@ -829,8 +783,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 +845,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 +869,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); @@ -1013,7 +965,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; @@ -1104,7 +1056,7 @@ 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) +static int sym_regtest (struct sym_hcb *np) { register volatile u32 data; /* @@ -1128,7 +1080,7 @@ static int sym_regtest (hcb_p np) } #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; @@ -1254,7 +1206,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; @@ -1312,85 +1264,85 @@ static void sym_log_hard_error(hcb_p np, u_short sist, u_char dstat) } static struct sym_pci_chip sym_pci_dev_table[] = { - {PCI_ID_SYM53C810, 0x0f, "810", 4, 8, 4, 64, + {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} }; @@ -1428,7 +1380,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 +1413,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; @@ -1476,13 +1428,12 @@ static void sym_update_dmap_regs(hcb_p np) } #endif +/* Enforce all the fiddly SPI rules and the chip limitations */ static void sym_check_goals(struct scsi_device *sdev) { 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; @@ -1492,7 +1443,7 @@ static void sym_check_goals(struct scsi_device *sdev) st->offset = 0; return; } - + if (scsi_device_dt(sdev)) { if (scsi_device_dt_only(sdev)) st->options |= PPR_OPT_DT; @@ -1503,7 +1454,8 @@ static void sym_check_goals(struct scsi_device *sdev) st->options &= ~PPR_OPT_DT; } - if (!(np->features & FE_ULTRA3)) + /* Some targets fail to properly negotiate DT in SE mode */ + if ((np->scsi_mode != SMODE_LVD) || !(np->features & FE_U3EN)) st->options &= ~PPR_OPT_DT; if (st->options & PPR_OPT_DT) { @@ -1516,6 +1468,7 @@ static void sym_check_goals(struct scsi_device *sdev) if (st->period > np->maxsync_dt) st->period = np->maxsync_dt; } else { + st->options &= ~PPR_OPT_MASK; if (st->offset > np->maxoffs) st->offset = np->maxoffs; if (st->period < np->minsync) @@ -1523,7 +1476,7 @@ static void sym_check_goals(struct scsi_device *sdev) if (st->period > np->maxsync) st->period = np->maxsync; } -} +} /* * Prepare the next negotiation message if needed. @@ -1532,38 +1485,31 @@ 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, ccb_p cp, u_char *msgptr) { tcb_p tp = &np->target[cp->target]; - int msglen = 0; struct scsi_device *sdev = tp->sdev; + struct sym_trans *goal = &tp->tinfo.goal; + struct sym_trans *curr = &tp->tinfo.curr; + int msglen = 0; + int nego; if (likely(sdev)) sym_check_goals(sdev); /* - * 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->options & PPR_OPT_MASK) || (goal->period < 0xa)) { nego = NS_PPR; + } else if (curr->width != goal->width) { + nego = NS_WIDE; + } else if (curr->period != goal->period || + curr->offset != 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; + nego = 0; } switch (nego) { @@ -1571,24 +1517,24 @@ static int sym_prepare_nego(hcb_p np, ccb_p cp, int nego, u_char *msgptr) 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; + msgptr[msglen++] = goal->period; + msgptr[msglen++] = 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; + 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++] = 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; + msgptr[msglen++] = goal->offset; + msgptr[msglen++] = goal->width; + msgptr[msglen++] = goal->options & PPR_OPT_MASK; break; }; @@ -1610,7 +1556,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, ccb_p cp) { u_short qidx; @@ -1641,13 +1587,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. @@ -1676,7 +1615,7 @@ void sym_put_start_queue(hcb_p np, ccb_p cp) /* * 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, lcb_p lp, int maxn) { SYM_QUEHEAD *qp; ccb_p cp; @@ -1730,7 +1669,7 @@ 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; int i, n; @@ -1763,11 +1702,65 @@ 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; + ccb_p cp; + + while ((qp = sym_remque_head(&np->comp_ccbq)) != 0) { + struct scsi_cmnd *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); + } +} + /* * 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 +1779,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; @@ -1877,7 +1870,7 @@ void sym_start_up (hcb_p np, int reason) /* * For now, disable AIP generation on C1010-66. */ - if (np->device_id == PCI_ID_LSI53C1010_66) + if (np->device_id == PCI_DEVICE_ID_LSI_53C1010_66) OUTB (nc_aipcntl1, DISAIP); /* @@ -1887,7 +1880,7 @@ 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); @@ -1896,9 +1889,9 @@ void sym_start_up (hcb_p np, int reason) * Disable overlapped arbitration for some dual function devices, * regardless revision id (kind of post-chip-design feature. ;-)) */ - if (np->device_id == PCI_ID_SYM53C875) + if (np->device_id == PCI_DEVICE_ID_NCR_53C875) OUTB (nc_ctest0, (1<<5)); - else if (np->device_id == PCI_ID_SYM53C896) + else if (np->device_id == PCI_DEVICE_ID_NCR_53C896) np->rv_ccntl0 |= DPR; /* @@ -1955,7 +1948,7 @@ void sym_start_up (hcb_p np, int reason) if (np->features & (FE_ULTRA2|FE_ULTRA3)) { OUTONW (nc_sien, SBMC); if (reason == 0) { - MDELAY(100); + mdelay(100); INW (nc_sist); } np->scsi_mode = INB (nc_stest4) & SMODE; @@ -2022,7 +2015,7 @@ void sym_start_up (hcb_p np, int reason) /* * Switch trans mode for current job and it's 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; @@ -2073,7 +2066,7 @@ 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; } @@ -2131,7 +2124,7 @@ 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]; @@ -2150,7 +2143,7 @@ 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]; @@ -2176,17 +2169,17 @@ 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]; - 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; + tp->tinfo.goal.options = tp->tinfo.curr.options = opts; sym_xpt_async_nego_ppr(np, target); } @@ -2217,7 +2210,7 @@ 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); @@ -2268,7 +2261,7 @@ 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); @@ -2283,7 +2276,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,7 +2292,7 @@ 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; @@ -2340,7 +2333,7 @@ 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); @@ -2428,7 +2421,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; @@ -2747,7 +2740,7 @@ unexpected_phase: 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; + np->msgout[0] = IDENTIFY(0, cp->lun); nxtdsp = SCRIPTB_BA (np, ident_break_atn); } else @@ -2838,7 +2831,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; @@ -2993,7 +2986,7 @@ unknown_int: * 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; @@ -3036,60 +3029,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,14 +3047,13 @@ 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, ccb_p 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; /* @@ -3176,10 +3114,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,16 +3128,7 @@ 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. */ @@ -3228,7 +3154,7 @@ 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); + memset(cp->sns_bbuf, 0, SYM_SNS_BBUF_LEN); cp->phys.sense.addr = cpu_to_scr(vtobus(cp->sns_bbuf)); cp->phys.sense.size = cpu_to_scr(SYM_SNS_BBUF_LEN); @@ -3278,7 +3204,7 @@ 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; @@ -3297,7 +3223,7 @@ 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 *ccb; cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); ccb = cp->cam_ccb; if (cp->host_status != HS_DISCONNECT || @@ -3361,7 +3287,7 @@ 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; @@ -3538,8 +3464,8 @@ static void sym_sir_task_recovery(hcb_p np, int num) */ 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; + 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 +3506,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 +3517,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; @@ -3714,7 +3639,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, ccb_p cp, u32 scr, int *ofs) { u32 dp_scr; int dp_ofs, dp_sg, dp_sgmin; @@ -3832,7 +3757,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, tcb_p tp, ccb_p cp, int ofs) { int dp_ofs = ofs; u32 dp_scr = sym_get_script_dp (np, cp); @@ -3931,7 +3856,7 @@ out_reject: * a relevant information. :) */ -int sym_compute_residual(hcb_p np, ccb_p cp) +int sym_compute_residual(struct sym_hcb *np, ccb_p cp) { int dp_sg, dp_sgmin, resid = 0; int dp_ofs = 0; @@ -4031,7 +3956,7 @@ 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, int target) { u_char chg, ofs, per, fak, div; @@ -4112,7 +4037,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, tcb_p tp, ccb_p cp) { int req = 1; int result; @@ -4149,23 +4074,20 @@ reject_it: * 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; + 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. @@ -4175,29 +4097,30 @@ sym_ppr_nego_check(hcb_p np, int req, int target) wide = np->maxwide; } if (!wide || !(np->features & FE_ULTRA3)) - dt &= ~PPR_OPT_DT; + opts = 0; if (!(np->features & FE_U3EN)) /* Broken U3EN bit not supported */ - dt &= ~PPR_OPT_DT; + opts = 0; - if (dt != (np->msgin[7] & PPR_OPT_MASK)) chg = 1; + if (opts != (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 +4140,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. @@ -4235,7 +4158,7 @@ sym_ppr_nego_check(hcb_p np, int req, int target) np->msgout[4] = 0; np->msgout[5] = ofs; np->msgout[6] = wide; - np->msgout[7] = dt; + np->msgout[7] = opts; if (DEBUG_FLAGS & DEBUG_NEGO) { sym_print_nego_msg(np, target, "ppr msgout", np->msgout); @@ -4251,7 +4174,7 @@ 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) { + if (!req && !opts) { tp->tinfo.goal.options = 0; tp->tinfo.goal.width = wide; tp->tinfo.goal.period = per; @@ -4260,7 +4183,7 @@ reject_it: 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, tcb_p tp, ccb_p cp) { int req = 1; int result; @@ -4297,7 +4220,7 @@ reject_it: * 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, int target) { u_char chg, wide; @@ -4362,7 +4285,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, tcb_p tp, ccb_p cp) { int req = 1; int result; @@ -4431,7 +4354,7 @@ 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, tcb_p tp, ccb_p cp) { switch (cp->nego_status) { case NS_PPR: @@ -4461,7 +4384,7 @@ 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, tcb_p tp, ccb_p cp) { sym_nego_default(np, tp, cp); OUTB (HS_PRT, HS_BUSY); @@ -4470,7 +4393,7 @@ static void sym_nego_rejected(hcb_p np, tcb_p tp, ccb_p cp) /* * 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); @@ -4744,7 +4667,7 @@ out_stuck: /* * Acquire a control block */ -ccb_p sym_get_ccb (hcb_p np, u_char tn, u_char ln, u_char tag_order) +ccb_p sym_get_ccb (struct sym_hcb *np, u_char tn, u_char ln, u_char tag_order) { tcb_p tp = &np->target[tn]; lcb_p lp = sym_lp(np, tp, ln); @@ -4893,7 +4816,7 @@ out_free: /* * Release one control block */ -void sym_free_ccb (hcb_p np, ccb_p cp) +void sym_free_ccb (struct sym_hcb *np, ccb_p cp) { tcb_p tp = &np->target[cp->target]; lcb_p lp = sym_lp(np, tp, cp->lun); @@ -4978,13 +4901,6 @@ void sym_free_ccb (hcb_p np, ccb_p cp) 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,7 +4919,7 @@ 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 ccb_p sym_alloc_ccb(struct sym_hcb *np) { ccb_p cp = NULL; int hcode; @@ -5071,9 +4987,6 @@ 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 @@ -5090,7 +5003,7 @@ out_free: /* * Look up a CCB from a DSA value. */ -static ccb_p sym_ccb_from_dsa(hcb_p np, u32 dsa) +static ccb_p sym_ccb_from_dsa(struct sym_hcb *np, u32 dsa) { int hcode; ccb_p cp; @@ -5110,7 +5023,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,7 +5039,7 @@ 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) +lcb_p 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); @@ -5228,7 +5141,7 @@ 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); @@ -5280,38 +5193,35 @@ 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 *csio, ccb_p cp) { tcb_p tp; lcb_p lp; - u_char idmsg, *msgptr; + 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->cam_ccb = csio; /* - * 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); - /* - * 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, cp->lun); /* * Build the tag message if present. @@ -5372,7 +5282,7 @@ int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p cp) 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); + msglen += sym_prepare_nego(np, cp, msgptr + msglen); } /* @@ -5422,7 +5332,7 @@ int sym_queue_scsiio(hcb_p np, cam_scsiio_p csio, ccb_p 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; @@ -5441,7 +5351,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) +int sym_abort_ccb(struct sym_hcb *np, ccb_p cp, int timed_out) { /* * Check that the IO is active. @@ -5471,7 +5381,7 @@ int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out) 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 *ccb, int timed_out) { ccb_p cp; SYM_QUEHEAD *qp; @@ -5501,7 +5411,7 @@ 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, ccb_p cp) { tcb_p tp; lcb_p lp; @@ -5518,7 +5428,6 @@ void sym_complete_error (hcb_p np, ccb_p cp) 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); } /* @@ -5636,11 +5545,11 @@ 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, ccb_p cp) { tcb_p tp; lcb_p lp; - cam_ccb_p ccb; + struct scsi_cmnd *ccb; int resid; /* @@ -5746,15 +5655,8 @@ if (resid) /* * 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 sym_hcb *np, struct sym_fw *fw, struct sym_nvram *nvram) { -#ifndef SYM_OPT_NVRAM_PRE_READ - struct sym_nvram nvram_buf, *nvram = &nvram_buf; -#endif int i; /* @@ -5780,13 +5682,6 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw) */ sym_chip_reset (np); - /* - * Try to read the user set-up. - */ -#ifndef SYM_OPT_NVRAM_PRE_READ - (void) sym_read_nvram(np, nvram); -#endif - /* * Prepare controller and devices settings, according * to chip features, user set-up and driver set-up. @@ -5851,17 +5746,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 @@ -5993,7 +5880,7 @@ 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; @@ -6007,12 +5894,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)