@@ -230,13 +230,12 @@ struct ScsiReqBlk {
230230 struct scsi_cmnd * cmd ;
231231
232232 struct SGentry * segment_x ; /* Linear array of hw sg entries (up to 64 entries) */
233- u32 sg_bus_addr ; /* Bus address of sg list (ie, of segment_x) */
233+ dma_addr_t sg_bus_addr ; /* Bus address of sg list (ie, of segment_x) */
234234
235235 u8 sg_count ; /* No of HW sg entries for this request */
236236 u8 sg_index ; /* Index of HW sg entry for this request */
237- u32 total_xfer_length ; /* Total number of bytes remaining to be transfered */
238- unsigned char * virt_addr ; /* Virtual address of current transfer position */
239-
237+ size_t total_xfer_length ; /* Total number of bytes remaining to be transfered */
238+ size_t request_length ; /* Total number of bytes in this request */
240239 /*
241240 * The sense buffer handling function, request_sense, uses
242241 * the first hw sg entry (segment_x[0]) and the transfer
@@ -246,8 +245,7 @@ struct ScsiReqBlk {
246245 * total_xfer_length in xferred. These values are restored in
247246 * pci_unmap_srb_sense. This is the only place xferred is used.
248247 */
249- unsigned char * virt_addr_req ; /* Saved virtual address of the request buffer */
250- u32 xferred ; /* Saved copy of total_xfer_length */
248+ size_t xferred ; /* Saved copy of total_xfer_length */
251249
252250 u16 state ;
253251
@@ -977,17 +975,6 @@ static void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
977975 }
978976}
979977
980- static inline void pio_trigger (void )
981- {
982- static int feedback_requested ;
983-
984- if (!feedback_requested ) {
985- feedback_requested = 1 ;
986- printk (KERN_WARNING "%s: Please, contact <linux-scsi@vger.kernel.org> "
987- "to help improve support for your system.\n" , __FILE__ );
988- }
989- }
990-
991978/* Prepare SRB for being sent to Device DCB w/ command *cmd */
992979static void build_srb (struct scsi_cmnd * cmd , struct DeviceCtlBlk * dcb ,
993980 struct ScsiReqBlk * srb )
@@ -1001,7 +988,6 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
1001988 srb -> sg_count = 0 ;
1002989 srb -> total_xfer_length = 0 ;
1003990 srb -> sg_bus_addr = 0 ;
1004- srb -> virt_addr = NULL ;
1005991 srb -> sg_index = 0 ;
1006992 srb -> adapter_status = 0 ;
1007993 srb -> target_status = 0 ;
@@ -1032,7 +1018,6 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
10321018 reqlen , cmd -> request_buffer , cmd -> use_sg ,
10331019 srb -> sg_count );
10341020
1035- srb -> virt_addr = page_address (sl -> page );
10361021 for (i = 0 ; i < srb -> sg_count ; i ++ ) {
10371022 u32 busaddr = (u32 )sg_dma_address (& sl [i ]);
10381023 u32 seglen = (u32 )sl [i ].length ;
@@ -1077,12 +1062,14 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
10771062 srb -> total_xfer_length ++ ;
10781063
10791064 srb -> segment_x [0 ].length = srb -> total_xfer_length ;
1080- srb -> virt_addr = cmd -> request_buffer ;
1065+
10811066 dprintkdbg (DBG_0 ,
10821067 "build_srb: [1] len=%d buf=%p use_sg=%d map=%08x\n" ,
10831068 srb -> total_xfer_length , cmd -> request_buffer ,
10841069 cmd -> use_sg , srb -> segment_x [0 ].address );
10851070 }
1071+
1072+ srb -> request_length = srb -> total_xfer_length ;
10861073}
10871074
10881075
@@ -1414,10 +1401,10 @@ static int dc395x_eh_abort(struct scsi_cmnd *cmd)
14141401 }
14151402 srb = find_cmd (cmd , & dcb -> srb_going_list );
14161403 if (srb ) {
1417- dprintkl (KERN_DEBUG , "eh_abort: Command in progress" );
1404+ dprintkl (KERN_DEBUG , "eh_abort: Command in progress\n " );
14181405 /* XXX: Should abort the command here */
14191406 } else {
1420- dprintkl (KERN_DEBUG , "eh_abort: Command not found" );
1407+ dprintkl (KERN_DEBUG , "eh_abort: Command not found\n " );
14211408 }
14221409 return FAILED ;
14231410}
@@ -1976,14 +1963,11 @@ static void sg_verify_length(struct ScsiReqBlk *srb)
19761963
19771964/*
19781965 * Compute the next Scatter Gather list index and adjust its length
1979- * and address if necessary; also compute virt_addr
1966+ * and address if necessary
19801967 */
19811968static void sg_update_list (struct ScsiReqBlk * srb , u32 left )
19821969{
19831970 u8 idx ;
1984- struct scatterlist * sg ;
1985- struct scsi_cmnd * cmd = srb -> cmd ;
1986- int segment = cmd -> use_sg ;
19871971 u32 xferred = srb -> total_xfer_length - left ; /* bytes transfered */
19881972 struct SGentry * psge = srb -> segment_x + srb -> sg_index ;
19891973
@@ -2016,29 +2000,6 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
20162000 psge ++ ;
20172001 }
20182002 sg_verify_length (srb );
2019-
2020- /* we need the corresponding virtual address */
2021- if (!segment || (srb -> flag & AUTO_REQSENSE )) {
2022- srb -> virt_addr += xferred ;
2023- return ;
2024- }
2025-
2026- /* We have to walk the scatterlist to find it */
2027- sg = (struct scatterlist * )cmd -> request_buffer ;
2028- while (segment -- ) {
2029- unsigned long mask =
2030- ~((unsigned long )sg -> length - 1 ) & PAGE_MASK ;
2031- if ((sg_dma_address (sg ) & mask ) == (psge -> address & mask )) {
2032- srb -> virt_addr = (page_address (sg -> page )
2033- + psge -> address -
2034- (psge -> address & PAGE_MASK ));
2035- return ;
2036- }
2037- ++ sg ;
2038- }
2039-
2040- dprintkl (KERN_ERR , "sg_update_list: sg_to_virt failed\n" );
2041- srb -> virt_addr = NULL ;
20422003}
20432004
20442005
@@ -2050,15 +2011,7 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
20502011 */
20512012static void sg_subtract_one (struct ScsiReqBlk * srb )
20522013{
2053- srb -> total_xfer_length -- ;
2054- srb -> segment_x [srb -> sg_index ].length -- ;
2055- if (srb -> total_xfer_length &&
2056- !srb -> segment_x [srb -> sg_index ].length ) {
2057- if (debug_enabled (DBG_PIO ))
2058- printk (" (next segment)" );
2059- srb -> sg_index ++ ;
2060- sg_update_list (srb , srb -> total_xfer_length );
2061- }
2014+ sg_update_list (srb , srb -> total_xfer_length - 1 );
20622015}
20632016
20642017
@@ -2118,7 +2071,7 @@ static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
21182071 * If we need more data, the DMA SG list will be freshly set up, anyway
21192072 */
21202073 dprintkdbg (DBG_PIO , "data_out_phase0: "
2121- "DMA{fifcnt =0x%02x fifostat=0x%02x} "
2074+ "DMA{fifocnt =0x%02x fifostat=0x%02x} "
21222075 "SCSI{fifocnt=0x%02x cnt=0x%06x status=0x%04x} total=0x%06x\n" ,
21232076 DC395x_read8 (acb , TRM_S1040_DMA_FIFOCNT ),
21242077 DC395x_read8 (acb , TRM_S1040_DMA_FIFOSTAT ),
@@ -2239,12 +2192,11 @@ static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
22392192 data_io_transfer (acb , srb , XFERDATAOUT );
22402193}
22412194
2242-
22432195static void data_in_phase0 (struct AdapterCtlBlk * acb , struct ScsiReqBlk * srb ,
22442196 u16 * pscsi_status )
22452197{
22462198 u16 scsi_status = * pscsi_status ;
2247- u32 d_left_counter = 0 ;
2199+
22482200 dprintkdbg (DBG_0 , "data_in_phase0: (pid#%li) <%02i-%i>\n" ,
22492201 srb -> cmd -> pid , srb -> cmd -> device -> id , srb -> cmd -> device -> lun );
22502202
@@ -2262,6 +2214,9 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
22622214 * seem to be a bad idea, actually.
22632215 */
22642216 if (!(srb -> state & SRB_XFERPAD )) {
2217+ u32 d_left_counter ;
2218+ unsigned int sc , fc ;
2219+
22652220 if (scsi_status & PARITYERROR ) {
22662221 dprintkl (KERN_INFO , "data_in_phase0: (pid#%li) "
22672222 "Parity Error\n" , srb -> cmd -> pid );
@@ -2298,59 +2253,99 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
22982253 DC395x_read8 (acb , TRM_S1040_DMA_FIFOSTAT ));
22992254 }
23002255 /* Now: Check remainig data: The SCSI counters should tell us ... */
2301- d_left_counter = DC395x_read32 (acb , TRM_S1040_SCSI_COUNTER )
2302- + ((DC395x_read8 (acb , TRM_S1040_SCSI_FIFOCNT ) & 0x1f )
2256+ sc = DC395x_read32 (acb , TRM_S1040_SCSI_COUNTER );
2257+ fc = DC395x_read8 (acb , TRM_S1040_SCSI_FIFOCNT );
2258+ d_left_counter = sc + ((fc & 0x1f )
23032259 << ((srb -> dcb -> sync_period & WIDE_SYNC ) ? 1 :
23042260 0 ));
23052261 dprintkdbg (DBG_KG , "data_in_phase0: "
23062262 "SCSI{fifocnt=0x%02x%s ctr=0x%08x} "
23072263 "DMA{fifocnt=0x%02x fifostat=0x%02x ctr=0x%08x} "
23082264 "Remain{totxfer=%i scsi_fifo+ctr=%i}\n" ,
2309- DC395x_read8 ( acb , TRM_S1040_SCSI_FIFOCNT ) ,
2265+ fc ,
23102266 (srb -> dcb -> sync_period & WIDE_SYNC ) ? "words" : "bytes" ,
2311- DC395x_read32 ( acb , TRM_S1040_SCSI_COUNTER ) ,
2312- DC395x_read8 ( acb , TRM_S1040_DMA_FIFOCNT ) ,
2267+ sc ,
2268+ fc ,
23132269 DC395x_read8 (acb , TRM_S1040_DMA_FIFOSTAT ),
23142270 DC395x_read32 (acb , TRM_S1040_DMA_CXCNT ),
23152271 srb -> total_xfer_length , d_left_counter );
23162272#if DC395x_LASTPIO
23172273 /* KG: Less than or equal to 4 bytes can not be transfered via DMA, it seems. */
23182274 if (d_left_counter
23192275 && srb -> total_xfer_length <= DC395x_LASTPIO ) {
2276+ size_t left_io = srb -> total_xfer_length ;
2277+
23202278 /*u32 addr = (srb->segment_x[srb->sg_index].address); */
23212279 /*sg_update_list (srb, d_left_counter); */
2322- dprintkdbg (DBG_PIO , "data_in_phase0: PIO (%i %s) to "
2323- "%p for remaining %i bytes:" ,
2324- DC395x_read8 ( acb , TRM_S1040_SCSI_FIFOCNT ) & 0x1f ,
2280+ dprintkdbg (DBG_PIO , "data_in_phase0: PIO (%i %s) "
2281+ " for remaining %i bytes:" ,
2282+ fc & 0x1f ,
23252283 (srb -> dcb -> sync_period & WIDE_SYNC ) ?
23262284 "words" : "bytes" ,
2327- srb -> virt_addr ,
23282285 srb -> total_xfer_length );
23292286 if (srb -> dcb -> sync_period & WIDE_SYNC )
23302287 DC395x_write8 (acb , TRM_S1040_SCSI_CONFIG2 ,
23312288 CFG2_WIDEFIFO );
2332- while (DC395x_read8 (acb , TRM_S1040_SCSI_FIFOCNT ) != 0x40 ) {
2333- u8 byte = DC395x_read8 (acb , TRM_S1040_SCSI_FIFO );
2334- pio_trigger ();
2335- * (srb -> virt_addr )++ = byte ;
2336- if (debug_enabled (DBG_PIO ))
2337- printk (" %02x" , byte );
2338- d_left_counter -- ;
2339- sg_subtract_one (srb );
2340- }
2341- if (srb -> dcb -> sync_period & WIDE_SYNC ) {
2342- #if 1
2343- /* Read the last byte ... */
2344- if (srb -> total_xfer_length > 0 ) {
2345- u8 byte = DC395x_read8 (acb , TRM_S1040_SCSI_FIFO );
2346- pio_trigger ();
2347- * (srb -> virt_addr )++ = byte ;
2348- srb -> total_xfer_length -- ;
2289+ while (left_io ) {
2290+ unsigned char * virt , * base = NULL ;
2291+ unsigned long flags = 0 ;
2292+ size_t len = left_io ;
2293+
2294+ if (srb -> cmd -> use_sg ) {
2295+ size_t offset = srb -> request_length - left_io ;
2296+ local_irq_save (flags );
2297+ /* Assumption: it's inside one page as it's at most 4 bytes and
2298+ I just assume it's on a 4-byte boundary */
2299+ base = scsi_kmap_atomic_sg ((struct scatterlist * )srb -> cmd -> request_buffer ,
2300+ srb -> sg_count , & offset , & len );
2301+ virt = base + offset ;
2302+ } else {
2303+ virt = srb -> cmd -> request_buffer + srb -> cmd -> request_bufflen - left_io ;
2304+ len = left_io ;
2305+ }
2306+ left_io -= len ;
2307+
2308+ while (len ) {
2309+ u8 byte ;
2310+ byte = DC395x_read8 (acb , TRM_S1040_SCSI_FIFO );
2311+ * virt ++ = byte ;
2312+
23492313 if (debug_enabled (DBG_PIO ))
23502314 printk (" %02x" , byte );
2315+
2316+ d_left_counter -- ;
2317+ sg_subtract_one (srb );
2318+
2319+ len -- ;
2320+
2321+ fc = DC395x_read8 (acb , TRM_S1040_SCSI_FIFOCNT );
2322+
2323+ if (fc == 0x40 ) {
2324+ left_io = 0 ;
2325+ break ;
2326+ }
2327+ }
2328+
2329+ WARN_ON ((fc != 0x40 ) == !d_left_counter );
2330+
2331+ if (fc == 0x40 && (srb -> dcb -> sync_period & WIDE_SYNC )) {
2332+ /* Read the last byte ... */
2333+ if (srb -> total_xfer_length > 0 ) {
2334+ u8 byte = DC395x_read8 (acb , TRM_S1040_SCSI_FIFO );
2335+
2336+ * virt ++ = byte ;
2337+ srb -> total_xfer_length -- ;
2338+ if (debug_enabled (DBG_PIO ))
2339+ printk (" %02x" , byte );
2340+ }
2341+
2342+ DC395x_write8 (acb , TRM_S1040_SCSI_CONFIG2 , 0 );
2343+ }
2344+
2345+ if (srb -> cmd -> use_sg ) {
2346+ scsi_kunmap_atomic_sg (base );
2347+ local_irq_restore (flags );
23512348 }
2352- #endif
2353- DC395x_write8 (acb , TRM_S1040_SCSI_CONFIG2 , 0 );
23542349 }
23552350 /*printk(" %08x", *(u32*)(bus_to_virt (addr))); */
23562351 /*srb->total_xfer_length = 0; */
@@ -2509,22 +2504,43 @@ static void data_io_transfer(struct AdapterCtlBlk *acb,
25092504 SCMD_FIFO_IN );
25102505 } else { /* write */
25112506 int ln = srb -> total_xfer_length ;
2507+ size_t left_io = srb -> total_xfer_length ;
2508+
25122509 if (srb -> dcb -> sync_period & WIDE_SYNC )
25132510 DC395x_write8 (acb , TRM_S1040_SCSI_CONFIG2 ,
25142511 CFG2_WIDEFIFO );
2515- dprintkdbg (DBG_PIO ,
2516- "data_io_transfer: PIO %i bytes from %p:" ,
2517- srb -> total_xfer_length , srb -> virt_addr );
25182512
2519- while (srb -> total_xfer_length ) {
2520- if (debug_enabled (DBG_PIO ))
2521- printk (" %02x" , (unsigned char ) * (srb -> virt_addr ));
2513+ while (left_io ) {
2514+ unsigned char * virt , * base = NULL ;
2515+ unsigned long flags = 0 ;
2516+ size_t len = left_io ;
2517+
2518+ if (srb -> cmd -> use_sg ) {
2519+ size_t offset = srb -> request_length - left_io ;
2520+ local_irq_save (flags );
2521+ /* Again, max 4 bytes */
2522+ base = scsi_kmap_atomic_sg ((struct scatterlist * )srb -> cmd -> request_buffer ,
2523+ srb -> sg_count , & offset , & len );
2524+ virt = base + offset ;
2525+ } else {
2526+ virt = srb -> cmd -> request_buffer + srb -> cmd -> request_bufflen - left_io ;
2527+ len = left_io ;
2528+ }
2529+ left_io -= len ;
2530+
2531+ while (len -- ) {
2532+ if (debug_enabled (DBG_PIO ))
2533+ printk (" %02x" , * virt );
25222534
2523- pio_trigger ();
2524- DC395x_write8 (acb , TRM_S1040_SCSI_FIFO ,
2525- * (srb -> virt_addr )++ );
2535+ DC395x_write8 (acb , TRM_S1040_SCSI_FIFO , * virt ++ );
25262536
2527- sg_subtract_one (srb );
2537+ sg_subtract_one (srb );
2538+ }
2539+
2540+ if (srb -> cmd -> use_sg ) {
2541+ scsi_kunmap_atomic_sg (base );
2542+ local_irq_restore (flags );
2543+ }
25282544 }
25292545 if (srb -> dcb -> sync_period & WIDE_SYNC ) {
25302546 if (ln % 2 ) {
@@ -3319,7 +3335,6 @@ static void pci_unmap_srb_sense(struct AdapterCtlBlk *acb,
33193335 srb -> segment_x [DC395x_MAX_SG_LISTENTRY - 1 ].address ;
33203336 srb -> segment_x [0 ].length =
33213337 srb -> segment_x [DC395x_MAX_SG_LISTENTRY - 1 ].length ;
3322- srb -> virt_addr = srb -> virt_addr_req ;
33233338}
33243339
33253340
@@ -3713,8 +3728,6 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
37133728 srb -> xferred = srb -> total_xfer_length ;
37143729 /* srb->segment_x : a one entry of S/G list table */
37153730 srb -> total_xfer_length = sizeof (cmd -> sense_buffer );
3716- srb -> virt_addr_req = srb -> virt_addr ;
3717- srb -> virt_addr = cmd -> sense_buffer ;
37183731 srb -> segment_x [0 ].length = sizeof (cmd -> sense_buffer );
37193732 /* Map sense buffer */
37203733 srb -> segment_x [0 ].address =
0 commit comments