|
@@ -4724,6 +4724,10 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
|
|
|
BUG_ON((unsigned long)asc_dvc->overrun_buf & 7);
|
|
|
asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf,
|
|
|
ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
|
|
|
+ if (dma_mapping_error(board->dev, asc_dvc->overrun_dma)) {
|
|
|
+ warn_code = -ENOMEM;
|
|
|
+ goto err_dma_map;
|
|
|
+ }
|
|
|
phy_addr = cpu_to_le32(asc_dvc->overrun_dma);
|
|
|
AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D,
|
|
|
(uchar *)&phy_addr, 1);
|
|
@@ -4739,14 +4743,23 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
|
|
|
AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
|
|
|
if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
|
|
|
asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
|
|
|
- return warn_code;
|
|
|
+ warn_code = UW_ERR;
|
|
|
+ goto err_mcode_start;
|
|
|
}
|
|
|
if (AscStartChip(iop_base) != 1) {
|
|
|
asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
|
|
|
- return warn_code;
|
|
|
+ warn_code = UW_ERR;
|
|
|
+ goto err_mcode_start;
|
|
|
}
|
|
|
|
|
|
return warn_code;
|
|
|
+
|
|
|
+err_mcode_start:
|
|
|
+ dma_unmap_single(board->dev, asc_dvc->overrun_dma,
|
|
|
+ ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
|
|
|
+err_dma_map:
|
|
|
+ asc_dvc->overrun_dma = 0;
|
|
|
+ return warn_code;
|
|
|
}
|
|
|
|
|
|
static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
|
|
@@ -4802,6 +4815,8 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
|
|
|
}
|
|
|
release_firmware(fw);
|
|
|
warn_code |= AscInitMicroCodeVar(asc_dvc);
|
|
|
+ if (!asc_dvc->overrun_dma)
|
|
|
+ return warn_code;
|
|
|
asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
|
|
|
AscEnableInterrupt(iop_base);
|
|
|
return warn_code;
|
|
@@ -7978,9 +7993,10 @@ static int advansys_reset(struct scsi_cmnd *scp)
|
|
|
status = AscInitAsc1000Driver(asc_dvc);
|
|
|
|
|
|
/* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */
|
|
|
- if (asc_dvc->err_code) {
|
|
|
+ if (asc_dvc->err_code || !asc_dvc->overrun_dma) {
|
|
|
scmd_printk(KERN_INFO, scp, "SCSI bus reset error: "
|
|
|
- "0x%x\n", asc_dvc->err_code);
|
|
|
+ "0x%x, status: 0x%x\n", asc_dvc->err_code,
|
|
|
+ status);
|
|
|
ret = FAILED;
|
|
|
} else if (status) {
|
|
|
scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: "
|
|
@@ -12311,7 +12327,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
|
|
|
asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL);
|
|
|
if (!asc_dvc_varp->overrun_buf) {
|
|
|
ret = -ENOMEM;
|
|
|
- goto err_free_wide_mem;
|
|
|
+ goto err_free_irq;
|
|
|
}
|
|
|
warn_code = AscInitAsc1000Driver(asc_dvc_varp);
|
|
|
|
|
@@ -12320,30 +12336,36 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
|
|
|
"warn 0x%x, error 0x%x\n",
|
|
|
asc_dvc_varp->init_state, warn_code,
|
|
|
asc_dvc_varp->err_code);
|
|
|
- if (asc_dvc_varp->err_code) {
|
|
|
+ if (!asc_dvc_varp->overrun_dma) {
|
|
|
ret = -ENODEV;
|
|
|
- kfree(asc_dvc_varp->overrun_buf);
|
|
|
+ goto err_free_mem;
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
- if (advansys_wide_init_chip(shost))
|
|
|
+ if (advansys_wide_init_chip(shost)) {
|
|
|
ret = -ENODEV;
|
|
|
+ goto err_free_mem;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- if (ret)
|
|
|
- goto err_free_wide_mem;
|
|
|
-
|
|
|
ASC_DBG_PRT_SCSI_HOST(2, shost);
|
|
|
|
|
|
ret = scsi_add_host(shost, boardp->dev);
|
|
|
if (ret)
|
|
|
- goto err_free_wide_mem;
|
|
|
+ goto err_free_mem;
|
|
|
|
|
|
scsi_scan_host(shost);
|
|
|
return 0;
|
|
|
|
|
|
- err_free_wide_mem:
|
|
|
- advansys_wide_free_mem(boardp);
|
|
|
+ err_free_mem:
|
|
|
+ if (ASC_NARROW_BOARD(boardp)) {
|
|
|
+ if (asc_dvc_varp->overrun_dma)
|
|
|
+ dma_unmap_single(boardp->dev, asc_dvc_varp->overrun_dma,
|
|
|
+ ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE);
|
|
|
+ kfree(asc_dvc_varp->overrun_buf);
|
|
|
+ } else
|
|
|
+ advansys_wide_free_mem(boardp);
|
|
|
+ err_free_irq:
|
|
|
free_irq(boardp->irq, shost);
|
|
|
err_free_dma:
|
|
|
#ifdef CONFIG_ISA
|