diff options
Diffstat (limited to 'drivers/scsi/advansys.c')
-rw-r--r-- | drivers/scsi/advansys.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index b756041f0b26..7f87979da22d 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c | |||
@@ -4724,6 +4724,10 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) | |||
4724 | BUG_ON((unsigned long)asc_dvc->overrun_buf & 7); | 4724 | BUG_ON((unsigned long)asc_dvc->overrun_buf & 7); |
4725 | asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf, | 4725 | asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf, |
4726 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); | 4726 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); |
4727 | if (dma_mapping_error(board->dev, asc_dvc->overrun_dma)) { | ||
4728 | warn_code = -ENOMEM; | ||
4729 | goto err_dma_map; | ||
4730 | } | ||
4727 | phy_addr = cpu_to_le32(asc_dvc->overrun_dma); | 4731 | phy_addr = cpu_to_le32(asc_dvc->overrun_dma); |
4728 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, | 4732 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, |
4729 | (uchar *)&phy_addr, 1); | 4733 | (uchar *)&phy_addr, 1); |
@@ -4739,14 +4743,23 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) | |||
4739 | AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); | 4743 | AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); |
4740 | if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { | 4744 | if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { |
4741 | asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; | 4745 | asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; |
4742 | return warn_code; | 4746 | warn_code = UW_ERR; |
4747 | goto err_mcode_start; | ||
4743 | } | 4748 | } |
4744 | if (AscStartChip(iop_base) != 1) { | 4749 | if (AscStartChip(iop_base) != 1) { |
4745 | asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; | 4750 | asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; |
4746 | return warn_code; | 4751 | warn_code = UW_ERR; |
4752 | goto err_mcode_start; | ||
4747 | } | 4753 | } |
4748 | 4754 | ||
4749 | return warn_code; | 4755 | return warn_code; |
4756 | |||
4757 | err_mcode_start: | ||
4758 | dma_unmap_single(board->dev, asc_dvc->overrun_dma, | ||
4759 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); | ||
4760 | err_dma_map: | ||
4761 | asc_dvc->overrun_dma = 0; | ||
4762 | return warn_code; | ||
4750 | } | 4763 | } |
4751 | 4764 | ||
4752 | static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) | 4765 | static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) |
@@ -4781,12 +4794,14 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) | |||
4781 | if (err) { | 4794 | if (err) { |
4782 | printk(KERN_ERR "Failed to load image \"%s\" err %d\n", | 4795 | printk(KERN_ERR "Failed to load image \"%s\" err %d\n", |
4783 | fwname, err); | 4796 | fwname, err); |
4797 | asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; | ||
4784 | return err; | 4798 | return err; |
4785 | } | 4799 | } |
4786 | if (fw->size < 4) { | 4800 | if (fw->size < 4) { |
4787 | printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", | 4801 | printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", |
4788 | fw->size, fwname); | 4802 | fw->size, fwname); |
4789 | release_firmware(fw); | 4803 | release_firmware(fw); |
4804 | asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; | ||
4790 | return -EINVAL; | 4805 | return -EINVAL; |
4791 | } | 4806 | } |
4792 | chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | | 4807 | chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | |
@@ -4800,6 +4815,8 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) | |||
4800 | } | 4815 | } |
4801 | release_firmware(fw); | 4816 | release_firmware(fw); |
4802 | warn_code |= AscInitMicroCodeVar(asc_dvc); | 4817 | warn_code |= AscInitMicroCodeVar(asc_dvc); |
4818 | if (!asc_dvc->overrun_dma) | ||
4819 | return warn_code; | ||
4803 | asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC; | 4820 | asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC; |
4804 | AscEnableInterrupt(iop_base); | 4821 | AscEnableInterrupt(iop_base); |
4805 | return warn_code; | 4822 | return warn_code; |
@@ -5110,12 +5127,14 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) | |||
5110 | if (err) { | 5127 | if (err) { |
5111 | printk(KERN_ERR "Failed to load image \"%s\" err %d\n", | 5128 | printk(KERN_ERR "Failed to load image \"%s\" err %d\n", |
5112 | fwname, err); | 5129 | fwname, err); |
5130 | asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; | ||
5113 | return err; | 5131 | return err; |
5114 | } | 5132 | } |
5115 | if (fw->size < 4) { | 5133 | if (fw->size < 4) { |
5116 | printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", | 5134 | printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", |
5117 | fw->size, fwname); | 5135 | fw->size, fwname); |
5118 | release_firmware(fw); | 5136 | release_firmware(fw); |
5137 | asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; | ||
5119 | return -EINVAL; | 5138 | return -EINVAL; |
5120 | } | 5139 | } |
5121 | chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | | 5140 | chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | |
@@ -5624,12 +5643,14 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) | |||
5624 | if (err) { | 5643 | if (err) { |
5625 | printk(KERN_ERR "Failed to load image \"%s\" err %d\n", | 5644 | printk(KERN_ERR "Failed to load image \"%s\" err %d\n", |
5626 | fwname, err); | 5645 | fwname, err); |
5646 | asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; | ||
5627 | return err; | 5647 | return err; |
5628 | } | 5648 | } |
5629 | if (fw->size < 4) { | 5649 | if (fw->size < 4) { |
5630 | printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", | 5650 | printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", |
5631 | fw->size, fwname); | 5651 | fw->size, fwname); |
5632 | release_firmware(fw); | 5652 | release_firmware(fw); |
5653 | asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; | ||
5633 | return -EINVAL; | 5654 | return -EINVAL; |
5634 | } | 5655 | } |
5635 | chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | | 5656 | chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | |
@@ -6124,12 +6145,14 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) | |||
6124 | if (err) { | 6145 | if (err) { |
6125 | printk(KERN_ERR "Failed to load image \"%s\" err %d\n", | 6146 | printk(KERN_ERR "Failed to load image \"%s\" err %d\n", |
6126 | fwname, err); | 6147 | fwname, err); |
6148 | asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; | ||
6127 | return err; | 6149 | return err; |
6128 | } | 6150 | } |
6129 | if (fw->size < 4) { | 6151 | if (fw->size < 4) { |
6130 | printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", | 6152 | printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", |
6131 | fw->size, fwname); | 6153 | fw->size, fwname); |
6132 | release_firmware(fw); | 6154 | release_firmware(fw); |
6155 | asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; | ||
6133 | return -EINVAL; | 6156 | return -EINVAL; |
6134 | } | 6157 | } |
6135 | chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | | 6158 | chksum = (fw->data[3] << 24) | (fw->data[2] << 16) | |
@@ -7969,10 +7992,11 @@ static int advansys_reset(struct scsi_cmnd *scp) | |||
7969 | ASC_DBG(1, "before AscInitAsc1000Driver()\n"); | 7992 | ASC_DBG(1, "before AscInitAsc1000Driver()\n"); |
7970 | status = AscInitAsc1000Driver(asc_dvc); | 7993 | status = AscInitAsc1000Driver(asc_dvc); |
7971 | 7994 | ||
7972 | /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */ | 7995 | /* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */ |
7973 | if (asc_dvc->err_code) { | 7996 | if (asc_dvc->err_code || !asc_dvc->overrun_dma) { |
7974 | scmd_printk(KERN_INFO, scp, "SCSI bus reset error: " | 7997 | scmd_printk(KERN_INFO, scp, "SCSI bus reset error: " |
7975 | "0x%x\n", asc_dvc->err_code); | 7998 | "0x%x, status: 0x%x\n", asc_dvc->err_code, |
7999 | status); | ||
7976 | ret = FAILED; | 8000 | ret = FAILED; |
7977 | } else if (status) { | 8001 | } else if (status) { |
7978 | scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: " | 8002 | scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: " |
@@ -12303,7 +12327,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, | |||
12303 | asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL); | 12327 | asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL); |
12304 | if (!asc_dvc_varp->overrun_buf) { | 12328 | if (!asc_dvc_varp->overrun_buf) { |
12305 | ret = -ENOMEM; | 12329 | ret = -ENOMEM; |
12306 | goto err_free_wide_mem; | 12330 | goto err_free_irq; |
12307 | } | 12331 | } |
12308 | warn_code = AscInitAsc1000Driver(asc_dvc_varp); | 12332 | warn_code = AscInitAsc1000Driver(asc_dvc_varp); |
12309 | 12333 | ||
@@ -12312,30 +12336,36 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, | |||
12312 | "warn 0x%x, error 0x%x\n", | 12336 | "warn 0x%x, error 0x%x\n", |
12313 | asc_dvc_varp->init_state, warn_code, | 12337 | asc_dvc_varp->init_state, warn_code, |
12314 | asc_dvc_varp->err_code); | 12338 | asc_dvc_varp->err_code); |
12315 | if (asc_dvc_varp->err_code) { | 12339 | if (!asc_dvc_varp->overrun_dma) { |
12316 | ret = -ENODEV; | 12340 | ret = -ENODEV; |
12317 | kfree(asc_dvc_varp->overrun_buf); | 12341 | goto err_free_mem; |
12318 | } | 12342 | } |
12319 | } | 12343 | } |
12320 | } else { | 12344 | } else { |
12321 | if (advansys_wide_init_chip(shost)) | 12345 | if (advansys_wide_init_chip(shost)) { |
12322 | ret = -ENODEV; | 12346 | ret = -ENODEV; |
12347 | goto err_free_mem; | ||
12348 | } | ||
12323 | } | 12349 | } |
12324 | 12350 | ||
12325 | if (ret) | ||
12326 | goto err_free_wide_mem; | ||
12327 | |||
12328 | ASC_DBG_PRT_SCSI_HOST(2, shost); | 12351 | ASC_DBG_PRT_SCSI_HOST(2, shost); |
12329 | 12352 | ||
12330 | ret = scsi_add_host(shost, boardp->dev); | 12353 | ret = scsi_add_host(shost, boardp->dev); |
12331 | if (ret) | 12354 | if (ret) |
12332 | goto err_free_wide_mem; | 12355 | goto err_free_mem; |
12333 | 12356 | ||
12334 | scsi_scan_host(shost); | 12357 | scsi_scan_host(shost); |
12335 | return 0; | 12358 | return 0; |
12336 | 12359 | ||
12337 | err_free_wide_mem: | 12360 | err_free_mem: |
12338 | advansys_wide_free_mem(boardp); | 12361 | if (ASC_NARROW_BOARD(boardp)) { |
12362 | if (asc_dvc_varp->overrun_dma) | ||
12363 | dma_unmap_single(boardp->dev, asc_dvc_varp->overrun_dma, | ||
12364 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); | ||
12365 | kfree(asc_dvc_varp->overrun_buf); | ||
12366 | } else | ||
12367 | advansys_wide_free_mem(boardp); | ||
12368 | err_free_irq: | ||
12339 | free_irq(boardp->irq, shost); | 12369 | free_irq(boardp->irq, shost); |
12340 | err_free_dma: | 12370 | err_free_dma: |
12341 | #ifdef CONFIG_ISA | 12371 | #ifdef CONFIG_ISA |