[PATCH 4/24] advansys: Make advansys_board_found a little more readable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 - Put all the error cleanup at the end of the function and goto the
   appropriate label
 - Split advansys_init_wide_chip out of advansys_board_found
 - Use GFP_KERNEL, not GFP_ATOMIC, when allocating memory during
   initialisation
 - Make share_irq be 0 or IRQD_SHARED, not FALSE or TRUE

Signed-off-by: Matthew Wilcox <matthew@xxxxxx>
---
 drivers/scsi/advansys.c |  404 +++++++++++++++++++----------------------------
 1 files changed, 166 insertions(+), 238 deletions(-)

diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index a0bad3b..87e7730 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -3845,7 +3845,7 @@ typedef struct asc_board {
 	 */
 	void __iomem *ioremap_addr;	/* I/O Memory remap address. */
 	ushort ioport;		/* I/O Port address. */
-	ADV_CARR_T *orig_carrp;	/* ADV_CARR_T memory block. */
+	ADV_CARR_T *carrp;	/* ADV_CARR_T memory block. */
 	adv_req_t *orig_reqp;	/* adv_req_t memory block. */
 	adv_req_t *adv_reqp;	/* Request structures. */
 	adv_sgblk_t *adv_sgblkp;	/* Scatter-gather structures. */
@@ -17755,6 +17755,111 @@ static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq)
 	}
 }
 
+static int __devinit
+advansys_wide_init_chip(asc_board_t *boardp, ADV_DVC_VAR *adv_dvc_varp)
+{
+	int req_cnt = 0;
+	adv_req_t *reqp = NULL;
+	int sg_cnt = 0;
+	adv_sgblk_t *sgp;
+	int warn_code, err_code;
+
+	/*
+	 * Allocate buffer carrier structures. The total size
+	 * is about 4 KB, so allocate all at once.
+	 */
+	boardp->carrp = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL);
+	ASC_DBG1(1, "advansys_wide_init_chip: carrp 0x%p\n", boardp->carrp);
+
+	if (!boardp->carrp)
+		goto kmalloc_failed;
+
+	/*
+	 * Allocate up to 'max_host_qng' request structures for the Wide
+	 * board. The total size is about 16 KB, so allocate all at once.
+	 * If the allocation fails decrement and try again.
+	 */
+	for (req_cnt = adv_dvc_varp->max_host_qng; req_cnt > 0; req_cnt--) {
+		reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL);
+
+		ASC_DBG3(1, "advansys_wide_init_chip: reqp 0x%p, req_cnt %d, "
+			 "bytes %lu\n", reqp, req_cnt,
+			 (ulong)sizeof(adv_req_t) * req_cnt);
+
+		if (reqp)
+			break;
+	}
+
+	if (!reqp)
+		goto kmalloc_failed;
+
+	boardp->orig_reqp = reqp;
+
+	/*
+	 * Allocate up to ADV_TOT_SG_BLOCK request structures for
+	 * the Wide board. Each structure is about 136 bytes.
+	 */
+	boardp->adv_sgblkp = NULL;
+	for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
+		sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL);
+
+		if (!sgp)
+			break;
+
+		sgp->next_sgblkp = boardp->adv_sgblkp;
+		boardp->adv_sgblkp = sgp;
+
+	}
+
+	ASC_DBG3(1, "advansys_wide_init_chip: sg_cnt %d * %u = %u bytes\n",
+		 sg_cnt, sizeof(adv_sgblk_t),
+		 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
+
+	if (!boardp->adv_sgblkp)
+		goto kmalloc_failed;
+
+	adv_dvc_varp->carrier_buf = boardp->carrp;
+
+	/*
+	 * Point 'adv_reqp' to the request structures and
+	 * link them together.
+	 */
+	req_cnt--;
+	reqp[req_cnt].next_reqp = NULL;
+	for (; req_cnt > 0; req_cnt--) {
+		reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
+	}
+	boardp->adv_reqp = &reqp[0];
+
+	if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
+		ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc3550Driver()\n");
+		warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
+	} else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) {
+		ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C0800Driver()"
+			   "\n");
+		warn_code = AdvInitAsc38C0800Driver(adv_dvc_varp);
+	} else {
+		ASC_DBG(2, "advansys_wide_init_chip: AdvInitAsc38C1600Driver()"
+			   "\n");
+		warn_code = AdvInitAsc38C1600Driver(adv_dvc_varp);
+	}
+	err_code = adv_dvc_varp->err_code;
+
+	if (warn_code || err_code) {
+		ASC_PRINT3("advansys_wide_init_chip: board %d error: warn 0x%x,"
+			   " error 0x%x\n", boardp->id, warn_code, err_code);
+	}
+
+	goto exit;
+
+ kmalloc_failed:
+	ASC_PRINT1("advansys_wide_init_chip: board %d error: kmalloc() "
+		   "failed\n", boardp->id);
+	err_code = ADV_ERROR;
+ exit:
+	return err_code;
+}
+
 static struct Scsi_Host *__devinit
 advansys_board_found(int iop, struct device *dev, int bus_type)
 {
@@ -17763,8 +17868,8 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 	asc_board_t *boardp;
 	ASC_DVC_VAR *asc_dvc_varp = NULL;
 	ADV_DVC_VAR *adv_dvc_varp = NULL;
-	adv_sgblk_t *sgp = NULL;
-	int share_irq = FALSE;
+	adv_sgblk_t *sgp;
+	int share_irq;
 	int iolen = 0;
 	ADV_PADDR pci_memory_address;
 	int warn_code, err_code;
@@ -17866,9 +17971,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 			ASC_PRINT3
 			    ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n",
 			     boardp->id, pci_memory_address, iolen);
