diff options
Diffstat (limited to 'drivers/scsi/sym53c8xx_2/sym_glue.c')
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_glue.c | 83 |
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 | ||
147 | static void __unmap_scsi_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) | 147 | static 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 | ||
163 | static 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 | |||
178 | static int __map_scsi_sg_data(struct pci_dev *pdev, struct scsi_cmnd *cmd) | 155 | static 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 | |||
334 | static 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 | |||
363 | static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd *cmd) | 303 | static 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++; |