diff options
author | Matthew Wilcox <matthew@wil.cx> | 2007-07-29 19:30:28 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.localdomain> | 2007-10-12 14:38:49 -0400 |
commit | b2c16f586ee529e97ac63183e70e2bfd586a2f47 (patch) | |
tree | 7dcbddc023b22fa6ff740f8217317288309f0d29 /drivers/scsi/advansys.c | |
parent | 605fe5987f728e92e75ba12f7be01ffc3b132ad0 (diff) |
[SCSI] advansys: Make advansys_board_found a little more readable
- Put all the error cleanup at the end of the function and goto the
appropriate label
- Split advansys_wide_init_chip out of advansys_board_found
- Split advansys_wide_free_mem out of advansys_board_found. Use it
from advansys_release
- Use GFP_KERNEL, not GFP_ATOMIC, when allocating memory during
initialisation
- Eliminate lots of PROC_FS ifdefs by removing the ifdefs around the prtbuf
struct member
Signed-off-by: Matthew Wilcox <matthew@wil.cx>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/advansys.c')
-rw-r--r-- | drivers/scsi/advansys.c | 394 |
1 files changed, 158 insertions, 236 deletions
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 7a964bb75acb..303dc98b45c0 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c | |||
@@ -3825,10 +3825,8 @@ typedef struct asc_board { | |||
3825 | } eep_config; | 3825 | } eep_config; |
3826 | ulong last_reset; /* Saved last reset time */ | 3826 | ulong last_reset; /* Saved last reset time */ |
3827 | spinlock_t lock; /* Board spinlock */ | 3827 | spinlock_t lock; /* Board spinlock */ |
3828 | #ifdef CONFIG_PROC_FS | ||
3829 | /* /proc/scsi/advansys/[0...] */ | 3828 | /* /proc/scsi/advansys/[0...] */ |
3830 | char *prtbuf; /* /proc print buffer */ | 3829 | char *prtbuf; /* /proc print buffer */ |
3831 | #endif /* CONFIG_PROC_FS */ | ||
3832 | #ifdef ADVANSYS_STATS | 3830 | #ifdef ADVANSYS_STATS |
3833 | struct asc_stats asc_stats; /* Board statistics */ | 3831 | struct asc_stats asc_stats; /* Board statistics */ |
3834 | #endif /* ADVANSYS_STATS */ | 3832 | #endif /* ADVANSYS_STATS */ |
@@ -3845,7 +3843,7 @@ typedef struct asc_board { | |||
3845 | */ | 3843 | */ |
3846 | void __iomem *ioremap_addr; /* I/O Memory remap address. */ | 3844 | void __iomem *ioremap_addr; /* I/O Memory remap address. */ |
3847 | ushort ioport; /* I/O Port address. */ | 3845 | ushort ioport; /* I/O Port address. */ |
3848 | ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */ | 3846 | ADV_CARR_T *carrp; /* ADV_CARR_T memory block. */ |
3849 | adv_req_t *orig_reqp; /* adv_req_t memory block. */ | 3847 | adv_req_t *orig_reqp; /* adv_req_t memory block. */ |
3850 | adv_req_t *adv_reqp; /* Request structures. */ | 3848 | adv_req_t *adv_reqp; /* Request structures. */ |
3851 | adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */ | 3849 | adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */ |
@@ -17703,6 +17701,124 @@ static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) | |||
17703 | } | 17701 | } |
17704 | } | 17702 | } |
17705 | 17703 | ||
17704 | static int __devinit | ||
17705 | advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp) | ||
17706 | { | ||
17707 | int req_cnt = 0; | ||
17708 | adv_req_t *reqp = NULL; | ||
17709 | int sg_cnt = 0; | ||
17710 | adv_sgblk_t *sgp; | ||
17711 | int warn_code, err_code; | ||
17712 | |||
17713 | /* | ||
17714 | * Allocate buffer carrier structures. The total size | ||
17715 | * is about 4 KB, so allocate all at once. | ||
17716 | */ | ||
17717 | boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL); | ||
17718 | ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp); | ||
17719 | |||
17720 | if (!boardp->carrp) | ||
17721 | goto kmalloc_failed; | ||
17722 | |||
17723 | /* | ||
17724 | * Allocate up to 'max_host_qng' request structures for the Wide | ||
17725 | * board. The total size is about 16 KB, so allocate all at once. | ||
17726 | * If the allocation fails decrement and try again. | ||
17727 | */ | ||
17728 | for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) { | ||
17729 | reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL); | ||
17730 | |||
17731 | ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, " | ||
17732 | "bytes %lu\n", reqp, req_cnt, | ||
17733 | (ulong)sizeof(adv_req_t) * req_cnt); | ||
17734 | |||
17735 | if (reqp) | ||
17736 | break; | ||
17737 | } | ||
17738 | |||
17739 | if (!reqp) | ||
17740 | goto kmalloc_failed; | ||
17741 | |||
17742 | boardp->orig_reqp = reqp; | ||
17743 | |||
17744 | /* | ||
17745 | * Allocate up to ADV_TOT_SG_BLOCK request structures for | ||
17746 | * the Wide board. Each structure is about 136 bytes. | ||
17747 | */ | ||
17748 | boardp->adv_sgblkp = NULL; | ||
17749 | for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) { | ||
17750 | sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL); | ||
17751 | |||
17752 | if (!sgp) | ||
17753 | break; | ||
17754 | |||
17755 | sgp->next_sgblkp = boardp->adv_sgblkp; | ||
17756 | boardp->adv_sgblkp = sgp; | ||
17757 | |||
17758 | } | ||
17759 | |||
17760 | ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n", | ||
17761 | sg_cnt, sizeof(adv_sgblk_t), | ||
17762 | (unsigned)(sizeof(adv_sgblk_t) * sg_cnt)); | ||
17763 | |||
17764 | if (!boardp->adv_sgblkp) | ||
17765 | goto kmalloc_failed; | ||
17766 | |||
17767 | adv_dvc_varp->carrier_buf = boardp->carrp; | ||
17768 | |||
17769 | /* | ||
17770 | * Point 'adv_reqp' to the request structures and | ||
17771 | * link them together. | ||
17772 | */ | ||
17773 | req_cnt--; | ||
17774 | reqp[req_cnt].next_reqp = NULL; | ||
17775 | for (; req_cnt > 0; req_cnt--) { | ||
17776 | reqp[req_cnt - 1].next_reqp = &reqp[req_cnt]; | ||
17777 | } | ||
17778 | boardp->adv_reqp = &reqp[0]; | ||
17779 | |||
17780 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { | ||
17781 | ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n"); | ||
17782 | warn_code = AdvInitAsc3550Driver(adv_dvc_varp); | ||
17783 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { | ||
17784 | ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()" | ||
17785 | "\n"); | ||
17786 | warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp); | ||
17787 | } else { | ||
17788 | ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()" | ||
17789 | "\n"); | ||
17790 | warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp); | ||
17791 | } | ||
17792 | err_code = adv_dvc_varp->err_code; | ||
17793 | |||
17794 | if (warn_code || err_code) { | ||
17795 | ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x," | ||
17796 | " error 0x%x\n", boardp->id, warn_code, err_code); | ||
17797 | } | ||
17798 | |||
17799 | goto exit; | ||
17800 | |||
17801 | kmalloc_failed: | ||
17802 | ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() " | ||
17803 | "failed\n", boardp->id); | ||
17804 | err_code = ADV_ERROR; | ||
17805 | exit: | ||
17806 | return err_code; | ||
17807 | } | ||
17808 | |||
17809 | static void advansys_wide_free_mem(asc_board_t *boardp) | ||
17810 | { | ||
17811 | kfree(boardp->carrp); | ||
17812 | boardp->carrp = NULL; | ||
17813 | kfree(boardp->orig_reqp); | ||
17814 | boardp->orig_reqp = boardp->adv_reqp = NULL; | ||
17815 | while (boardp->adv_sgblkp) { | ||
17816 | adv_sgblk_t *sgp = boardp->adv_sgblkp; | ||
17817 | boardp->adv_sgblkp = sgp->next_sgblkp; | ||
17818 | kfree(sgp); | ||
17819 | } | ||
17820 | } | ||
17821 | |||
17706 | static struct Scsi_Host *__devinit | 17822 | static struct Scsi_Host *__devinit |
17707 | advansys_board_found(int iop, struct device *dev, int bus_type) | 17823 | advansys_board_found(int iop, struct device *dev, int bus_type) |
17708 | { | 17824 | { |
@@ -17711,7 +17827,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
17711 | asc_board_t *boardp; | 17827 | asc_board_t *boardp; |
17712 | ASC_DVC_VAR *asc_dvc_varp = NULL; | 17828 | ASC_DVC_VAR *asc_dvc_varp = NULL; |
17713 | ADV_DVC_VAR *adv_dvc_varp = NULL; | 17829 | ADV_DVC_VAR *adv_dvc_varp = NULL; |
17714 | adv_sgblk_t *sgp = NULL; | ||
17715 | int share_irq; | 17830 | int share_irq; |
17716 | int iolen = 0; | 17831 | int iolen = 0; |
17717 | ADV_PADDR pci_memory_address; | 17832 | ADV_PADDR pci_memory_address; |
@@ -17814,9 +17929,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
17814 | ASC_PRINT3 | 17929 | ASC_PRINT3 |
17815 | ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n", | 17930 | ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n", |
17816 | boardp->id, pci_memory_address, iolen); | 17931 | boardp->id, pci_memory_address, iolen); |
17817 | scsi_unregister(shost); | 17932 | goto err_shost; |
17818 | asc_board_count--; | ||
17819 | return NULL; | ||
17820 | } | 17933 | } |
17821 | ASC_DBG1(1, | 17934 | ASC_DBG1(1, |
17822 | "advansys_board_found: ioremap_addr: 0x%lx\n", | 17935 | "advansys_board_found: ioremap_addr: 0x%lx\n", |
@@ -17846,13 +17959,11 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
17846 | * Allocate buffer for printing information from | 17959 | * Allocate buffer for printing information from |
17847 | * /proc/scsi/advansys/[0...]. | 17960 | * /proc/scsi/advansys/[0...]. |
17848 | */ | 17961 | */ |
17849 | if ((boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) { | 17962 | boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL); |
17850 | ASC_PRINT3 | 17963 | if (!boardp->prtbuf) { |
17851 | ("advansys_board_found: board %d: kmalloc(%d, %d) returned NULL\n", | 17964 | ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) " |
17852 | boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC); | 17965 | "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE); |
17853 | scsi_unregister(shost); | 17966 | goto err_unmap; |
17854 | asc_board_count--; | ||
17855 | return NULL; | ||
17856 | } | 17967 | } |
17857 | #endif /* CONFIG_PROC_FS */ | 17968 | #endif /* CONFIG_PROC_FS */ |
17858 | 17969 | ||
@@ -17978,14 +18089,8 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
17978 | } | 18089 | } |
17979 | } | 18090 | } |
17980 | 18091 | ||
17981 | if (err_code != 0) { | 18092 | if (err_code != 0) |
17982 | #ifdef CONFIG_PROC_FS | 18093 | goto err_free_proc; |
17983 | kfree(boardp->prtbuf); | ||
17984 | #endif /* CONFIG_PROC_FS */ | ||
17985 | scsi_unregister(shost); | ||
17986 | asc_board_count--; | ||
17987 | return NULL; | ||
17988 | } | ||
17989 | 18094 | ||
17990 | /* | 18095 | /* |
17991 | * Save the EEPROM configuration so that it can be displayed | 18096 | * Save the EEPROM configuration so that it can be displayed |
@@ -18067,12 +18172,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18067 | ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n", | 18172 | ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n", |
18068 | boardp->id, | 18173 | boardp->id, |
18069 | asc_dvc_varp->init_state, asc_dvc_varp->err_code); | 18174 | asc_dvc_varp->init_state, asc_dvc_varp->err_code); |
18070 | #ifdef CONFIG_PROC_FS | 18175 | goto err_free_proc; |
18071 | kfree(boardp->prtbuf); | ||
18072 | #endif /* CONFIG_PROC_FS */ | ||
18073 | scsi_unregister(shost); | ||
18074 | asc_board_count--; | ||
18075 | return NULL; | ||
18076 | } | 18176 | } |
18077 | 18177 | ||
18078 | /* | 18178 | /* |
@@ -18276,10 +18376,8 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18276 | 18376 | ||
18277 | /* BIOS start address. */ | 18377 | /* BIOS start address. */ |
18278 | if (ASC_NARROW_BOARD(boardp)) { | 18378 | if (ASC_NARROW_BOARD(boardp)) { |
18279 | shost->base = ((ulong) | 18379 | shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base, |
18280 | AscGetChipBiosAddress(asc_dvc_varp-> | 18380 | asc_dvc_varp->bus_type); |
18281 | iop_base, | ||
18282 | asc_dvc_varp->bus_type)); | ||
18283 | } else { | 18381 | } else { |
18284 | /* | 18382 | /* |
18285 | * Fill-in BIOS board variables. The Wide BIOS saves | 18383 | * Fill-in BIOS board variables. The Wide BIOS saves |
@@ -18337,12 +18435,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18337 | ASC_PRINT3 | 18435 | ASC_PRINT3 |
18338 | ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n", | 18436 | ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n", |
18339 | boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port); | 18437 | boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port); |
18340 | #ifdef CONFIG_PROC_FS | 18438 | goto err_free_proc; |
18341 | kfree(boardp->prtbuf); | ||
18342 | #endif /* CONFIG_PROC_FS */ | ||
18343 | scsi_unregister(shost); | ||
18344 | asc_board_count--; | ||
18345 | return NULL; | ||
18346 | } | 18439 | } |
18347 | 18440 | ||
18348 | /* Register DMA Channel for Narrow boards. */ | 18441 | /* Register DMA Channel for Narrow boards. */ |
@@ -18352,19 +18445,12 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18352 | /* Register DMA channel for ISA bus. */ | 18445 | /* Register DMA channel for ISA bus. */ |
18353 | if (asc_dvc_varp->bus_type & ASC_IS_ISA) { | 18446 | if (asc_dvc_varp->bus_type & ASC_IS_ISA) { |
18354 | shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel; | 18447 | shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel; |
18355 | if ((ret = | 18448 | ret = request_dma(shost->dma_channel, "advansys"); |
18356 | request_dma(shost->dma_channel, "advansys")) != 0) { | 18449 | if (ret) { |
18357 | ASC_PRINT3 | 18450 | ASC_PRINT3 |
18358 | ("advansys_board_found: board %d: request_dma() %d failed %d\n", | 18451 | ("advansys_board_found: board %d: request_dma() %d failed %d\n", |
18359 | boardp->id, shost->dma_channel, ret); | 18452 | boardp->id, shost->dma_channel, ret); |
18360 | release_region(shost->io_port, | 18453 | goto err_free_region; |
18361 | boardp->asc_n_io_port); | ||
18362 | #ifdef CONFIG_PROC_FS | ||
18363 | kfree(boardp->prtbuf); | ||
18364 | #endif /* CONFIG_PROC_FS */ | ||
18365 | scsi_unregister(shost); | ||
18366 | asc_board_count--; | ||
18367 | return NULL; | ||
18368 | } | 18454 | } |
18369 | AscEnableIsaDma(shost->dma_channel); | 18455 | AscEnableIsaDma(shost->dma_channel); |
18370 | } | 18456 | } |
@@ -18391,17 +18477,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18391 | ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n", | 18477 | ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n", |
18392 | boardp->id, shost->irq, ret); | 18478 | boardp->id, shost->irq, ret); |
18393 | } | 18479 | } |
18394 | release_region(shost->io_port, boardp->asc_n_io_port); | 18480 | goto err_free_dma; |
18395 | iounmap(boardp->ioremap_addr); | ||
18396 | if (shost->dma_channel != NO_ISA_DMA) { | ||
18397 | free_dma(shost->dma_channel); | ||
18398 | } | ||
18399 | #ifdef CONFIG_PROC_FS | ||
18400 | kfree(boardp->prtbuf); | ||
18401 | #endif /* CONFIG_PROC_FS */ | ||
18402 | scsi_unregister(shost); | ||
18403 | asc_board_count--; | ||
18404 | return NULL; | ||
18405 | } | 18481 | } |
18406 | 18482 | ||
18407 | /* | 18483 | /* |
@@ -18419,173 +18495,33 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18419 | asc_dvc_varp->init_state, warn_code, err_code); | 18495 | asc_dvc_varp->init_state, warn_code, err_code); |
18420 | } | 18496 | } |
18421 | } else { | 18497 | } else { |
18422 | ADV_CARR_T *carrp; | 18498 | err_code = advansys_wide_init_chip(boardp, adv_dvc_varp); |
18423 | int req_cnt = 0; | ||
18424 | adv_req_t *reqp = NULL; | ||
18425 | int sg_cnt = 0; | ||
18426 | |||
18427 | /* | ||
18428 | * Allocate buffer carrier structures. The total size | ||
18429 | * is about 4 KB, so allocate all at once. | ||
18430 | */ | ||
18431 | carrp = (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC); | ||
18432 | ASC_DBG1(1, "advansys_board_found: carrp 0x%lx\n", (ulong)carrp); | ||
18433 | |||
18434 | if (carrp == NULL) { | ||
18435 | goto kmalloc_error; | ||
18436 | } | ||
18437 | |||
18438 | /* | ||
18439 | * Allocate up to 'max_host_qng' request structures for | ||
18440 | * the Wide board. The total size is about 16 KB, so | ||
18441 | * allocate all at once. If the allocation fails decrement | ||
18442 | * and try again. | ||
18443 | */ | ||
18444 | for (req_cnt = adv_dvc_varp->max_host_qng; | ||
18445 | req_cnt > 0; req_cnt--) { | ||
18446 | |||
18447 | reqp = (adv_req_t *) | ||
18448 | kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC); | ||
18449 | |||
18450 | ASC_DBG3(1, | ||
18451 | "advansys_board_found: reqp 0x%lx, req_cnt %d, bytes %lu\n", | ||
18452 | (ulong)reqp, req_cnt, | ||
18453 | (ulong)sizeof(adv_req_t) * req_cnt); | ||
18454 | |||
18455 | if (reqp != NULL) { | ||
18456 | break; | ||
18457 | } | ||
18458 | } | ||
18459 | if (reqp == NULL) { | ||
18460 | goto kmalloc_error; | ||
18461 | } | ||
18462 | |||
18463 | /* | ||
18464 | * Allocate up to ADV_TOT_SG_BLOCK request structures for | ||
18465 | * the Wide board. Each structure is about 136 bytes. | ||
18466 | */ | ||
18467 | boardp->adv_sgblkp = NULL; | ||
18468 | for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) { | ||
18469 | |||
18470 | sgp = (adv_sgblk_t *) | ||
18471 | kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC); | ||
18472 | |||
18473 | if (sgp == NULL) { | ||
18474 | break; | ||
18475 | } | ||
18476 | |||
18477 | sgp->next_sgblkp = boardp->adv_sgblkp; | ||
18478 | boardp->adv_sgblkp = sgp; | ||
18479 | |||
18480 | } | ||
18481 | ASC_DBG3(1, | ||
18482 | "advansys_board_found: sg_cnt %d * %u = %u bytes\n", | ||
18483 | sg_cnt, sizeof(adv_sgblk_t), | ||
18484 | (unsigned)(sizeof(adv_sgblk_t) * sg_cnt)); | ||
18485 | |||
18486 | /* | ||
18487 | * If no request structures or scatter-gather structures could | ||
18488 | * be allocated, then return an error. Otherwise continue with | ||
18489 | * initialization. | ||
18490 | */ | ||
18491 | kmalloc_error: | ||
18492 | if (carrp == NULL) { | ||
18493 | ASC_PRINT1 | ||
18494 | ("advansys_board_found: board %d error: failed to kmalloc() carrier buffer.\n", | ||
18495 | boardp->id); | ||
18496 | err_code = ADV_ERROR; | ||
18497 | } else if (reqp == NULL) { | ||
18498 | kfree(carrp); | ||
18499 | ASC_PRINT1 | ||
18500 | ("advansys_board_found: board %d error: failed to kmalloc() adv_req_t buffer.\n", | ||
18501 | boardp->id); | ||
18502 | err_code = ADV_ERROR; | ||
18503 | } else if (boardp->adv_sgblkp == NULL) { | ||
18504 | kfree(carrp); | ||
18505 | kfree(reqp); | ||
18506 | ASC_PRINT1 | ||
18507 | ("advansys_board_found: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n", | ||
18508 | boardp->id); | ||
18509 | err_code = ADV_ERROR; | ||
18510 | } else { | ||
18511 | |||
18512 | /* Save carrier buffer pointer. */ | ||
18513 | boardp->orig_carrp = carrp; | ||
18514 | |||
18515 | /* | ||
18516 | * Save original pointer for kfree() in case the | ||
18517 | * driver is built as a module and can be unloaded. | ||
18518 | */ | ||
18519 | boardp->orig_reqp = reqp; | ||
18520 | |||
18521 | adv_dvc_varp->carrier_buf = carrp; | ||
18522 | |||
18523 | /* | ||
18524 | * Point 'adv_reqp' to the request structures and | ||
18525 | * link them together. | ||
18526 | */ | ||
18527 | req_cnt--; | ||
18528 | reqp[req_cnt].next_reqp = NULL; | ||
18529 | for (; req_cnt > 0; req_cnt--) { | ||
18530 | reqp[req_cnt - 1].next_reqp = &reqp[req_cnt]; | ||
18531 | } | ||
18532 | boardp->adv_reqp = &reqp[0]; | ||
18533 | |||
18534 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { | ||
18535 | ASC_DBG(2, | ||
18536 | "advansys_board_found: AdvInitAsc3550Driver()\n"); | ||
18537 | warn_code = AdvInitAsc3550Driver(adv_dvc_varp); | ||
18538 | } else if (adv_dvc_varp->chip_type == | ||
18539 | ADV_CHIP_ASC38C0800) { | ||
18540 | ASC_DBG(2, | ||
18541 | "advansys_board_found: AdvInitAsc38C0800Driver()\n"); | ||
18542 | warn_code = | ||
18543 | AdvInitAsc38C0800Driver(adv_dvc_varp); | ||
18544 | } else { | ||
18545 | ASC_DBG(2, | ||
18546 | "advansys_board_found: AdvInitAsc38C1600Driver()\n"); | ||
18547 | warn_code = | ||
18548 | AdvInitAsc38C1600Driver(adv_dvc_varp); | ||
18549 | } | ||
18550 | err_code = adv_dvc_varp->err_code; | ||
18551 | |||
18552 | if (warn_code || err_code) { | ||
18553 | ASC_PRINT3 | ||
18554 | ("advansys_board_found: board %d error: warn 0x%x, error 0x%x\n", | ||
18555 | boardp->id, warn_code, err_code); | ||
18556 | } | ||
18557 | } | ||
18558 | } | 18499 | } |
18559 | 18500 | ||
18560 | if (err_code != 0) { | 18501 | if (err_code != 0) |
18561 | release_region(shost->io_port, boardp->asc_n_io_port); | 18502 | goto err_free_wide_mem; |
18562 | if (ASC_WIDE_BOARD(boardp)) { | 18503 | |
18563 | iounmap(boardp->ioremap_addr); | ||
18564 | kfree(boardp->orig_carrp); | ||
18565 | boardp->orig_carrp = NULL; | ||
18566 | if (boardp->orig_reqp) { | ||
18567 | kfree(boardp->orig_reqp); | ||
18568 | boardp->orig_reqp = boardp->adv_reqp = NULL; | ||
18569 | } | ||
18570 | while ((sgp = boardp->adv_sgblkp) != NULL) { | ||
18571 | boardp->adv_sgblkp = sgp->next_sgblkp; | ||
18572 | kfree(sgp); | ||
18573 | } | ||
18574 | } | ||
18575 | if (shost->dma_channel != NO_ISA_DMA) { | ||
18576 | free_dma(shost->dma_channel); | ||
18577 | } | ||
18578 | #ifdef CONFIG_PROC_FS | ||
18579 | kfree(boardp->prtbuf); | ||
18580 | #endif /* CONFIG_PROC_FS */ | ||
18581 | free_irq(shost->irq, shost); | ||
18582 | scsi_unregister(shost); | ||
18583 | asc_board_count--; | ||
18584 | return NULL; | ||
18585 | } | ||
18586 | ASC_DBG_PRT_SCSI_HOST(2, shost); | 18504 | ASC_DBG_PRT_SCSI_HOST(2, shost); |
18587 | 18505 | ||
18588 | return shost; | 18506 | return shost; |
18507 | |||
18508 | err_free_wide_mem: | ||
18509 | advansys_wide_free_mem(boardp); | ||
18510 | free_irq(shost->irq, shost); | ||
18511 | err_free_dma: | ||
18512 | if (shost->dma_channel != NO_ISA_DMA) | ||
18513 | free_dma(shost->dma_channel); | ||
18514 | err_free_region: | ||
18515 | release_region(shost->io_port, boardp->asc_n_io_port); | ||
18516 | err_free_proc: | ||
18517 | kfree(boardp->prtbuf); | ||
18518 | err_unmap: | ||
18519 | if (boardp->ioremap_addr) | ||
18520 | iounmap(boardp->ioremap_addr); | ||
18521 | err_shost: | ||
18522 | scsi_unregister(shost); | ||
18523 | asc_board_count--; | ||
18524 | return NULL; | ||
18589 | } | 18525 | } |
18590 | 18526 | ||
18591 | /* | 18527 | /* |
@@ -18901,24 +18837,10 @@ static int advansys_release(struct Scsi_Host *shost) | |||
18901 | } | 18837 | } |
18902 | release_region(shost->io_port, boardp->asc_n_io_port); | 18838 | release_region(shost->io_port, boardp->asc_n_io_port); |
18903 | if (ASC_WIDE_BOARD(boardp)) { | 18839 | if (ASC_WIDE_BOARD(boardp)) { |
18904 | adv_sgblk_t *sgp = NULL; | ||
18905 | |||
18906 | iounmap(boardp->ioremap_addr); | 18840 | iounmap(boardp->ioremap_addr); |
18907 | kfree(boardp->orig_carrp); | 18841 | advansys_wide_free_mem(boardp); |
18908 | boardp->orig_carrp = NULL; | ||
18909 | if (boardp->orig_reqp) { | ||
18910 | kfree(boardp->orig_reqp); | ||
18911 | boardp->orig_reqp = boardp->adv_reqp = NULL; | ||
18912 | } | ||
18913 | while ((sgp = boardp->adv_sgblkp) != NULL) { | ||
18914 | boardp->adv_sgblkp = sgp->next_sgblkp; | ||
18915 | kfree(sgp); | ||
18916 | } | ||
18917 | } | 18842 | } |
18918 | #ifdef CONFIG_PROC_FS | ||
18919 | ASC_ASSERT(boardp->prtbuf != NULL); | ||
18920 | kfree(boardp->prtbuf); | 18843 | kfree(boardp->prtbuf); |
18921 | #endif /* CONFIG_PROC_FS */ | ||
18922 | scsi_unregister(shost); | 18844 | scsi_unregister(shost); |
18923 | ASC_DBG(1, "advansys_release: end\n"); | 18845 | ASC_DBG(1, "advansys_release: end\n"); |
18924 | return 0; | 18846 | return 0; |