diff options
author | Matthew Wilcox <matthew@wil.cx> | 2007-10-02 21:55:41 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-10-12 14:54:05 -0400 |
commit | d10fb2c7b5ce1b475df50cde9262d2c3fe3d296e (patch) | |
tree | fd037eb44ff9ac58cf8f207efc11cb6612d851cf | |
parent | b249c7fda2ca8efcbe37ace1e20a3fffac08bccb (diff) |
[SCSI] advansys: Use dma mapping for overrun buffer
Convert the call to virt_to_bus() into a call to dma_map_single(). Some
architectures may require different DMA addresses for different devices,
so allocate one overrun buffer per host rather than one for all cards.
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/advansys.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 88e7fef18a29..07507a7e9c50 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c | |||
@@ -529,7 +529,6 @@ typedef struct asc_dvc_cfg { | |||
529 | ushort mcode_date; | 529 | ushort mcode_date; |
530 | ushort mcode_version; | 530 | ushort mcode_version; |
531 | uchar max_tag_qng[ASC_MAX_TID + 1]; | 531 | uchar max_tag_qng[ASC_MAX_TID + 1]; |
532 | uchar *overrun_buf; | ||
533 | uchar sdtr_period_offset[ASC_MAX_TID + 1]; | 532 | uchar sdtr_period_offset[ASC_MAX_TID + 1]; |
534 | uchar adapter_info[6]; | 533 | uchar adapter_info[6]; |
535 | } ASC_DVC_CFG; | 534 | } ASC_DVC_CFG; |
@@ -551,6 +550,7 @@ typedef struct asc_dvc_cfg { | |||
551 | #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002 | 550 | #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002 |
552 | #define ASC_MIN_TAGGED_CMD 7 | 551 | #define ASC_MIN_TAGGED_CMD 7 |
553 | #define ASC_MAX_SCSI_RESET_WAIT 30 | 552 | #define ASC_MAX_SCSI_RESET_WAIT 30 |
553 | #define ASC_OVERRUN_BSIZE 64 | ||
554 | 554 | ||
555 | struct asc_dvc_var; /* Forward Declaration. */ | 555 | struct asc_dvc_var; /* Forward Declaration. */ |
556 | 556 | ||
@@ -566,6 +566,8 @@ typedef struct asc_dvc_var { | |||
566 | ASC_SCSI_BIT_ID_TYPE unit_not_ready; | 566 | ASC_SCSI_BIT_ID_TYPE unit_not_ready; |
567 | ASC_SCSI_BIT_ID_TYPE queue_full_or_busy; | 567 | ASC_SCSI_BIT_ID_TYPE queue_full_or_busy; |
568 | ASC_SCSI_BIT_ID_TYPE start_motor; | 568 | ASC_SCSI_BIT_ID_TYPE start_motor; |
569 | uchar overrun_buf[ASC_OVERRUN_BSIZE] __aligned(8); | ||
570 | dma_addr_t overrun_dma; | ||
569 | uchar scsi_reset_wait; | 571 | uchar scsi_reset_wait; |
570 | uchar chip_no; | 572 | uchar chip_no; |
571 | char is_in_int; | 573 | char is_in_int; |
@@ -668,7 +670,6 @@ typedef struct asceep_config { | |||
668 | #define ASC_EEP_CMD_WRITE 0x40 | 670 | #define ASC_EEP_CMD_WRITE 0x40 |
669 | #define ASC_EEP_CMD_WRITE_ABLE 0x30 | 671 | #define ASC_EEP_CMD_WRITE_ABLE 0x30 |
670 | #define ASC_EEP_CMD_WRITE_DISABLE 0x00 | 672 | #define ASC_EEP_CMD_WRITE_DISABLE 0x00 |
671 | #define ASC_OVERRUN_BSIZE 0x00000048UL | ||
672 | #define ASCV_MSGOUT_BEG 0x0000 | 673 | #define ASCV_MSGOUT_BEG 0x0000 |
673 | #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3) | 674 | #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3) |
674 | #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4) | 675 | #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4) |
@@ -2404,13 +2405,12 @@ struct asc_board { | |||
2404 | ushort bios_codelen; /* BIOS Code Segment Length. */ | 2405 | ushort bios_codelen; /* BIOS Code Segment Length. */ |
2405 | }; | 2406 | }; |
2406 | 2407 | ||
2408 | #define asc_dvc_to_board(asc_dvc) container_of(asc_dvc, struct asc_board, \ | ||
2409 | dvc_var.asc_dvc_var) | ||
2407 | #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \ | 2410 | #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \ |
2408 | dvc_var.adv_dvc_var) | 2411 | dvc_var.adv_dvc_var) |
2409 | #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev) | 2412 | #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev) |
2410 | 2413 | ||
2411 | /* Overrun buffer used by all narrow boards. */ | ||
2412 | static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; | ||
2413 | |||
2414 | #ifdef ADVANSYS_DEBUG | 2414 | #ifdef ADVANSYS_DEBUG |
2415 | static int asc_dbglvl = 3; | 2415 | static int asc_dbglvl = 3; |
2416 | 2416 | ||
@@ -2465,8 +2465,8 @@ static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h) | |||
2465 | "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed, | 2465 | "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed, |
2466 | h->isa_dma_channel, h->chip_version); | 2466 | h->isa_dma_channel, h->chip_version); |
2467 | 2467 | ||
2468 | printk(" mcode_date 0x%x, mcode_version %d, overrun_buf 0x%p\n", | 2468 | printk(" mcode_date 0x%x, mcode_version %d\n", |
2469 | h->mcode_date, h->mcode_version, h->overrun_buf); | 2469 | h->mcode_date, h->mcode_version); |
2470 | } | 2470 | } |
2471 | 2471 | ||
2472 | /* | 2472 | /* |
@@ -6316,6 +6316,7 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) | |||
6316 | PortAddr iop_base; | 6316 | PortAddr iop_base; |
6317 | ASC_PADDR phy_addr; | 6317 | ASC_PADDR phy_addr; |
6318 | ASC_DCNT phy_size; | 6318 | ASC_DCNT phy_size; |
6319 | struct asc_board *board = asc_dvc_to_board(asc_dvc); | ||
6319 | 6320 | ||
6320 | iop_base = asc_dvc->iop_base; | 6321 | iop_base = asc_dvc->iop_base; |
6321 | warn_code = 0; | 6322 | warn_code = 0; |
@@ -6330,12 +6331,14 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) | |||
6330 | AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B, | 6331 | AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B, |
6331 | ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id)); | 6332 | ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id)); |
6332 | 6333 | ||
6333 | /* Align overrun buffer on an 8 byte boundary. */ | 6334 | /* Ensure overrun buffer is aligned on an 8 byte boundary. */ |
6334 | phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf); | 6335 | BUG_ON((unsigned long)asc_dvc->overrun_buf & 7); |
6335 | phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7); | 6336 | asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf, |
6337 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); | ||
6338 | phy_addr = cpu_to_le32(asc_dvc->overrun_dma); | ||
6336 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, | 6339 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, |
6337 | (uchar *)&phy_addr, 1); | 6340 | (uchar *)&phy_addr, 1); |
6338 | phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8); | 6341 | phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE); |
6339 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D, | 6342 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D, |
6340 | (uchar *)&phy_size, 1); | 6343 | (uchar *)&phy_size, 1); |
6341 | 6344 | ||
@@ -13404,7 +13407,6 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, | |||
13404 | asc_dvc_varp->bus_type = bus_type; | 13407 | asc_dvc_varp->bus_type = bus_type; |
13405 | asc_dvc_varp->drv_ptr = boardp; | 13408 | asc_dvc_varp->drv_ptr = boardp; |
13406 | asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg; | 13409 | asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg; |
13407 | asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0]; | ||
13408 | asc_dvc_varp->iop_base = iop; | 13410 | asc_dvc_varp->iop_base = iop; |
13409 | } else { | 13411 | } else { |
13410 | #ifdef CONFIG_PCI | 13412 | #ifdef CONFIG_PCI |
@@ -13880,19 +13882,23 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, | |||
13880 | */ | 13882 | */ |
13881 | static int advansys_release(struct Scsi_Host *shost) | 13883 | static int advansys_release(struct Scsi_Host *shost) |
13882 | { | 13884 | { |
13883 | struct asc_board *boardp = shost_priv(shost); | 13885 | struct asc_board *board = shost_priv(shost); |
13884 | ASC_DBG(1, "begin\n"); | 13886 | ASC_DBG(1, "begin\n"); |
13885 | scsi_remove_host(shost); | 13887 | scsi_remove_host(shost); |
13886 | free_irq(boardp->irq, shost); | 13888 | free_irq(board->irq, shost); |
13887 | if (shost->dma_channel != NO_ISA_DMA) { | 13889 | if (shost->dma_channel != NO_ISA_DMA) { |
13888 | ASC_DBG(1, "free_dma()\n"); | 13890 | ASC_DBG(1, "free_dma()\n"); |
13889 | free_dma(shost->dma_channel); | 13891 | free_dma(shost->dma_channel); |
13890 | } | 13892 | } |
13891 | if (!ASC_NARROW_BOARD(boardp)) { | 13893 | if (ASC_NARROW_BOARD(board)) { |
13892 | iounmap(boardp->ioremap_addr); | 13894 | dma_unmap_single(board->dev, |
13893 | advansys_wide_free_mem(boardp); | 13895 | board->dvc_var.asc_dvc_var.overrun_dma, |
13896 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); | ||
13897 | } else { | ||
13898 | iounmap(board->ioremap_addr); | ||
13899 | advansys_wide_free_mem(board); | ||
13894 | } | 13900 | } |
13895 | kfree(boardp->prtbuf); | 13901 | kfree(board->prtbuf); |
13896 | scsi_host_put(shost); | 13902 | scsi_host_put(shost); |
13897 | ASC_DBG(1, "end\n"); | 13903 | ASC_DBG(1, "end\n"); |
13898 | return 0; | 13904 | return 0; |