? .dc395x_trm.o.flags ? .kversion ? Rules.make ? dc395x_trm.c.126 ? dc395x_trm.c.131 ? dc395x_trm.c.debug_nmi ? dc395x_trm.c.new ? dc395x_trm.h.131 Index: dc395x_trm.c =================================================================== RCS file: /home/cvsroot/dc395/dc395x_trm.c,v retrieving revision 1.77 retrieving revision 1.79 diff -u -r1.77 -r1.79 --- dc395x_trm.c 2002/02/28 11:18:37 1.77 +++ dc395x_trm.c 2002/03/11 02:34:37 1.79 @@ -12,7 +12,7 @@ //* Kurt Garloff //* (C) 1999-2000 Kurt Garloff //* License: GNU GPL -//* $Id: dc395x_trm.c,v 1.77 2002/02/28 11:18:37 garloff Exp $ +//* $Id: dc395x_trm.c,v 1.79 2002/03/11 02:34:37 garloff Exp $ //*********************************************************************** //* Tekram PCI SCSI adapter (DC395/U/UW/F or DC315/U) revision history //* @@ -101,6 +101,11 @@ //* 1.37 02/02/28 KG Free SRB's SG lists on module exit //* Alloc in many chunks instead of one big //* and don't waste memory by alignment. +//* 1.38 02/03/11 KG Fix pci_map stuff for 2.4 kernels +//* (sg.address vs. page_address(sg.page) + sg.offset) +//* Correctly clean up SG list after REQUEST_SENSE. +//* kfree() DCBs on module exit. +//* Fix inconsistency SRB_array[] size vs. DC395x_MAX_SRB_CNT //*********************************************************************** /* ************************************************************************* @@ -235,6 +240,9 @@ #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,16) +# include +#endif #include "scsi.h" #include "hosts.h" #include "constants.h" @@ -356,7 +364,13 @@ # 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) +#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) +#else +# define CPU_ADDR(sg) ((sg).address? (sg).address: page_address((sg).page)+(sg).offset) +# define PAGE_ADDRESS(sg) ((sg)->address? (sg)->address /*& ~PAGE_MASK*/: page_address((sg)->page)) +#endif # define SET_DIR(dir,pcmd) dir = scsi_to_pci_dma_dir((pcmd)->sc_data_direction) #else # ifndef PCI_DMA_NONE @@ -367,7 +381,7 @@ # endif # define PCI_MAP_SINGLE(hw,ptr,sz,dir) virt_to_bus(ptr) # define PCI_UNMAP_SINGLE(hw,dma,sz,dir) -# define PCI_MAP_SG(hw,sg,n,dir) +# define PCI_MAP_SG(hw,sg,n,dir) n # define PCI_UNMAP_SG(hw,sg,n,dir) # define PCI_DMA_SYNC_SINGLE(hw,dma,sz,dir) # define PCI_DMA_SYNC_SG(hw,sg,n,dir) @@ -376,12 +390,6 @@ # define SET_DIR(dir,pcmd) dir = PCI_DMA_BIDIRECTIONAL #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,1) -# define PAGE_ADDRESS(sg) page_address((sg)->page) -#else LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,16) -# define PAGE_ADDRESS(sg) (sg)->address -#endif - /* cmd->result */ #define RES_TARGET 0x000000FF /* Target State */ @@ -621,8 +629,7 @@ BYTE MsgLen; BYTE DeviceCnt; - /* As every SRB is 768 bytes, don't use too many */ - DC395X_TRM_SRB SRB_array[40]; + DC395X_TRM_SRB SRB_array[DC395x_MAX_SRB_CNT]; DC395X_TRM_SRB TmpSRB; }; typedef struct _ACB DC395X_TRM_ACB, *PACB; @@ -1993,28 +2000,28 @@ // Find out about direction SET_DIR(dir,pcmd); - if( pcmd->use_sg && dir != PCI_DMA_NONE) - { + if (pcmd->use_sg && dir != PCI_DMA_NONE) { unsigned int len = 0; - PCI_MAP_SG(pDCB->pDCBACB->pdev, (struct scatterlist*)pcmd->request_buffer, - pcmd->use_sg, dir); - pSRB->SRBSGCount = pcmd->use_sg; + /* TODO: In case usg_sg and the no of segments differ, things + * will probably go wrong. */ + pSRB->SRBSGCount = PCI_MAP_SG(pDCB->pDCBACB->pdev, (struct scatterlist*)pcmd->request_buffer, + pcmd->use_sg, dir); sgp = pSRB->SegmentX; request_size = pcmd->request_bufflen; #ifdef DC395x_SGPARANOIA printk(KERN_INFO "DC395x: BuildSRB: Bufflen = %d, buffer = %p, use_sg = %d\n", pcmd->request_bufflen, pcmd->request_buffer, pcmd->use_sg); + printk(KERN_INFO "DC395x: Mapped %i Segments to %i\n", + pcmd->use_sg, pSRB->SRBSGCount); #endif sl = (struct scatterlist *) pcmd->request_buffer; max = pcmd->use_sg; - if(max > DC395x_MAX_SG_LISTENTRY) - { + if (max > DC395x_MAX_SG_LISTENTRY) { printk(KERN_INFO "DC395x: cmd->use_sg=%4d bigger then DC395x_MAX_SG_LISTENTRY=%4d for pid %li\n", pcmd->use_sg,DC395x_MAX_SG_LISTENTRY,pcmd->pid); } - pSRB->virt_addr = PAGE_ADDRESS(sl); - for (i = 0; i < max; i++, sgp++) - { + pSRB->virt_addr = PAGE_ADDRESS((struct scatterlist*)sl); + for (i = 0; i < max; i++, sgp++) { DWORD busaddr = (DWORD) BUS_ADDR(sl[i]); DWORD seglen = (DWORD) sl[i].length; if (i > 0 && ((sgp-1)->address + (sgp-1)->length) == busaddr && @@ -2034,8 +2041,8 @@ len += seglen; } #ifdef DC395x_SGPARANOIA - printk(KERN_INFO "DC395x: Setting up sgp %d, address = 0x%08x, length = %d, tot len = %d\n", - i, busaddr, seglen, len); + printk(KERN_INFO "DC395x: Setting up sgp %d, address = 0x%08x, length = %d, tot len = %d\n", + i, busaddr, seglen, len); #endif } sgp--; @@ -2049,8 +2056,7 @@ len = request_size; } /* WIDE padding */ - if (pDCB->SyncPeriod & WIDE_SYNC && len%2) - { + if (pDCB->SyncPeriod & WIDE_SYNC && len%2) { len++; sgp->length++; } @@ -2059,9 +2065,12 @@ pSRB->SRBSGBusAddr = PCI_MAP_SINGLE(pDCB->pDCBACB->pdev, pSRB->SegmentX, sizeof(SGentry)*DC395x_MAX_SG_LISTENTRY, PCI_DMA_TODEVICE); - } - else if( pcmd->request_buffer && dir != PCI_DMA_NONE) - { +#ifdef DC395x_SGPARANOIA + printk("DC395x: Map SG descriptor list %p (%05x) to %08x\n", + pSRB->SegmentX, sizeof(SGentry)*DC395x_MAX_SG_LISTENTRY, + pSRB->SRBSGBusAddr); +#endif + } else if (pcmd->request_buffer && dir != PCI_DMA_NONE) { DWORD len = pcmd->request_bufflen; /* Actual request size */ pSRB->SRBSGCount = 1; pSRB->SegmentX[0].address = PCI_MAP_SINGLE(pDCB->pDCBACB->pdev, @@ -2077,9 +2086,7 @@ printk(KERN_INFO "DC395x: BuildSRB: len = %d, buffer = %p, use_sg = %d, map %08x\n", len, pcmd->request_buffer, pcmd->use_sg, pSRB->SegmentX[0].address); #endif - } - else - { + } else { pSRB->SRBSGCount = 0; pSRB->SRBTotalXferLength = 0; pSRB->SRBSGBusAddr = 0; @@ -2099,6 +2106,12 @@ pSRB->SRBState = 0; pSRB->RetryCnt = 0; +#if DC395x_SGPARANOIA + if ((unsigned long)pSRB->debugtrace & (DEBUGTRACEBUFSZ-1)) + printk ("DC395x: SRB %i (%p): debugtrace %p corrupt!\n", + (pSRB - pDCB->pDCBACB->SRB_array) / sizeof(DC395X_TRM_SRB), + pSRB, pSRB->debugtrace); +#endif pSRB->debugpos = 0; TRACEPRINTF ("pid %li(%li):%02x %02x..(%i-%i) *", pcmd->pid, jiffies, pcmd->cmnd[0], pcmd->cmnd[1], pcmd->target, pcmd->lun); @@ -4118,7 +4131,7 @@ DC395x_write32(TRM_S1040_DMA_XHIGHADDR, 0); if (pSRB->pcmd->use_sg) { /* with S/G */ ioDir |= DMACMD_SG; - DC395x_write32(TRM_S1040_DMA_XLOWADDR, pSRB->SRBSGBusAddr+sizeof(SGentry)*pSRB->SRBSGIndex); + DC395x_write32(TRM_S1040_DMA_XLOWADDR, pSRB->SRBSGBusAddr + sizeof(SGentry)*pSRB->SRBSGIndex); /* load how many bytes in the Scatter/Gather list table */ DC395x_write32(TRM_S1040_DMA_XCNT, ((DWORD) (pSRB->SRBSGCount - pSRB->SRBSGIndex) << 3)); } else { /* without S/G */ @@ -5266,8 +5279,17 @@ 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; /* ** target status.......................... */ @@ -5303,7 +5325,8 @@ printk ("\nDC395x: Sense=%02x, No ASC/ASCQ (%08x) ", pcmd->sense_buffer[2], *((unsigned int*)(pcmd->sense_buffer+3))); -#endif +#endif + if (status == (CHECK_CONDITION << 1)) { pcmd->result = DID_BAD_TARGET << 16; @@ -5312,11 +5335,6 @@ #ifdef DC395x_DEBUG0 printk(KERN_INFO "AUTO_REQSENSE2..............\n "); #endif - // 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; if( (pSRB->SRBTotalXferLength) && (pSRB->SRBTotalXferLength >= pcmd->underflow) ) pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,pSRB->EndMessage,CHECK_CONDITION); @@ -5518,15 +5536,28 @@ 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) + 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_UNLOCK_ACB_NI; pcmd->scsi_done (pcmd); //DC395x_LOCK_ACB_NI; @@ -5777,6 +5808,11 @@ /* Map sense buffer */ pSRB->SegmentX[0].address = PCI_MAP_SINGLE(pACB->pdev, pcmd->sense_buffer, sizeof(pcmd->sense_buffer), PCI_DMA_FROMDEVICE); +#ifdef DC395x_SGPARANOIA + printk ("DC395x: Map sense buffer at %p (%05x) to %08x\n", + pcmd->sense_buffer, sizeof(pcmd->sense_buffer), + pSRB->SegmentX[0].address); +#endif pSRB->SRBSGCount = 1; pSRB->SRBSGIndex = 0; @@ -5939,8 +5975,11 @@ { int srbidx; const unsigned bufs_per_page = PAGE_SIZE/DEBUGTRACEBUFSZ; - for (srbidx = 0; srbidx < SRBIdx; srbidx += bufs_per_page) + for (srbidx = 0; srbidx < SRBIdx; srbidx += bufs_per_page) { + //printk ("DC395x: Free tracebuf %p (for %i)\n", + // pACB->SRB_array[srbidx].debugtrace, srbidx); kfree (pACB->SRB_array[srbidx].debugtrace); + } } int DC395x_alloc_tracebufs (PACB pACB) @@ -5957,6 +5996,8 @@ DC395x_free_tracebufs (pACB, SRBIdx); return 1; } + //printk ("DC395x: Alloc %li bytes at %p for tracebuf %i\n", + // PAGE_SIZE, ptr, SRBIdx); i = 0; while (i < bufs_per_page && SRBIdx < DC395x_MAX_SRB_CNT) pACB->SRB_array[SRBIdx++].debugtrace @@ -5975,8 +6016,11 @@ { int srbidx; const unsigned SRBs_per_page = PAGE_SIZE/(DC395x_MAX_SG_LISTENTRY * sizeof(SGentry)); - for (srbidx = 0; srbidx < SRBIdx; srbidx += SRBs_per_page) + for (srbidx = 0; srbidx < SRBIdx; srbidx += SRBs_per_page) { + //printk ("DC395x: Free SG segs %p (for %i)\n", + // pACB->SRB_array[srbidx].SegmentX, srbidx); kfree (pACB->SRB_array[srbidx].SegmentX); + } } /* Allocate SG tables; as we have to pci_map them, an SG list (PSGE0) @@ -5997,6 +6041,8 @@ DC395x_free_SG_tables (pACB, SRBIdx); return 1; } + //printk ("DC395x: Alloc %li bytes at %p for SG segments %i\n", + // PAGE_SIZE, ptr, SRBIdx); i = 0; while (i < SRBs_per_page && SRBIdx < DC395x_MAX_SRB_CNT) pACB->SRB_array[SRBIdx++].SegmentX @@ -6122,10 +6168,10 @@ for (i = 0; i < DC395x_MAX_SCSI_ID; i++) pACB->DCBmap[i] = 0; -#if 1//def DC395x_DEBUG0 +#ifdef DC395x_DEBUG0 printk(KERN_INFO "DC395x: pACB = %p, pDCBmap = %p, pSRB_array = %p\n", pACB, pACB->DCBmap, pACB->SRB_array); - printk(KERN_INFO "DC395x: ACB size= %04x, DCB size= %04x, SRB size= %04x\n", + printk(KERN_INFO "DC395x: ACB size= %04lx, DCB size= %04lx, SRB size= %04lx\n", sizeof(DC395X_TRM_ACB), sizeof(DC395X_TRM_DCB), sizeof(DC395X_TRM_SRB) ); #endif return 0; @@ -7573,9 +7619,9 @@ { nDCB = pDCB->pNextDCB; DCBDEBUG(printk (KERN_INFO "DC395x: Free DCB (ID %i, LUN %i): %p\n",\ - pDCB->TargetID, pDCB->TargetLUN, pDCB);) - //kfree (pDCB); + pDCB->TargetID, pDCB->TargetLUN, pDCB);) DC395x_remove_dev (pACB, pDCB); + kfree (pDCB); printk ("."); pDCB = nDCB; } while (pDCB && pACB->pLinkDCB); @@ -7598,6 +7644,7 @@ //DC395x_ACB_LOCK(pACB,acb_flags); printk ("DC395x: Shutdown ."); DC395x_shutdown (host); + DC395x_freeDCBs (host); if (host->irq != IRQ_NONE) { Index: dc395x_trm.h =================================================================== RCS file: /home/cvsroot/dc395/dc395x_trm.h,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- dc395x_trm.h 2002/02/28 11:18:37 1.38 +++ dc395x_trm.h 2002/03/11 02:34:37 1.39 @@ -8,7 +8,7 @@ ** ********************************************************************** */ -/* $Id: dc395x_trm.h,v 1.38 2002/02/28 11:18:37 garloff Exp $ */ +/* $Id: dc395x_trm.h,v 1.39 2002/03/11 02:34:37 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.37, 2002-02-28" +#define DC395x_VERSION "1.38, 2002-03-11" /* Kernel version autodetection */ #include