-			scsi_unregister(shost);
-			asc_board_count--;
-			return NULL;
+			goto err_shost;
 		}
 		ASC_DBG1(1,
 			 "advansys_board_found: ioremap_addr: 0x%lx\n",
@@ -17898,13 +18001,11 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 	 * Allocate buffer for printing information from
 	 * /proc/scsi/advansys/[0...].
 	 */
-	if ((boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) {
-		ASC_PRINT3
-		    ("advansys_board_found: board %d: kmalloc(%d, %d) returned NULL\n",
-		     boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC);
-		scsi_unregister(shost);
-		asc_board_count--;
-		return NULL;
+	boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL);
+	if (!boardp->prtbuf) {
+		ASC_PRINT2("advansys_board_found: board %d: kmalloc(%d) "
+			   "returned NULL\n", boardp->id, ASC_PRTBUF_SIZE);
+		goto err_unmap;
 	}
 #endif /* CONFIG_PROC_FS */
 
@@ -17918,15 +18019,15 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 #ifdef CONFIG_ISA
 		case ASC_IS_ISA:
 			shost->unchecked_isa_dma = TRUE;
-			share_irq = FALSE;
+			share_irq = 0;
 			break;
 		case ASC_IS_VL:
 			shost->unchecked_isa_dma = FALSE;
-			share_irq = FALSE;
+			share_irq = 0;
 			break;
 		case ASC_IS_EISA:
 			shost->unchecked_isa_dma = FALSE;
-			share_irq = TRUE;
+			share_irq = IRQF_SHARED;
 			break;
 #endif /* CONFIG_ISA */
 #ifdef CONFIG_PCI
@@ -17937,7 +18038,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 					 PCI_SLOT(pdev->devfn),
 					 PCI_FUNC(pdev->devfn));
 			shost->unchecked_isa_dma = FALSE;
-			share_irq = TRUE;
+			share_irq = IRQF_SHARED;
 			break;
 #endif /* CONFIG_PCI */
 		default:
@@ -17945,7 +18046,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 			    ("advansys_board_found: board %d: unknown adapter type: %d\n",
 			     boardp->id, asc_dvc_varp->bus_type);
 			shost->unchecked_isa_dma = TRUE;
-			share_irq = FALSE;
+			share_irq = 0;
 			break;
 		}
 	} else {
@@ -17961,7 +18062,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 				 PCI_SLOT(pdev->devfn),
 				 PCI_FUNC(pdev->devfn));
 		shost->unchecked_isa_dma = FALSE;
