? .config ? .dc395x_trm.o.d ? .dc395x_trm.o.flags ? .dc395x_trm.o.tmp ? .kversion ? Rules.make ? dc395_mess.txt ? dc395x_trm.c.126 ? dc395x_trm.c.131 ? dc395x_trm.c.debug_nmi ? dc395x_trm.c.new ? dc395x_trm.h.131 Index: Makefile =================================================================== RCS file: /home/cvsroot/dc395/Makefile,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Makefile 2000/05/16 13:48:10 1.1 +++ Makefile 2002/06/21 09:57:38 1.2 @@ -1,30 +1,39 @@ # Makefile for the dc395x_trm (TRM-S1040 chip on Tekram DC3x5) driver # (w) 5/2000, garloff@suse.de +ifndef TOPDIR KDIR := /usr/src/linux -TARGETS := Rules.make arch dc395x_trm.o +TARGETS := Rules.make arch .config dc395x_trm.o .PHONY: dc395x_trm.o default: $(TARGETS) +module: $(TARGETS) - Rules.make: $(KDIR)/Rules.make cp -pf $(KDIR)/Rules.make . arch: $(KDIR)/arch rm -f arch ln -s $(KDIR)/arch . - + +.config: $(KDIR)/.config + cp -pf $(KDIR)/.config . + clean: rm -f $(TARGETS) - + +ifdef FORCE_NEW_EH + EDEFS="FORCE_NEW_EH=1" +endif + dc395x_trm.o: - $(MAKE) -f Makefile.dc395 KDIR=$(KDIR) + $(MAKE) -f Makefile.dc395 KDIR=$(KDIR) $(EDEFS) install: - $(MAKE) -f Makefile.dc395 KDIR=$(KDIR) install_mod + $(MAKE) -f Makefile.dc395 KDIR=$(KDIR) $(EDEFS) install_mod load: - $(MAKE) -f Makefile.dc395 KDIR=$(KDIR) load_module - + $(MAKE) -f Makefile.dc395 KDIR=$(KDIR) $(EDEFS) load_module + +endif Index: Makefile.dc395 =================================================================== RCS file: /home/cvsroot/dc395/Makefile.dc395,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- Makefile.dc395 2002/05/10 17:17:53 1.5 +++ Makefile.dc395 2002/06/21 09:57:38 1.6 @@ -18,14 +18,22 @@ CFLAGS += -DMODVERSIONS -include $(KDIR)/include/linux/modversions.h endif +ifdef FORCE_NEW_EH +CFLAGS += -DFORCE_NEW_EH=1 +endif + dc395x_trm.o: dc395x_trm.c dc395x_trm.h arch Rules.make # 2.4 and later define PERL in the Makefile #ifdef PERL ifeq ($(PATCHLEVEL),4) -MODLIB := $(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)/kernel/drivers + MODLIB := $(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)/kernel/drivers else -MODLIB := $(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) + ifeq ($(PATCHLEVEL),5) + MODLIB := $(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)/kernel/drivers + else + MODLIB := $(DESTDIR)$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) + endif endif install_mod: $(MODLIB)/$(TARGETMODDIR)/dc395x_trm.o @@ -50,6 +58,7 @@ rmmod dc395x_trm; fi; \ echo "Load dc395x_trm"; modprobe dc395x_trm; \ else \ + sync; \ echo "Give root password for loading of kernel module"; \ su -c \ 'if test ! -z "$(shell lsmod | grep dc395x_trm)"; then echo "Remove dc395x_trm"; \ Index: dc395-integ25.diff =================================================================== RCS file: /home/cvsroot/dc395/dc395-integ25.diff,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- dc395-integ25.diff 2002/02/28 05:07:04 1.1 +++ dc395-integ25.diff 2002/06/21 07:13:58 1.2 @@ -1,5 +1,5 @@ -diff -uNr linux-2.5.5-dj2/MAINTAINERS linux-2.5.5-dj2-dc395/MAINTAINERS ---- linux-2.5.5-dj2/MAINTAINERS Wed Feb 27 12:22:08 2002 +diff -uNr linux/MAINTAINERS linux-2.5.5-dj2-dc395/MAINTAINERS +--- linux/MAINTAINERS Wed Feb 27 12:22:08 2002 +++ linux-2.5.5-dj2-dc395/MAINTAINERS Thu Feb 28 06:03:55 2002 @@ -402,10 +402,12 @@ L: linux-hams@vger.kernel.org @@ -16,10 +16,10 @@ S: Maintained DECnet NETWORK LAYER -diff -uNr linux-2.5.5-dj2/drivers/scsi/Config.help linux-2.5.5-dj2-dc395/drivers/scsi/Config.help ---- linux-2.5.5-dj2/drivers/scsi/Config.help Wed Feb 27 12:22:09 2002 +diff -uNr linux/drivers/scsi/Config.help linux-2.5.5-dj2-dc395/drivers/scsi/Config.help +--- linux/drivers/scsi/Config.help Wed Feb 27 12:22:09 2002 +++ linux-2.5.5-dj2-dc395/drivers/scsi/Config.help Thu Feb 28 06:03:39 2002 -@@ -1137,6 +1137,18 @@ +@@ -1135,6 +1135,18 @@ say M here and read . The module will be called sim710.o. @@ -38,10 +38,10 @@ CONFIG_SCSI_DC390T This driver supports PCI SCSI host adapters based on the Am53C974A chip, e.g. Tekram DC390(T), DawiControl 2974 and some onboard -diff -uNr linux-2.5.5-dj2/drivers/scsi/Config.in linux-2.5.5-dj2-dc395/drivers/scsi/Config.in ---- linux-2.5.5-dj2/drivers/scsi/Config.in Wed Feb 27 12:22:09 2002 +diff -uNr linux/drivers/scsi/Config.in linux-2.5.5-dj2-dc395/drivers/scsi/Config.in +--- linux/drivers/scsi/Config.in Wed Feb 27 12:22:09 2002 +++ linux-2.5.5-dj2-dc395/drivers/scsi/Config.in Thu Feb 28 06:03:55 2002 -@@ -185,6 +185,9 @@ +@@ -183,6 +183,9 @@ dep_tristate 'Simple 53c710 SCSI support (Compaq, NCR machines)' CONFIG_SCSI_SIM710 $CONFIG_SCSI dep_tristate 'Symbios 53c416 SCSI support' CONFIG_SCSI_SYM53C416 $CONFIG_SCSI if [ "$CONFIG_PCI" = "y" ]; then @@ -51,10 +51,10 @@ dep_tristate 'Tekram DC390(T) and Am53/79C974 SCSI support' CONFIG_SCSI_DC390T $CONFIG_SCSI if [ "$CONFIG_SCSI_DC390T" != "n" ]; then bool ' _omit_ support for non-DC390 adapters' CONFIG_SCSI_DC390T_NOGENSUPP -diff -uNr linux-2.5.5-dj2/drivers/scsi/Makefile linux-2.5.5-dj2-dc395/drivers/scsi/Makefile ---- linux-2.5.5-dj2/drivers/scsi/Makefile Wed Feb 27 12:22:09 2002 +diff -uNr linux/drivers/scsi/Makefile linux-2.5.5-dj2-dc395/drivers/scsi/Makefile +--- linux/drivers/scsi/Makefile Wed Feb 27 12:22:09 2002 +++ linux-2.5.5-dj2-dc395/drivers/scsi/Makefile Thu Feb 28 06:03:55 2002 -@@ -104,6 +104,7 @@ +@@ -100,6 +100,7 @@ obj-$(CONFIG_SCSI_IBMMCA) += ibmmca.o obj-$(CONFIG_SCSI_EATA) += eata.o obj-$(CONFIG_SCSI_DC390T) += tmscsim.o Index: dc395x_trm.c =================================================================== RCS file: /home/cvsroot/dc395/dc395x_trm.c,v retrieving revision 1.81 retrieving revision 1.87 diff -u -r1.81 -r1.87 --- dc395x_trm.c 2002/05/10 17:17:53 1.81 +++ dc395x_trm.c 2002/06/21 14:48:06 1.87 @@ -12,7 +12,7 @@ //* Kurt Garloff //* (C) 1999-2000 Kurt Garloff //* License: GNU GPL -//* $Id: dc395x_trm.c,v 1.81 2002/05/10 17:17:53 garloff Exp $ +//* $Id: dc395x_trm.c,v 1.87 2002/06/21 14:48:06 garloff Exp $ //*********************************************************************** //* Tekram PCI SCSI adapter (DC395/U/UW/F or DC315/U) revision history //* @@ -109,6 +109,10 @@ //* 1.39 02/04/24 KG PAGE_ADDRESS for pre2.4.16 kernels //* Locking in IRQ handler (thx to Paul Rolland) //* 1.40 02/05/10 KG Init tmpSRB debugtrace buffer, fix double free of DCBs +//* 1.40a02/05/12 KG Doug Gilbert: Support new EH +//* 1.41 02/06/21 KG Keith Owens: Avoid unaligned acceses (iA64) +//* Add DC395x_eh_abort() handler. +//* Clean up pci mappings in abort/SRBdone. //*********************************************************************** /* ************************************************************************* @@ -249,10 +253,16 @@ #endif #include "scsi.h" #include "hosts.h" -#include "constants.h" +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,21) +# include "constants.h" +#endif #include "sd.h" #include "dc395x_trm.h" +#ifdef USE_NEW_EH +static int DC395x_reset(Scsi_Cmnd *cmd, unsigned int resetFlags); +#endif + #ifdef DC395x_DEBUGMALLOC inline void* dc395x_kmalloc (size_t sz, int fl) { @@ -357,16 +367,16 @@ # define DC395x_DRV_UNLOCK(drv_flags) do { restore_flags(drv_flags); } while (0) #define DC395x_read8(address) \ - (inb (pACB->IOPortBase + (address))) + (u8)(inb (pACB->IOPortBase + (address))) #define DC395x_read8_(address, base) \ - (inb ((USHORT)(base) + (address))) + (u8)(inb ((USHORT)(base) + (address))) #define DC395x_read16(address) \ - (inw (pACB->IOPortBase + (address))) + (u16)(inw (pACB->IOPortBase + (address))) #define DC395x_read32(address) \ - (inl (pACB->IOPortBase + (address))) + (u32)(inl (pACB->IOPortBase + (address))) #define DC395x_write8(address,value) \ outb ((value), pACB->IOPortBase + (address)) @@ -388,7 +398,7 @@ # define PCI_UNMAP_SG(hw,sg,n,dir) pci_unmap_sg(hw,sg,n,dir) # define PCI_DMA_SYNC_SINGLE(hw,dma,sz,dir) pci_dma_sync_single(hw,dma,sz,dir) # define PCI_DMA_SYNC_SG(hw,sg,n,dir) pci_dma_sync_sg(hw,sg,n,dir) -# define BUS_ADDR(sg) ((sg).dma_address) +# define BUS_ADDR(sg) sg_dma_address(&(sg)) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) # define CPU_ADDR(sg) (page_address((sg).page)+(sg).offset) # define PAGE_ADDRESS(sg) page_address((sg)->page) @@ -1206,6 +1216,10 @@ /* **************************************** */ +#define TRM_S1040_DMA_FIFOSTAT 0xA2 /* DMA FIFO Status (R) */ +/* +**************************************** +*/ #define TRM_S1040_DMA_STATUS 0xA3 /* DMA Interrupt Status (R/W) */ /* ######### */ #define XFERPENDING 0x80 /* Transfer pending */ @@ -1419,8 +1433,10 @@ void DC395x_Reselect( PACB pACB ); BYTE DC395x_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB ); static void DC395x_BuildSRB(Scsi_Cmnd* pcmd, PDCB pDCB, PSRB pSRB); - void DC395x_DoingSRB_Done( PACB pACB, BYTE did_code); + void DC395x_DoingSRB_Done( PACB pACB, BYTE did_code, Scsi_Cmnd* pcmd, BYTE force); static void DC395x_ScsiRstDetect( PACB pACB ); +static void DC395x_pci_unmap (PACB pACB, PSRB pSRB); +static void DC395x_pci_unmap_sense (PACB pACB, PSRB pSRB); //static void DC395x_printMsg (BYTE *MsgBuf, DWORD len); static inline void DC395x_EnableMsgOut_Abort ( PACB pACB, PSRB pSRB ); //static inline void DC395x_EnableMsgOutAbort1( PACB pACB, PSRB pSRB ); @@ -2474,10 +2490,10 @@ DC395x_read8 (TRM_S1040_SCSI_CONFIG2), DC395x_read8 (TRM_S1040_SCSI_COMMAND), DC395x_read8 (TRM_S1040_SCSI_TIMEOUT)); printk ("DC395x: dump: DMA block\n"); - printk (" Cmd %04x FIFOCnt %04x IRQStat %02x IRQEn %02x Cfg %04x\n", - DC395x_read16 (TRM_S1040_DMA_COMMAND), DC395x_read16 (TRM_S1040_DMA_FIFOCNT), - DC395x_read8 (TRM_S1040_DMA_STATUS), DC395x_read8 (TRM_S1040_DMA_INTEN), - DC395x_read16 (TRM_S1040_DMA_CONFIG)); + printk (" Cmd %04x FIFOCnt %02x FStat %02x IRQStat %02x IRQEn %02x Cfg %04x\n", + DC395x_read16 (TRM_S1040_DMA_COMMAND), DC395x_read8 (TRM_S1040_DMA_FIFOCNT), + DC395x_read8 (TRM_S1040_DMA_FIFOSTAT), DC395x_read8 (TRM_S1040_DMA_STATUS), + DC395x_read8 (TRM_S1040_DMA_INTEN), DC395x_read16 (TRM_S1040_DMA_CONFIG)); printk (" TCtr %08x CTCtr %08x Addr %08x%08x\n", DC395x_read32 (TRM_S1040_DMA_XCNT), DC395x_read32 (TRM_S1040_DMA_CXCNT), DC395x_read32 (TRM_S1040_DMA_XHIGHADDR), DC395x_read32 (TRM_S1040_DMA_XLOWADDR)); @@ -2490,6 +2506,7 @@ } +#ifdef OLD_EH static int DC395x_recover (PACB pACB, PDCB pDCB, PSRB pSRB) { int ctr = 4097; @@ -2523,6 +2540,7 @@ return ctr; } } +#endif /* OLD_EH */ static inline void DC395x_clrfifo (PACB pACB, char *txt) { @@ -2540,6 +2558,7 @@ DC395x_write16 (TRM_S1040_SCSI_CONTROL, DO_CLRFIFO); } +#ifdef OLD_EH /* ********************************************************************** ** @@ -2678,7 +2697,7 @@ } //DC395x_write8 (TRM_S1040_DMA_STATUS, FORCEDMACOMP); - //DC395x_write16 (TRM_S1040_DMA_CONTROL, DMARESETMODULE); + //DC395x_write8 (TRM_S1040_DMA_CONTROL, DMARESETMODULE); //DC395x_basic_config (pACB); if( (pACB->pActiveDCB == pDCB) && (pDCB->pActiveSRB == pSRB) ) { @@ -2722,6 +2741,7 @@ DEBUGRECURSION(in_driver--;) return( status ); } +#endif /* ********************************************************************* @@ -2817,6 +2837,137 @@ } #endif +#ifdef USE_NEW_EH +/* +********************************************************************** +** +** Function : int DC395x_eh_bus_reset(Scsi_Cmnd *cmd) +** Purpose : perform a hard reset on the SCSI bus +** Inputs : cmd - some command for this host (for fetching hooks) +** Returns : SUCCESS (0x2002) on success, else FAILED (0x2003). +********************************************************************** +*/ +int DC395x_eh_bus_reset(Scsi_Cmnd *cmd) +{ + PACB pACB; + //DWORD acb_flags=0; + + pACB = (PACB ) cmd->host->hostdata; + printk(KERN_INFO "DC395x: reset requested!\n"); + pACB = (PACB) cmd->host->hostdata; + /* mid level guarantees no recursion */ + //DC395x_ACB_LOCK(pACB,acb_flags); + + if (timer_pending (&pACB->Waiting_Timer)) + del_timer (&pACB->Waiting_Timer); + /* + ** disable interrupt + */ + DC395x_write8(TRM_S1040_DMA_INTEN, 0x00); + DC395x_write8(TRM_S1040_SCSI_INTEN, 0x00); + DC395x_write8(TRM_S1040_SCSI_CONTROL, DO_RSTMODULE); + DC395x_write8(TRM_S1040_DMA_CONTROL, DMARESETMODULE); + + DC395x_ResetSCSIBus( pACB ); + udelay(500); + /* We may be in serious trouble. Wait some seconds */ + pACB->pScsiHost->last_reset = jiffies + 3*HZ/2 + + HZ * dc395x_trm_eepromBuf[pACB->AdapterIndex].NvramDelayTime; + /* + ** re-enable interrupt + */ + /* Clear SCSI FIFO */ + DC395x_write8(TRM_S1040_DMA_CONTROL, CLRXFIFO); + DC395x_clrfifo (pACB, "reset"); + /* Delete pending IRQ */ + DC395x_read8 (TRM_S1040_SCSI_INTSTATUS); + DC395x_basic_config (pACB); + + DC395x_ResetDevParam( pACB ); + DC395x_DoingSRB_Done( pACB, DID_RESET, cmd, 0 ); + + pACB->pActiveDCB = NULL; + + pACB->ACBFlag = 0; /* RESET_DETECT, RESET_DONE ,RESET_DEV */ + DC395x_Waiting_process( pACB ); + + //DC395x_ACB_LOCK(pACB,acb_flags); + return SUCCESS; +} + +/* +********************************************************************** +** +** Function : int DC395x_eh_abort(Scsi_Cmnd *cmd) +** Purpose : abort an errant SCSI command +** Inputs : cmd - command to be aborted +** Returns : SUCCESS (0x2002) on success, else FAILED (0x2003). +********************************************************************** +*/ +int DC395x_eh_abort(Scsi_Cmnd *cmd) +{ + // Look into our command queues: If it has not been sent already, + // we remove it and return success. Otherwise fail. + // First check the Query Queues, then the Waiting ones + PACB pACB = (PACB) cmd->host->hostdata; + PDCB pDCB; PSRB pSRB; + int cnt = pACB->QueryCnt; + PSCSICMD pcmd, last = 0; + printk ("DC395x_eh_abort: cmd %p (pid %li, %02i-%i) ", + cmd, cmd->pid, cmd->target, cmd->lun); + for (pcmd = pACB->pQueryHead; cnt--; last = pcmd, pcmd = pcmd->next) { + if (pcmd == cmd) { + // unqueue + if (last) { + last->next = pcmd->next; + if (!pcmd->next) + pACB->pQueryTail = last; + } else { + pACB->pQueryHead = pcmd->next; + if (!pcmd->next) + pACB->pQueryTail = 0; + } + printk ("found in Query queue :-)\n"); + pACB->QueryCnt--; + cmd->result = DID_ABORT << 16; + return SUCCESS; + } + } + pDCB = DC395x_findDCB (pACB, cmd->target, cmd->lun); + if (!pDCB) { + printk ("no DCB !\n"); + return FAILED; + } + + pSRB = DC395x_find_cmd (cmd, pDCB->pWaitingSRB); + if (pSRB) { + DC395x_Waiting_remove (pDCB, pSRB, 0); + DC395x_pci_unmap_sense (pACB, pSRB); + DC395x_pci_unmap (pACB, pSRB); + DC395x_freetag (pDCB, pSRB); + DC395x_Free_insert (pACB, pSRB); + printk ("found in waiting queue :-)\n"); + cmd->result = DID_ABORT << 16; + return SUCCESS; + } + pSRB = DC395x_find_cmd (cmd, pDCB->pGoingSRB); + if (pSRB) + printk ("found in going queue :-(\n"); + else + printk ("not found!\n"); + return FAILED; +} + +/* TODO (new EH): + * int (*eh_device_reset_handler)(Scsi_Cmnd *); + * int (*eh_host_reset_handler)(Scsi_Cmnd *); + * + * remove Query Queue + * investigate whether/which commands need to be ffed back to mid-layer + * in _eh_reset() + */ +#endif /* end of USE_NEW_EH */ + /* ********************************************************************** ** @@ -2863,7 +3014,7 @@ DC395x_basic_config (pACB); DC395x_ResetDevParam( pACB ); - DC395x_DoingSRB_Done( pACB, DID_RESET ); + DC395x_DoingSRB_Done( pACB, DID_RESET, cmd, 1 ); pACB->pActiveDCB = NULL; pACB->ACBFlag = 0; /* RESET_DETECT, RESET_DONE ,RESET_DEV */ @@ -3238,7 +3389,7 @@ if (pACB->pActiveDCB->pActiveSRB) DC395x_EnableMsgOut_Abort (pACB, pACB->pActiveDCB->pActiveSRB); } - DC395x_write16 (TRM_S1040_DMA_CONTROL, ABORTXFER | CLRXFIFO); + DC395x_write8 (TRM_S1040_DMA_CONTROL, ABORTXFER | CLRXFIFO); break; #else printk ("DC395x: Ignore and hope for the best ...\n"); @@ -3669,12 +3820,12 @@ if (!(DC395x_read8(TRM_S1040_SCSI_FIFOCNT) & 0x40)) DC395x_clrfifo (pACB, "ClnIn"); - if (!(DC395x_read16(TRM_S1040_DMA_FIFOCNT) & 0x8000)) + if (!(DC395x_read8(TRM_S1040_DMA_FIFOSTAT) & 0x80)) DC395x_write8(TRM_S1040_DMA_CONTROL, CLRXFIFO); } else { /* write */ - if (!(DC395x_read16(TRM_S1040_DMA_FIFOCNT) & 0x8000)) + if (!(DC395x_read8(TRM_S1040_DMA_FIFOSTAT) & 0x80)) DC395x_write8(TRM_S1040_DMA_CONTROL, CLRXFIFO); if (!(DC395x_read8(TRM_S1040_SCSI_FIFOCNT) & 0x40)) @@ -3725,14 +3876,15 @@ * If we need more data, the DMA SG list will be freshly set up, anyway */ #ifdef DC395x_DEBUGPIO - printk ("DC395x: DOP0: DMA_FCNT: %04x, SCSI_FCNT: %02x, CTR %06x, stat %04x, Tot: %06x\n", - DC395x_read16 (TRM_S1040_DMA_FIFOCNT), + printk ("DC395x: DOP0: DMA_FCNT: %02x, DMA_FSTAT: %02x, SCSI_FCNT: %02x, CTR %06x, stat %04x, Tot: %06x\n", + DC395x_read8 (TRM_S1040_DMA_FIFOCNT), + DC395x_read8 (TRM_S1040_DMA_FIFOSTAT), DC395x_read8 (TRM_S1040_SCSI_FIFOCNT), DC395x_read32 (TRM_S1040_SCSI_COUNTER), scsi_status, pSRB->SRBTotalXferLength); //DC395x_dumpinfo(pACB, pDCB, pSRB); #endif - DC395x_write16 (TRM_S1040_DMA_CONTROL, STOPDMAXFER | CLRXFIFO); + DC395x_write8 (TRM_S1040_DMA_CONTROL, STOPDMAXFER | CLRXFIFO); if( !(pSRB->SRBState & SRB_XFERPAD) ) { @@ -3760,8 +3912,9 @@ printk ("DC395x: SCSI FIFOCNT %02x, SCSI CTR %08x\n", DC395x_read8 (TRM_S1040_SCSI_FIFOCNT), DC395x_read32 (TRM_S1040_SCSI_COUNTER)); - printk ("DC395x: DMA FIFOCNT %04x, DMA CTR %08x\n", - DC395x_read16 (TRM_S1040_DMA_FIFOCNT), + printk ("DC395x: DMA FIFOCNT %04x, FIFOSTAT %02x, DMA CTR %08x\n", + DC395x_read8 (TRM_S1040_DMA_FIFOCNT), + DC395x_read8 (TRM_S1040_DMA_FIFOSTAT), DC395x_read32 (TRM_S1040_DMA_CXCNT)); #endif /* @@ -3923,21 +4076,22 @@ // but: it would be better to wait first for the SCSI FIFO and then the // the DMA FIFO to become empty? How do we know, that the device not already // sent data to the FIFO in a MsgIn phase, eg.? - if (!(DC395x_read16 (TRM_S1040_DMA_FIFOCNT) & 0x8000)) { + if (!(DC395x_read8 (TRM_S1040_DMA_FIFOSTAT) & 0x80)) { #if 0 int ctr = 6000000; printk ("DC395x: DIP0: Wait for DMA FIFO to flush ...\n"); - //DC395x_write16 (TRM_S1040_DMA_CONTROL, STOPDMAXFER); + //DC395x_write8 (TRM_S1040_DMA_CONTROL, STOPDMAXFER); //DC395x_write32 (TRM_S1040_SCSI_COUNTER, 7); - //DC395x_write8 (TRM_S1040_SCSI_COMMAND, SCMD_DMA_IN); - while (!(DC395x_read16 (TRM_S1040_DMA_FIFOCNT) & 0x8000) && --ctr); + //DC395x_write8 (TRM_S1040_SCSI_COMMAND, SCMD_DMA_IN); + while (!(DC395x_read16 (TRM_S1040_DMA_FIFOSTAT) & 0x80) && --ctr); if (ctr < 6000000-1) printk ("DC395x: Debug: DIP0: Had to wait for DMA ...\n"); if (!ctr) printk (KERN_ERR "DC395x: Deadlock in DIP0 waiting for DMA FIFO empty!!\n"); //DC395x_write32 (TRM_S1040_SCSI_COUNTER, 0); #endif #ifdef DC395x_DEBUG_KG - printk ("DC395x: DIP0: DMA_FIFO: %04x\n", - DC395x_read16 (TRM_S1040_DMA_FIFOCNT)); + printk ("DC395x: DIP0: DMA_FIFO: %02x %02x\n", + DC395x_read8 (TRM_S1040_DMA_FIFOCNT), + DC395x_read8 (TRM_S1040_DMA_FIFOSTAT)); #endif } /* Now: Check remainig data: The SCSI counters should tell us ... */ @@ -3952,8 +4106,9 @@ printk ("DC395x: SCSI FIFOCNT %02x, SCSI CTR %08x\n", DC395x_read8 (TRM_S1040_SCSI_FIFOCNT), DC395x_read32 (TRM_S1040_SCSI_COUNTER)); - printk ("DC395x: DMA FIFOCNT %04x, DMA CTR %08x\n", - DC395x_read16 (TRM_S1040_DMA_FIFOCNT), + printk ("DC395x: DMA FIFOCNT %02x,%02x DMA CTR %08x\n", + DC395x_read8 (TRM_S1040_DMA_FIFOCNT), + DC395x_read8 (TRM_S1040_DMA_FIFOSTAT), DC395x_read32 (TRM_S1040_DMA_CXCNT)); printk ("DC395x: Remaining: TotXfer: %i, SCSI FIFO+Ctr: %i\n", pSRB->SRBTotalXferLength, dLeftCounter); @@ -4026,9 +4181,9 @@ //dLeftCounter += DC395x_read32(TRM_S1040_SCSI_COUNTER); #if 0 - printk ("DC395x: DIP0: ctr=%08x, DMA_FIFO=%04x, SCSI_FIFO=%02x\n", - dLeftCounter, DC395x_read16 (TRM_S1040_DMA_FIFOCNT), - DC395x_read8 (TRM_S1040_SCSI_FIFOCNT)); + printk ("DC395x: DIP0: ctr=%08x, DMA_FIFO=%02x,%02x SCSI_FIFO=%02x\n", + dLeftCounter, DC395x_read8 (TRM_S1040_DMA_FIFOCNT), + DC395x_read8 (TRM_S1040_DMA_FIFOSTAT), DC395x_read8 (TRM_S1040_SCSI_FIFOCNT)); printk ("DC395x: DIP0: DMAStat %02x\n", DC395x_read8 (TRM_S1040_DMA_STATUS)); #endif @@ -4966,7 +5121,7 @@ pDCB->DCBFlag &= ~ABORT_DEV_; pACB->pScsiHost->last_reset = jiffies + HZ/2 + 1; printk(KERN_ERR "DC395x: Disc: SRB_ABORT_SENT!\n"); - DC395x_DoingSRB_Done (pACB, DID_ABORT); + DC395x_DoingSRB_Done (pACB, DID_ABORT, pSRB->pcmd, 1); DC395x_Query_to_Waiting (pACB); DC395x_Waiting_process (pACB); } @@ -5270,8 +5425,67 @@ /* if (bval1 == TYPE_DISK || bval1 == TYPE_MOD) */ DC395x_disc_tagq_set (pDCB, ptr); }; - +/* +********************************************************************* +** unmap mapped pci regions from SRB +********************************************************************* + */ +static void DC395x_pci_unmap (PACB pACB, PSRB pSRB) +{ + int dir; + PSCSICMD pcmd = pSRB->pcmd; + SET_DIR(dir,pcmd); + if (pcmd->use_sg && dir != PCI_DMA_NONE) { + /* unmap DC395x SG list */ +#ifdef DC395x_SGPARANOIA + printk ("DC395x: Unmap SG descriptor list %08x (%05x)\n", + pSRB->SRBSGBusAddr, sizeof(SGentry)*DC395x_MAX_SG_LISTENTRY); +#endif + PCI_UNMAP_SINGLE(pACB->pdev, pSRB->SRBSGBusAddr, + sizeof(SGentry)*DC395x_MAX_SG_LISTENTRY, PCI_DMA_TODEVICE); +#ifdef DC395x_SGPARANOIA + printk ("DC395x: Unmap %i SG segments from %p\n", + pcmd->use_sg, pcmd->request_buffer); +#endif + /* unmap the sg segments */ + PCI_UNMAP_SG(pACB->pdev, (struct scatterlist*)pcmd->request_buffer, + pcmd->use_sg, dir); + } + else if (pcmd->request_buffer && dir != PCI_DMA_NONE) { +#ifdef DC395x_SGPARANOIA + printk ("DC395x: Unmap buffer at %08x (%05x)\n", + pSRB->SegmentX[0].address, pcmd->request_bufflen); +#endif + PCI_UNMAP_SINGLE(pACB->pdev, pSRB->SegmentX[0].address, + pcmd->request_bufflen, dir); + } +} + +/* +********************************************************************* +** unmap mapped pci sense buffer from SRB +********************************************************************* + */ +static void DC395x_pci_unmap_sense (PACB pACB, PSRB pSRB) +{ + if (!(pSRB->SRBFlag & AUTO_REQSENSE)) + return; + /* Unmap sense buffer */ +#ifdef DC395x_SGPARANOIA + printk ("DC395x: Unmap sense buffer from %08x (%05x)\n", + pSRB->SegmentX[0].address, sizeof(pcmd->sense_buffer)); +#endif + PCI_UNMAP_SINGLE(pACB->pdev, pSRB->SegmentX[0].address, + pSRB->SegmentX[0].length, PCI_DMA_FROMDEVICE); + // Restore SG stuff + //printk ("Auto_ReqSense finished: Restore Counters ...\n"); + pSRB->SRBTotalXferLength = pSRB->Xferred; + pSRB->SegmentX[0].address = pSRB->SegmentX[DC395x_MAX_SG_LISTENTRY-1].address; + pSRB->SegmentX[0].length = pSRB->SegmentX[DC395x_MAX_SG_LISTENTRY-1].length; +} + + /* ********************************************************************* ** scsiio @@ -5310,18 +5524,7 @@ #ifdef DC395x_DEBUG0 printk(KERN_INFO "AUTO_REQSENSE1..............\n "); #endif - /* Unmap sense buffer */ -#ifdef DC395x_SGPARANOIA - printk ("DC395x: Unmap sense buffer from %08x (%05x)\n", - pSRB->SegmentX[0].address, sizeof(pcmd->sense_buffer)); -#endif - PCI_UNMAP_SINGLE(pACB->pdev, pSRB->SegmentX[0].address, - pSRB->SegmentX[0].length, PCI_DMA_FROMDEVICE); - // Restore SG stuff - //printk ("Auto_ReqSense finished: Restore Counters ...\n"); - pSRB->SRBTotalXferLength = pSRB->Xferred; - pSRB->SegmentX[0].address = pSRB->SegmentX[DC395x_MAX_SG_LISTENTRY-1].address; - pSRB->SegmentX[0].length = pSRB->SegmentX[DC395x_MAX_SG_LISTENTRY-1].length; + DC395x_pci_unmap_sense (pACB, pSRB); /* ** target status.......................... */ @@ -5566,30 +5769,7 @@ printk (" 0x%08x\n", pcmd->result); #endif TRACEPRINTF("%08x(%li)*", pcmd->result, jiffies); - if (pcmd->use_sg && dir != PCI_DMA_NONE) { - /* unmap DC395x SG list */ -#ifdef DC395x_SGPARANOIA - printk ("DC395x: Unmap SG descriptor list %08x (%05x)\n", - pSRB->SRBSGBusAddr, sizeof(SGentry)*DC395x_MAX_SG_LISTENTRY); -#endif - PCI_UNMAP_SINGLE(pACB->pdev, pSRB->SRBSGBusAddr, - sizeof(SGentry)*DC395x_MAX_SG_LISTENTRY, PCI_DMA_TODEVICE); -#ifdef DC395x_SGPARANOIA - printk ("DC395x: Unmap %i SG segments from %p\n", - pcmd->use_sg, pcmd->request_buffer); -#endif - /* unmap the sg segments */ - PCI_UNMAP_SG(pACB->pdev, (struct scatterlist*)pcmd->request_buffer, - pcmd->use_sg, dir); - } - else if (pcmd->request_buffer && dir != PCI_DMA_NONE) { -#ifdef DC395x_SGPARANOIA - printk ("DC395x: Unmap buffer at %08x (%05x)\n", - pSRB->SegmentX[0].address, pcmd->request_bufflen); -#endif - PCI_UNMAP_SINGLE(pACB->pdev, pSRB->SegmentX[0].address, - pcmd->request_bufflen, dir); - } + DC395x_pci_unmap (pACB, pSRB); //DC395x_UNLOCK_ACB_NI; pcmd->scsi_done (pcmd); //DC395x_LOCK_ACB_NI; @@ -5607,7 +5787,8 @@ ** abort all cmds in our queues ********************************************************************* */ -void DC395x_DoingSRB_Done( PACB pACB, BYTE did_flag ) +void DC395x_DoingSRB_Done( PACB pACB, BYTE did_flag, + Scsi_Cmnd *cmd, BYTE force ) { PDCB pDCB; PSRB pSRB, pSRBTemp; @@ -5629,13 +5810,15 @@ while (cnt--) { int result; + int dir; pSRBTemp = pSRB->pNextSRB; pcmd = pSRB->pcmd; + SET_DIR(dir,pcmd); result = MK_RES(0,did_flag,0,0); //result = MK_RES(0,DID_RESET,0,0); TRACEPRINTF ("Reset(%li):%08x*", jiffies, result); printk (" (G)"); -#ifndef DC395x_DEBUGTRACE +#if 1//ndef DC395x_DEBUGTRACE printk ("%li(%02i-%i) ", pcmd->pid, pcmd->target, pcmd->lun); #endif TRACEOUT ("%s\n", pSRB->debugtrace); @@ -5643,13 +5826,20 @@ if (!pSRBTemp) pDCB->pGoingLast = NULL; DC395x_freetag (pDCB, pSRB); DC395x_Free_insert (pACB, pSRB); -#ifndef USE_NEW_EH - /* For new EH, don't give commands back */ pcmd->result = result; + DC395x_pci_unmap_sense (pACB, pSRB); + DC395x_pci_unmap (pACB, pSRB); +#ifdef USE_NEW_EH + if (force) { + /* For new EH, we normally don't need to give commands back, + * as they all complete or all time out */ +#endif + /* do we need the aic7xxx hack and conditionally decrease retry ? */ //DC395x_SCSI_DONE_ACB_UNLOCK; - // TODO: PCI_UNMAP pcmd->scsi_done( pcmd ); //DC395x_SCSI_DONE_ACB_LOCK; +#ifdef USE_NEW_EH + } #endif pSRB = pSRBTemp; } @@ -5673,7 +5863,7 @@ result = MK_RES(0,did_flag,0,0); TRACEPRINTF ("Reset(%li):%08x*", jiffies, result); printk (" (W)"); -#ifndef DC395x_DEBUGTRACE +#if 1//ndef DC395x_DEBUGTRACE printk ("%li(%i-%i)", pcmd->pid, pcmd->target, pcmd->lun); #endif TRACEOUT ("%s\n", pSRB->debugtrace); @@ -5681,15 +5871,22 @@ if (!pSRBTemp) pDCB->pWaitLast = NULL; DC395x_Free_insert (pACB, pSRB); -#ifndef USE_NEW_EH - /* For new EH, don't give commands back */ pcmd->result = result; + DC395x_pci_unmap_sense (pACB, pSRB); + DC395x_pci_unmap (pACB, pSRB); +#ifdef USE_NEW_EH + if (force) { + /* For new EH, we normally don't need to give commands back, + * as they all complete or all time out */ +#endif + /* do we need the aic7xxx hack and conditionally decrease retry ? */ //DC395x_SCSI_DONE_ACB_UNLOCK; - // TODO: PCI_UNMAP pcmd->scsi_done( pcmd ); //DC395x_SCSI_DONE_ACB_LOCK; -#endif pSRB = pSRBTemp; +#ifdef USE_NEW_EH + } +#endif } if (pDCB->WaitSRBCnt) printk ("\nDC395x: Debug: ML queued %i cmnds again to %02i-%i\n", @@ -5796,7 +5993,7 @@ { pACB->ACBFlag |= RESET_DETECT; DC395x_ResetDevParam( pACB ); - DC395x_DoingSRB_Done( pACB, DID_RESET ); + DC395x_DoingSRB_Done( pACB, DID_RESET, 0, 1 ); //DC395x_RecoverSRB( pACB ); pACB->pActiveDCB = NULL; pACB->ACBFlag = 0; @@ -7451,7 +7648,7 @@ /* KG: proc_info taken from driver aha152x.c */ #undef SPRINTF -#define SPRINTF(args...) pos += sprintf(pos, ## args) +#define SPRINTF(args...) pos += sprintf(pos, args) #define YESNO(YN) \ if (YN) SPRINTF(" Yes ");\ @@ -7461,7 +7658,7 @@ { int dev, spd, spd1; char *pos = buffer; - PSH shpnt; + PSH shpnt = NULL; PACB pACB; PDCB pDCB; DWORD flags; Index: dc395x_trm.h =================================================================== RCS file: /home/cvsroot/dc395/dc395x_trm.h,v retrieving revision 1.41 retrieving revision 1.43 diff -u -r1.41 -r1.43 --- dc395x_trm.h 2002/05/10 17:17:53 1.41 +++ dc395x_trm.h 2002/06/21 09:57:38 1.43 @@ -8,7 +8,7 @@ ** ********************************************************************** */ -/* $Id: dc395x_trm.h,v 1.41 2002/05/10 17:17:53 garloff Exp $ */ +/* $Id: dc395x_trm.h,v 1.43 2002/06/21 09:57:38 garloff Exp $ */ /* ***************************************************** ** Tekram TRM_S1040 for DC395x driver, header file @@ -20,7 +20,7 @@ #include #define DC395x_BANNER "Tekram DC395U/UW/F DC315/U" -#define DC395x_VERSION "1.40, 2002-05-10" +#define DC395x_VERSION "1.41, 2002-06-21" /* Kernel version autodetection */ #include @@ -58,18 +58,26 @@ //#define SYNC_FIRST -/* We don't have eh_abort_handler, eh_device_reset_handler, - * eh_bus_reset_handler, eh_host_reset_handler yet! - * So long: Use old exception handling :-( */ -#define OLD_EH +#if (LINUX_VERSION_CODE < KERNEL_VERSION (2,5,6) && !defined(FORCE_NEW_EH)) +/* Our new EH is not yet so well tested; only use it for 2.5 ... */ +# define OLD_EH +#endif #if (LINUX_VERSION_CODE < KERNEL_VERSION (2,1,70)) || defined(OLD_EH) -# define NEW_EH +# define EH_FUNC abort: DC395x_abort, \ + reset: DC395x_reset, # define NORM_REC_LVL 1 #else # define USE_NEW_EH # define NORM_REC_LVL 0 -# define NEW_EH use_new_eh_code: 1, +# if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,14) +# define EH_FUNC use_new_eh_code: 1, \ + eh_abort_handler: DC395x_eh_abort, \ + eh_bus_reset_handler: DC395x_eh_bus_reset, +# else +# define EH_FUNC eh_abort_handler: DC395x_eh_abort, \ + eh_bus_reset_handler: DC395x_eh_bus_reset, +# endif #endif #if defined(HOSTS_C) || defined(MODULE) || LINUX_VERSION_CODE > KERNEL_VERSION(2,3,99) @@ -78,8 +86,13 @@ extern int DC395x_detect(Scsi_Host_Template *psht); extern int DC395x_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)); +# ifdef USE_NEW_EH +extern int DC395x_eh_abort(Scsi_Cmnd * SCpnt); +extern int DC395x_eh_bus_reset(Scsi_Cmnd * SCpnt); +# else extern int DC395x_abort(Scsi_Cmnd *cmd); extern int DC395x_reset(Scsi_Cmnd *cmd ,unsigned int resetFlags); +# endif extern int DC395x_bios_param(Disk *disk, kdev_t devno, int geom[]); //-------------- # ifdef MODULE @@ -90,46 +103,41 @@ //-------------- extern int DC395x_proc_info(char*, char**, off_t, int, int, int); //-------------- - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30) -# define DC395x_TRMS1040 { \ +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30) +# define DC395x_TRMS1040 { \ proc_name: "dc395x_trm", \ proc_info: DC395x_proc_info, \ name: DC395x_BANNER " V" DC395x_VERSION,\ detect: DC395x_detect, \ release: DC395x_release, \ queuecommand: DC395x_queue_command, \ - abort: DC395x_abort, \ - reset: DC395x_reset, \ bios_param: DC395x_bios_param, \ can_queue: DC395x_MAX_CAN_QUEUE, \ this_id: 7, \ sg_tablesize: DC395x_MAX_SG_TABLESIZE, \ cmd_per_lun: DC395x_MAX_CMD_PER_LUN, \ - NEW_EH \ + EH_FUNC \ unchecked_isa_dma: 0, \ use_clustering: DISABLE_CLUSTERING \ } -#else +# else /* 2.3.30 */ extern struct proc_dir_entry DC395x_proc_scsi; -# define DC395x_TRMS1040 { \ +# define DC395x_TRMS1040 { \ proc_dir: &DC395x_proc_scsi, \ proc_info: DC395x_proc_info, \ name: DC395x_BANNER " V" DC395x_VERSION,\ detect: DC395x_detect, \ release: DC395x_release, \ queuecommand: DC395x_queue_command, \ - abort: DC395x_abort, \ - reset: DC395x_reset, \ bios_param: DC395x_bios_param, \ can_queue: DC395x_MAX_CAN_QUEUE, \ this_id: 7, \ sg_tablesize: DC395x_MAX_SG_TABLESIZE, \ cmd_per_lun: DC395x_MAX_CMD_PER_LUN, \ - NEW_EH \ + EH_FUNC \ unchecked_isa_dma: 0, \ use_clustering: DISABLE_CLUSTERING \ } -#endif /* 2,3,30 */ +# endif /* 2,3,30 */ #endif /* defined(HOSTS_C) || defined(MODULE) || LINUX_VERSION_CODE > 2,3,99 */ -#endif /* DC395x_H */ +#endif /* DC395x_trm_H */