aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sym53c8xx_2/sym_glue.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sym53c8xx_2/sym_glue.c')
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c83
1 files changed, 11 insertions, 72 deletions
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 4d78c7e87cca..15a51459c81f 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -146,41 +146,17 @@ struct sym_ucmd { /* Override the SCSI pointer structure */
146 146
147static void __unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) 147static void __unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
148{ 148{
149 int dma_dir = cmd->sc_data_direction; 149 if (SYM_UCMD_PTR(cmd)->data_mapped)
150 scsi_dma_unmap(cmd);
150 151
151 switch(SYM_UCMD_PTR(cmd)->data_mapped) {
152 case 2:
153 pci_unmap_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir);
154 break;
155 case 1:
156 pci_unmap_single(pdev, SYM_UCMD_PTR(cmd)->data_mapping,
157 cmd->request_bufflen, dma_dir);
158 break;
159 }
160 SYM_UCMD_PTR(cmd)->data_mapped = 0; 152 SYM_UCMD_PTR(cmd)->data_mapped = 0;
161} 153}
162 154
163static dma_addr_t __map_scsi_single_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
164{
165 dma_addr_t mapping;
166 int dma_dir = cmd->sc_data_direction;
167
168 mapping = pci_map_single(pdev, cmd->request_buffer,
169 cmd->request_bufflen, dma_dir);
170 if (mapping) {
171 SYM_UCMD_PTR(cmd)->data_mapped = 1;
172 SYM_UCMD_PTR(cmd)->data_mapping = mapping;
173 }
174
175 return mapping;
176}
177
178static int __map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) 155static int __map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
179{ 156{
180 int use_sg; 157 int use_sg;
181 int dma_dir = cmd->sc_data_direction;
182 158
183 use_sg = pci_map_sg(pdev, cmd->request_buffer, cmd->use_sg, dma_dir); 159 use_sg = scsi_dma_map(cmd);
184 if (use_sg > 0) { 160 if (use_sg > 0) {
185 SYM_UCMD_PTR(cmd)->data_mapped = 2; 161 SYM_UCMD_PTR(cmd)->data_mapped = 2;
186 SYM_UCMD_PTR(cmd)->data_mapping = use_sg; 162 SYM_UCMD_PTR(cmd)->data_mapping = use_sg;
@@ -191,8 +167,6 @@ static int __map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd)
191 167
192#define unmap_scsi_data(np, cmd) \ 168#define unmap_scsi_data(np, cmd) \
193 __unmap_scsi_data(np->s.device, cmd) 169 __unmap_scsi_data(np->s.device, cmd)
194#define map_scsi_single_data(np, cmd) \
195 __map_scsi_single_data(np->s.device, cmd)
196#define map_scsi_sg_data(np, cmd) \ 170#define map_scsi_sg_data(np, cmd) \
197 __map_scsi_sg_data(np->s.device, cmd) 171 __map_scsi_sg_data(np->s.device, cmd)
198/* 172/*
@@ -322,55 +296,20 @@ void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid)
322 */ 296 */
323 cam_status = sym_xerr_cam_status(DID_ERROR, cp->xerr_status); 297 cam_status = sym_xerr_cam_status(DID_ERROR, cp->xerr_status);
324 } 298 }
325 cmd->resid = resid; 299 scsi_set_resid(cmd, resid);
326 cmd->result = (drv_status << 24) + (cam_status << 16) + scsi_status; 300 cmd->result = (drv_status << 24) + (cam_status << 16) + scsi_status;
327} 301}
328 302
329
330/*
331 * Build the scatter/gather array for an I/O.
332 */
333
334static int sym_scatter_no_sglist(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd *cmd)
335{
336 struct sym_tblmove *data = &cp->phys.data[SYM_CONF_MAX_SG-1];
337 int segment;
338 unsigned int len = cmd->request_bufflen;
339
340 if (len) {
341 dma_addr_t baddr = map_scsi_single_data(np, cmd);
342 if (baddr) {
343 if (len & 1) {
344 struct sym_tcb *tp = &np->target[cp->target];
345 if (tp->head.wval & EWS) {
346 len++;
347 cp->odd_byte_adjustment++;
348 }
349 }
350 cp->data_len = len;
351 sym_build_sge(np, data, baddr, len);
352 segment = 1;
353 } else {
354 segment = -2;
355 }
356 } else {
357 segment = 0;
358 }
359
360 return segment;
361}
362
363static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd *cmd) 303static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd *cmd)
364{ 304{
365 int segment; 305 int segment;
366 int use_sg = (int) cmd->use_sg; 306 int use_sg;
367 307
368 cp->data_len = 0; 308 cp->data_len = 0;
369 309
370 if (!use_sg) 310 use_sg = map_scsi_sg_data(np, cmd);
371 segment = sym_scatter_no_sglist(np, cp, cmd); 311 if (use_sg > 0) {
372 else if ((use_sg = map_scsi_sg_data(np, cmd)) > 0) { 312 struct scatterlist *sg;
373 struct scatterlist *scatter = (struct scatterlist *)cmd->request_buffer;
374 struct sym_tcb *tp = &np->target[cp->target]; 313 struct sym_tcb *tp = &np->target[cp->target];
375 struct sym_tblmove *data; 314 struct sym_tblmove *data;
376 315
@@ -381,9 +320,9 @@ static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd
381 320
382 data = &cp->phys.data[SYM_CONF_MAX_SG - use_sg]; 321 data = &cp->phys.data[SYM_CONF_MAX_SG - use_sg];
383 322
384 for (segment = 0; segment < use_sg; segment++) { 323 scsi_for_each_sg(cmd, sg, use_sg, segment) {
385 dma_addr_t baddr = sg_dma_address(&scatter[segment]); 324 dma_addr_t baddr = sg_dma_address(sg);
386 unsigned int len = sg_dma_len(&scatter[segment]); 325 unsigned int len = sg_dma_len(sg);
387 326
388 if ((len & 1) && (tp->head.wval & EWS)) { 327 if ((len & 1) && (tp->head.wval & EWS)) {
389 len++; 328 len++;