diff options
Diffstat (limited to 'drivers/scsi/mac53c94.c')
-rw-r--r-- | drivers/scsi/mac53c94.c | 62 |
1 files changed, 21 insertions, 41 deletions
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 5806ede120a4..b12ad7c7c673 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c | |||
@@ -77,7 +77,7 @@ static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd * | |||
77 | for (i = 0; i < cmd->cmd_len; ++i) | 77 | for (i = 0; i < cmd->cmd_len; ++i) |
78 | printk(" %.2x", cmd->cmnd[i]); | 78 | printk(" %.2x", cmd->cmnd[i]); |
79 | printk("\n" KERN_DEBUG "use_sg=%d request_bufflen=%d request_buffer=%p\n", | 79 | printk("\n" KERN_DEBUG "use_sg=%d request_bufflen=%d request_buffer=%p\n", |
80 | cmd->use_sg, cmd->request_bufflen, cmd->request_buffer); | 80 | scsi_sg_count(cmd), scsi_bufflen(cmd), scsi_sglist(cmd)); |
81 | } | 81 | } |
82 | #endif | 82 | #endif |
83 | 83 | ||
@@ -173,8 +173,7 @@ static void mac53c94_start(struct fsc_state *state) | |||
173 | writeb(CMD_SELECT, ®s->command); | 173 | writeb(CMD_SELECT, ®s->command); |
174 | state->phase = selecting; | 174 | state->phase = selecting; |
175 | 175 | ||
176 | if (cmd->use_sg > 0 || cmd->request_bufflen != 0) | 176 | set_dma_cmds(state, cmd); |
177 | set_dma_cmds(state, cmd); | ||
178 | } | 177 | } |
179 | 178 | ||
180 | static irqreturn_t do_mac53c94_interrupt(int irq, void *dev_id) | 179 | static irqreturn_t do_mac53c94_interrupt(int irq, void *dev_id) |
@@ -262,7 +261,7 @@ static void mac53c94_interrupt(int irq, void *dev_id) | |||
262 | writeb(CMD_NOP, ®s->command); | 261 | writeb(CMD_NOP, ®s->command); |
263 | /* set DMA controller going if any data to transfer */ | 262 | /* set DMA controller going if any data to transfer */ |
264 | if ((stat & (STAT_MSG|STAT_CD)) == 0 | 263 | if ((stat & (STAT_MSG|STAT_CD)) == 0 |
265 | && (cmd->use_sg > 0 || cmd->request_bufflen != 0)) { | 264 | && (scsi_sg_count(cmd) > 0 || scsi_bufflen(cmd))) { |
266 | nb = cmd->SCp.this_residual; | 265 | nb = cmd->SCp.this_residual; |
267 | if (nb > 0xfff0) | 266 | if (nb > 0xfff0) |
268 | nb = 0xfff0; | 267 | nb = 0xfff0; |
@@ -310,14 +309,7 @@ static void mac53c94_interrupt(int irq, void *dev_id) | |||
310 | printk(KERN_DEBUG "intr %x before data xfer complete\n", intr); | 309 | printk(KERN_DEBUG "intr %x before data xfer complete\n", intr); |
311 | } | 310 | } |
312 | writel(RUN << 16, &dma->control); /* stop dma */ | 311 | writel(RUN << 16, &dma->control); /* stop dma */ |
313 | if (cmd->use_sg != 0) { | 312 | scsi_dma_unmap(cmd); |
314 | pci_unmap_sg(state->pdev, | ||
315 | (struct scatterlist *)cmd->request_buffer, | ||
316 | cmd->use_sg, cmd->sc_data_direction); | ||
317 | } else { | ||
318 | pci_unmap_single(state->pdev, state->dma_addr, | ||
319 | cmd->request_bufflen, cmd->sc_data_direction); | ||
320 | } | ||
321 | /* should check dma status */ | 313 | /* should check dma status */ |
322 | writeb(CMD_I_COMPLETE, ®s->command); | 314 | writeb(CMD_I_COMPLETE, ®s->command); |
323 | state->phase = completing; | 315 | state->phase = completing; |
@@ -365,47 +357,35 @@ static void cmd_done(struct fsc_state *state, int result) | |||
365 | */ | 357 | */ |
366 | static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd) | 358 | static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd) |
367 | { | 359 | { |
368 | int i, dma_cmd, total; | 360 | int i, dma_cmd, total, nseg; |
369 | struct scatterlist *scl; | 361 | struct scatterlist *scl; |
370 | struct dbdma_cmd *dcmds; | 362 | struct dbdma_cmd *dcmds; |
371 | dma_addr_t dma_addr; | 363 | dma_addr_t dma_addr; |
372 | u32 dma_len; | 364 | u32 dma_len; |
373 | 365 | ||
366 | nseg = scsi_dma_map(cmd); | ||
367 | BUG_ON(nseg < 0); | ||
368 | if (!nseg) | ||
369 | return; | ||
370 | |||
374 | dma_cmd = cmd->sc_data_direction == DMA_TO_DEVICE ? | 371 | dma_cmd = cmd->sc_data_direction == DMA_TO_DEVICE ? |
375 | OUTPUT_MORE : INPUT_MORE; | 372 | OUTPUT_MORE : INPUT_MORE; |
376 | dcmds = state->dma_cmds; | 373 | dcmds = state->dma_cmds; |
377 | if (cmd->use_sg > 0) { | 374 | total = 0; |
378 | int nseg; | 375 | |
379 | 376 | scsi_for_each_sg(cmd, scl, nseg, i) { | |
380 | total = 0; | 377 | dma_addr = sg_dma_address(scl); |
381 | scl = (struct scatterlist *) cmd->request_buffer; | 378 | dma_len = sg_dma_len(scl); |
382 | nseg = pci_map_sg(state->pdev, scl, cmd->use_sg, | 379 | if (dma_len > 0xffff) |
383 | cmd->sc_data_direction); | 380 | panic("mac53c94: scatterlist element >= 64k"); |
384 | for (i = 0; i < nseg; ++i) { | 381 | total += dma_len; |
385 | dma_addr = sg_dma_address(scl); | 382 | st_le16(&dcmds->req_count, dma_len); |
386 | dma_len = sg_dma_len(scl); | 383 | st_le16(&dcmds->command, dma_cmd); |
387 | if (dma_len > 0xffff) | ||
388 | panic("mac53c94: scatterlist element >= 64k"); | ||
389 | total += dma_len; | ||
390 | st_le16(&dcmds->req_count, dma_len); | ||
391 | st_le16(&dcmds->command, dma_cmd); | ||
392 | st_le32(&dcmds->phy_addr, dma_addr); | ||
393 | dcmds->xfer_status = 0; | ||
394 | ++scl; | ||
395 | ++dcmds; | ||
396 | } | ||
397 | } else { | ||
398 | total = cmd->request_bufflen; | ||
399 | if (total > 0xffff) | ||
400 | panic("mac53c94: transfer size >= 64k"); | ||
401 | dma_addr = pci_map_single(state->pdev, cmd->request_buffer, | ||
402 | total, cmd->sc_data_direction); | ||
403 | state->dma_addr = dma_addr; | ||
404 | st_le16(&dcmds->req_count, total); | ||
405 | st_le32(&dcmds->phy_addr, dma_addr); | 384 | st_le32(&dcmds->phy_addr, dma_addr); |
406 | dcmds->xfer_status = 0; | 385 | dcmds->xfer_status = 0; |
407 | ++dcmds; | 386 | ++dcmds; |
408 | } | 387 | } |
388 | |||
409 | dma_cmd += OUTPUT_LAST - OUTPUT_MORE; | 389 | dma_cmd += OUTPUT_LAST - OUTPUT_MORE; |
410 | st_le16(&dcmds[-1].command, dma_cmd); | 390 | st_le16(&dcmds[-1].command, dma_cmd); |
411 | st_le16(&dcmds->command, DBDMA_STOP); | 391 | st_le16(&dcmds->command, DBDMA_STOP); |