-		share_irq = TRUE;
+		share_irq = IRQF_SHARED;
 #endif /* CONFIG_PCI */
 	}
 
@@ -18030,14 +18131,8 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 		}
 	}
 
-	if (err_code != 0) {
-#ifdef CONFIG_PROC_FS
-		kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-		scsi_unregister(shost);
-		asc_board_count--;
-		return NULL;
-	}
+	if (err_code != 0)
+		goto err_free_proc;
 
 	/*
 	 * Save the EEPROM configuration so that it can be displayed
@@ -18119,12 +18214,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 			    ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n",
 			     boardp->id,
 			     asc_dvc_varp->init_state, asc_dvc_varp->err_code);
-#ifdef CONFIG_PROC_FS
-			kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-			scsi_unregister(shost);
-			asc_board_count--;
-			return NULL;
+			goto err_free_proc;
 		}
 
 		/*
@@ -18328,10 +18418,8 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 
 	/* BIOS start address. */
 	if (ASC_NARROW_BOARD(boardp)) {
-		shost->base = ((ulong)
-			     AscGetChipBiosAddress(asc_dvc_varp->
-						   iop_base,
-						   asc_dvc_varp->bus_type));
+		shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base,
+						    asc_dvc_varp->bus_type);
 	} else {
 		/*
 		 * Fill-in BIOS board variables. The Wide BIOS saves
@@ -18389,12 +18477,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 		ASC_PRINT3
 		    ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n",
 		     boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port);
-#ifdef CONFIG_PROC_FS
-		kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-		scsi_unregister(shost);
-		asc_board_count--;
-		return NULL;
+		goto err_free_proc;
 	}
 
 	/* Register DMA Channel for Narrow boards. */
@@ -18404,19 +18487,12 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 		/* Register DMA channel for ISA bus. */
 		if (asc_dvc_varp->bus_type & ASC_IS_ISA) {
 			shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel;
-			if ((ret =
-			     request_dma(shost->dma_channel, "advansys")) != 0) {
+			ret = request_dma(shost->dma_channel, "advansys");
+			if (ret) {
 				ASC_PRINT3
 				    ("advansys_board_found: board %d: request_dma() %d failed %d\n",
 				     boardp->id, shost->dma_channel, ret);
-				release_region(shost->io_port,
-					       boardp->asc_n_io_port);
-#ifdef CONFIG_PROC_FS
-				kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-				scsi_unregister(shost);
-				asc_board_count--;
-				return NULL;
+				goto err_free_region;
 			}
 			AscEnableIsaDma(shost->dma_channel);
 		}
@@ -18434,16 +18510,13 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 	 * If IRQF_DISABLED is not set, then interrupts are enabled
 	 * before the driver interrupt function is called.
 	 */
-	if (((ret = request_irq(shost->irq, advansys_interrupt,
-				IRQF_DISABLED | (share_irq ==
-						 TRUE ?
-						 IRQF_SHARED :
-						 0), "advansys", boardp)) != 0)
-	    &&
-	    ((ret =
-	      request_irq(shost->irq, advansys_interrupt,
-			  (share_irq == TRUE ? IRQF_SHARED : 0),
-			  "advansys", boardp)) != 0)) {
+	ret = request_irq(shost->irq, advansys_interrupt,
+			  share_irq | IRQF_DISABLED, "advansys", boardp);
+	if (ret)
+		ret = request_irq(shost->irq, advansys_interrupt,
+				  share_irq, "advansys", boardp);
+
+	if (ret) {
 		if (ret == -EBUSY) {
 			ASC_PRINT2
 			    ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n",
@@ -18457,17 +18530,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 			    ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n",
 			     boardp->id, shost->irq, ret);
 		}
-		release_region(shost->io_port, boardp->asc_n_io_port);
-		iounmap(boardp->ioremap_addr);
-		if (shost->dma_channel != NO_ISA_DMA) {
-			free_dma(shost->dma_channel);
-		}
-#ifdef CONFIG_PROC_FS
-		kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-		scsi_unregister(shost);
-		asc_board_count--;
-		return NULL;
+		goto err_free_dma;
 	}
 
 	/*
@@ -18485,173 +18548,38 @@ advansys_board_found(int iop, struct device *dev, int bus_type)
 			     asc_dvc_varp->init_state, warn_code, err_code);
 		}
 	} else {
-		ADV_CARR_T *carrp;
-		int req_cnt = 0;
-		adv_req_t *reqp = NULL;
-		int sg_cnt = 0;
-
-		/*
-		 * Allocate buffer carrier structures. The total size
-		 * is about 4 KB, so allocate all at once.
-		 */
-		carrp = (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC);
-		ASC_DBG1(1, "advansys_board_found: carrp 0x%lx\n", (ulong)carrp);
-
-		if (carrp == NULL) {
-			goto kmalloc_error;
-		}
-
-		/*
-		 * Allocate up to 'max_host_qng' request structures for
-		 * the Wide board. The total size is about 16 KB, so
-		 * allocate all at once. If the allocation fails decrement
-		 * and try again.
-		 */
-		for (req_cnt = adv_dvc_varp->max_host_qng;
-		     req_cnt > 0; req_cnt--) {
-
-			reqp = (adv_req_t *)
-			    kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC);
-
-			ASC_DBG3(1,
-				 "advansys_board_found: reqp 0x%lx, req_cnt %d, bytes %lu\n",
-				 (ulong)reqp, req_cnt,
-				 (ulong)sizeof(adv_req_t) * req_cnt);
-
-			if (reqp != NULL) {
-				break;
-			}
-		}
-		if (reqp == NULL) {
-			goto kmalloc_error;
-		}
-
-		/*
-		 * Allocate up to ADV_TOT_SG_BLOCK request structures for
-		 * the Wide board. Each structure is about 136 bytes.
-		 */
-		boardp->adv_sgblkp = NULL;
-		for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) {
-
-			sgp = (adv_sgblk_t *)
-			    kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC);
-
-			if (sgp == NULL) {
-				break;
-			}
-
-			sgp->next_sgblkp = boardp->adv_sgblkp;
-			boardp->adv_sgblkp = sgp;
-
-		}
-		ASC_DBG3(1,
-			 "advansys_board_found: sg_cnt %d * %u = %u bytes\n",
-			 sg_cnt, sizeof(adv_sgblk_t),
-			 (unsigned)(sizeof(adv_sgblk_t) * sg_cnt));
-
-		/*
-		 * If no request structures or scatter-gather structures could
-		 * be allocated, then return an error. Otherwise continue with
-		 * initialization.
-		 */
- kmalloc_error:
-		if (carrp == NULL) {
-			ASC_PRINT1
-			    ("advansys_board_found: board %d error: failed to kmalloc() carrier buffer.\n",
-			     boardp->id);
-			err_code = ADV_ERROR;
-		} else if (reqp == NULL) {
-			kfree(carrp);
-			ASC_PRINT1
-			    ("advansys_board_found: board %d error: failed to kmalloc() adv_req_t buffer.\n",
-			     boardp->id);
-			err_code = ADV_ERROR;
-		} else if (boardp->adv_sgblkp == NULL) {
-			kfree(carrp);
-			kfree(reqp);
-			ASC_PRINT1
-			    ("advansys_board_found: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n",
-			     boardp->id);
-			err_code = ADV_ERROR;
-		} else {
-
-			/* Save carrier buffer pointer. */
-			boardp->orig_carrp = carrp;
-
-			/*
-			 * Save original pointer for kfree() in case the
-			 * driver is built as a module and can be unloaded.
-			 */
-			boardp->orig_reqp = reqp;
-
-			adv_dvc_varp->carrier_buf = carrp;
-
-			/*
-			 * Point 'adv_reqp' to the request structures and
-			 * link them together.
-			 */
-			req_cnt--;
-			reqp[req_cnt].next_reqp = NULL;
-			for (; req_cnt > 0; req_cnt--) {
-				reqp[req_cnt - 1].next_reqp = &reqp[req_cnt];
-			}
-			boardp->adv_reqp = &reqp[0];
-
-			if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) {
-				ASC_DBG(2,
-					"advansys_board_found: AdvInitAsc3550Driver()\n");
-				warn_code = AdvInitAsc3550Driver(adv_dvc_varp);
-			} else if (adv_dvc_varp->chip_type ==
-				   ADV_CHIP_ASC38C0800) {
-				ASC_DBG(2,
-					"advansys_board_found: AdvInitAsc38C0800Driver()\n");
-				warn_code =
-				    AdvInitAsc38C0800Driver(adv_dvc_varp);
-			} else {
-				ASC_DBG(2,
-					"advansys_board_found: AdvInitAsc38C1600Driver()\n");
-				warn_code =
-				    AdvInitAsc38C1600Driver(adv_dvc_varp);
-			}
-			err_code = adv_dvc_varp->err_code;
-
-			if (warn_code || err_code) {
-				ASC_PRINT3
-				    ("advansys_board_found: board %d error: warn 0x%x, error 0x%x\n",
-				     boardp->id, warn_code, err_code);
-			}
-		}
+		err_code = advansys_wide_init_chip(boardp, adv_dvc_varp);
 	}
 
-	if (err_code != 0) {
-		release_region(shost->io_port, boardp->asc_n_io_port);
-		if (ASC_WIDE_BOARD(boardp)) {
-			iounmap(boardp->ioremap_addr);
-			kfree(boardp->orig_carrp);
-			boardp->orig_carrp = NULL;
-			if (boardp->orig_reqp) {
-				kfree(boardp->orig_reqp);
-				boardp->orig_reqp = boardp->adv_reqp = NULL;
-			}
-			while ((sgp = boardp->adv_sgblkp) != NULL) {
-				boardp->adv_sgblkp = sgp->next_sgblkp;
-				kfree(sgp);
-			}
-		}
-		if (shost->dma_channel != NO_ISA_DMA) {
-			free_dma(shost->dma_channel);
-		}
-#ifdef CONFIG_PROC_FS
-		kfree(boardp->prtbuf);
-#endif /* CONFIG_PROC_FS */
-		free_irq(shost->irq, boardp);
-		scsi_unregister(shost);
-		asc_board_count--;
-		return NULL;
-	}
+	if (err_code != 0)
+		goto err_free_wide_mem;
+
 	ASC_DBG_PRT_SCSI_HOST(2, shost);
 
 	return shost;
+
+ err_free_wide_mem:
+	kfree(boardp->carrp);
+	kfree(boardp->orig_reqp);
+	while ((sgp = boardp->adv_sgblkp) != NULL) {
+		boardp->adv_sgblkp = sgp->next_sgblkp;
+		kfree(sgp);
+	}
+	free_irq(shost->irq, boardp);
+ err_free_dma:
+	if (shost->dma_channel != NO_ISA_DMA)
+		free_dma(shost->dma_channel);
+ err_free_region:
+	release_region(shost->io_port, boardp->asc_n_io_port);
+ err_free_proc:
+	kfree(boardp->prtbuf);
+ err_unmap:
+	if (boardp->ioremap_addr)
+		iounmap(boardp->ioremap_addr);
+ err_shost:
+	scsi_unregister(shost);
+	asc_board_count--;
+	return NULL;
 }
 
 /*
@@ -18970,8 +18898,8 @@ static int advansys_release(struct Scsi_Host *shost)
 		adv_sgblk_t *sgp = NULL;
 
 		iounmap(boardp->ioremap_addr);
-		kfree(boardp->orig_carrp);
-		boardp->orig_carrp = NULL;
+		kfree(boardp->carrp);
+		boardp->carrp = NULL;
 		if (boardp->orig_reqp) {
 			kfree(boardp->orig_reqp);
 			boardp->orig_reqp = boardp->adv_reqp = NULL;
-- 
1.4.4.4

-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux