diff options
| author | Joshua M. Clulow <jmc@joyent.com> | 2016-02-25 09:36:34 +0000 | 
|---|---|---|
| committer | Joshua M. Clulow <jmc@joyent.com> | 2016-07-06 16:25:11 +0000 | 
| commit | d8b1d9739721de55f9ee63fc356056982e6316ee (patch) | |
| tree | defe40aac74063c22b36750161c46f9abc1419d6 /usr/src | |
| parent | 5d8ee4be0214467fc42e9fd57125043790742b16 (diff) | |
| download | illumos-joyent-d8b1d9739721de55f9ee63fc356056982e6316ee.tar.gz | |
XXX cleanup round 1
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/uts/common/io/cpqary3/cpqary3.c | 4 | ||||
| -rw-r--r-- | usr/src/uts/common/io/cpqary3/cpqary3.h | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/io/cpqary3/cpqary3_ciss.h | 57 | ||||
| -rw-r--r-- | usr/src/uts/common/io/cpqary3/cpqary3_isr.c | 30 | ||||
| -rw-r--r-- | usr/src/uts/common/io/cpqary3/cpqary3_talk2ctlr.c | 456 | ||||
| -rw-r--r-- | usr/src/uts/common/io/cpqary3/cpqary3_transport.c | 20 | ||||
| -rw-r--r-- | usr/src/uts/common/io/cpqary3/cpqary3_util.c | 5 | 
7 files changed, 272 insertions, 302 deletions
| diff --git a/usr/src/uts/common/io/cpqary3/cpqary3.c b/usr/src/uts/common/io/cpqary3/cpqary3.c index 622f0dcf68..ff4aada92c 100644 --- a/usr/src/uts/common/io/cpqary3/cpqary3.c +++ b/usr/src/uts/common/io/cpqary3/cpqary3.c @@ -879,7 +879,7 @@ cpqary3_update_ctlrdetails(cpqary3_t *cpqary3p, uint32_t *cleanstatus)  	 */  	retvalue = ddi_regs_map_setup(cpqary3p->dip,  	    mem_bar0, /* INDEX_PCI_BASE0, */ -	    (caddr_t *)&cpqary3p->idr, (offset_t)I2O_IBDB_SET, map_len, +	    (caddr_t *)&cpqary3p->idr, (offset_t)I2O_INBOUND_DOORBELL, map_len,  	    &cpqary3_dev_attributes, &cpqary3p->idr_handle);  	if (retvalue != DDI_SUCCESS) { @@ -926,7 +926,7 @@ cpqary3_update_ctlrdetails(cpqary3_t *cpqary3p, uint32_t *cleanstatus)  	/* LOCKUP CODE */  	retvalue = ddi_regs_map_setup(cpqary3p->dip,  	    mem_bar0, /* INDEX_PCI_BASE0, */ -	    (caddr_t *)&cpqary3p->spr0, (offset_t)I2O_CTLR_INIT, map_len, +	    (caddr_t *)&cpqary3p->spr0, (offset_t)I2O_SCRATCHPAD, map_len,  	    &cpqary3_dev_attributes, &cpqary3p->spr0_handle);  	if (retvalue != DDI_SUCCESS) { diff --git a/usr/src/uts/common/io/cpqary3/cpqary3.h b/usr/src/uts/common/io/cpqary3/cpqary3.h index 0c56d3b356..f7c229eb69 100644 --- a/usr/src/uts/common/io/cpqary3/cpqary3.h +++ b/usr/src/uts/common/io/cpqary3/cpqary3.h @@ -467,7 +467,7 @@ int32_t cpqary3_ioctl_bmic_pass(uintptr_t, cpqary3_t *, int);  int32_t cpqary3_ioctl_scsi_pass(uintptr_t, cpqary3_t *, int);  uint8_t cpqary3_probe4targets(cpqary3_t *);  void cpqary3_cmdlist_release(cpqary3_cmdpvt_t *, uint8_t); -int32_t cpqary3_submit(cpqary3_t *, uint32_t); +int cpqary3_submit(cpqary3_t *, uint32_t);  void cpqary3_free_phyctgs_mem(cpqary3_phyctg_t *, uint8_t);  caddr_t cpqary3_alloc_phyctgs_mem(cpqary3_t *, size_t, uint32_t *,      cpqary3_phyctg_t *); diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h b/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h index 88b772391c..46f6c5e006 100644 --- a/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h +++ b/usr/src/uts/common/io/cpqary3/cpqary3_ciss.h @@ -68,33 +68,56 @@ extern "C" {  #define	CFG_MEM1BAR		0x14  /* I2O Space Register Offsets */ -#define	I2O_IBDB_SET		0x20 -#define	I2O_IBDB_CLEAR		0x70 +#define	I2O_INBOUND_DOORBELL	0x20  #define	I2O_INT_STATUS		0x30  #define	I2O_INT_MASK		0x34  #define	I2O_IBPOST_Q		0x40  #define	I2O_OBPOST_Q		0x44  #define	I2O_OBDB_STATUS		0x9C  #define	I2O_OBDB_CLEAR		0xA0 -#define	I2O_CTLR_INIT		0xB0	/* not available in CISS specs */ +#define	I2O_SCRATCHPAD		0xB0 -/* Configuration Table */ -#define	CFGTBL_CHANGE_REQ	0x00000001l -#define	CFGTBL_ACC_CMDS		0x00000001l +/* + * The Scratchpad Register (I2O_SCRATCHPAD) is not mentioned in the CISS + * specification.  It serves at least two known functions: + *	- Signalling controller readiness + *	- Exposing a debugging code when the controller firmware locks up + */ +#define	CISS_SCRATCHPAD_INITIALISED		0xffff0000 -/* Transport Method */ -#define	CFGTBL_XPORT_SIMPLE		0x00000002l -#define	CFGTBL_XPORT_PERFORMANT		0x00000004l -#define	CFGTBL_XPORT_MEMQ		0x00000008l +/* + * Outbound Doorbell Register Values. + * + * These are read from the Outbound Doorbell Set/Status Register + * (I2O_OBDB_STATUS), but cleared by writing to the Clear + * Register (I2O_OBDB_CLEAR). + */ +#define	CISS_ODR_BIT_INTERRUPT			(1UL << 0) +#define	CISS_ODR_BIT_LOCKUP			(1UL << 1) -#define	CPQARY3_SIMPLE		CFGTBL_XPORT_SIMPLE -#define	CPQARY3_PERFORMANT	CFGTBL_XPORT_PERFORMANT +/* + * Inbound Doorbell Register Values. + * + * These are written to and read from the Inbound Doorbell Register + * (I2O_INBOUND_DOORBELL). + */ +#define	CISS_IDR_BIT_CFGTBL_CHANGE		(1UL << 0) -/* not being used currently */ -#define	CFGTBL_BusType_Ultra2	0x00000001l -#define	CFGTBL_BusType_Ultra3	0x00000002l -#define	CFGTBL_BusType_Fibre1G	0x00000100l -#define	CFGTBL_BusType_Fibre2G	0x00000200l +/* + * Transport Methods. + * + * These bit positions are used in the Configuration Table to detect controller + * support for a particular method, via "TransportSupport"; to request that the + * controller enable a particular method, via "HostWrite.TransportRequest"; and + * to detect whether the controller has acknowledged the request and enabled + * the desired method, via "TransportActive". + * + * See: "9.1 Configuration Table" in the CISS Specification. + */ +#define	CISS_CFGTBL_READY_FOR_COMMANDS		(1UL << 0) +#define	CISS_CFGTBL_XPORT_SIMPLE		(1UL << 1) +#define	CISS_CFGTBL_XPORT_PERFORMANT		(1UL << 2) +#define	CISS_CFGTBL_XPORT_MEMQ			(1UL << 4)  /* for hard reset of the controller */  #define	CISS_POWER_OFF		0x03	/* Self Defined */ diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_isr.c b/usr/src/uts/common/io/cpqary3/cpqary3_isr.c index 5a8b3f46f4..d62e93159d 100644 --- a/usr/src/uts/common/io/cpqary3/cpqary3_isr.c +++ b/usr/src/uts/common/io/cpqary3/cpqary3_isr.c @@ -33,18 +33,29 @@  uint_t  cpqary3_hw_isr(caddr_t per_ctlr)  { -	uint8_t			need_swintr; -	cpqary3_t		*cpqary3p; +	boolean_t		need_swintr; +	cpqary3_t		*cpqary3p = (cpqary3_t *)per_ctlr;  	cpqary3_drvr_replyq_t	*replyq_ptr; -	volatile CfgTable_t	*ctp; +	volatile CfgTable_t	*ctp = cpqary3p->ct;  	uint32_t		spr0;  	uint32_t		doorbell_status;  	uint32_t		tag; -	cpqary3p = (void *)per_ctlr; -	ctp = (CfgTable_t *)cpqary3p->ct;  	replyq_ptr = (cpqary3_drvr_replyq_t *)cpqary3p->drvr_replyq; + +	/* +	 * Check the Interrupt Status Register to see if the Outbound +	 * Post List FIFO is not empty. +	 */ +	if (cpqary3p->check_ctlr_intr(cpqary3p) != CPQARY3_SUCCESS) { +		/* +		 * The Outbound Post List FIFO is not empty, so we must +		 * service this interrupt. +		 */ +		goto service; +	} +  	if (CPQARY3_FAILURE == cpqary3p->check_ctlr_intr(cpqary3p)) {  		if (cpqary3p->heartbeat ==  		    DDI_GET32(cpqary3p, &ctp->HeartBeat)) { @@ -73,6 +84,8 @@ cpqary3_hw_isr(caddr_t per_ctlr)  		return (DDI_INTR_UNCLAIMED);  	} +service: +  	/* PERF */  	/* @@ -133,16 +146,17 @@ cpqary3_hw_isr(caddr_t per_ctlr)  	mutex_enter(&cpqary3p->hw_mutex);  	if (cpqary3p->swintr_flag == CPQARY3_TRUE) { -		need_swintr = CPQARY3_FALSE; +		need_swintr = B_FALSE;  	} else { -		need_swintr = CPQARY3_TRUE; +		need_swintr = B_TRUE;  		cpqary3p->swintr_flag = CPQARY3_TRUE;  	}  	mutex_exit(&cpqary3p->hw_mutex); -	if (CPQARY3_TRUE == need_swintr) +	if (need_swintr) {  		ddi_trigger_softintr(cpqary3p->cpqary3_softintr_id); +	}  	return (DDI_INTR_CLAIMED);  } diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_talk2ctlr.c b/usr/src/uts/common/io/cpqary3/cpqary3_talk2ctlr.c index f0cca1d38b..2382ac22c5 100644 --- a/usr/src/uts/common/io/cpqary3/cpqary3_talk2ctlr.c +++ b/usr/src/uts/common/io/cpqary3/cpqary3_talk2ctlr.c @@ -11,6 +11,7 @@  /*   * Copyright (C) 2013 Hewlett-Packard Development Company, L.P. + * Copyright 2016 Joyent, Inc.   */  /* @@ -284,53 +285,32 @@ cpqary3_poll_retrieve(cpqary3_t *cpqary3p, uint32_t poll_tag)   * Calls	: 	None   * Return Values: 	None   */ -int32_t +int  cpqary3_submit(cpqary3_t *cpqary3p, uint32_t cmd_phyaddr)  { -	uint32_t		phys_addr = 0; -	uint8_t			retval  = 0; +	ASSERT(cpqary3p != NULL); +	ASSERT(MUTEX_HELD(&cpqary3p->hw_mutex));  	/* -	 * Write the Physical Address of the command-to-be-submitted -	 * into the Controller's Inbound Post Q. +	 * If a controller lockup has been detected, reject new command +	 * submissions.  	 */ - -	ASSERT(cpqary3p != NULL); - -#ifdef AMD64_DEBUG -	{ -	char		debug_char; -	uint32_t	tmp_cmd_phyaddr; - -	tmp_cmd_phyaddr = (uint32_t)(cmd_phyaddr & 0XFFFFFFFF); - -	cmn_err(CE_WARN, "CPQary3: cmd_phyaddr = %lX\n tmp_cmd_phyaddr = %lX", -	    cmd_phyaddr, tmp_cmd_phyaddr); - -	debug_enter(&debug_char); -	ddi_put32(cpqary3p->ipq_handle, (uint32_t *)cpqary3p->ipq, cmd_phyaddr); -	} -#endif - - -	/* CONTROLLER_LOCKUP */  	if (cpqary3p->controller_lockup == CPQARY3_TRUE) { -		retval = EIO; -		return (retval); +		return (EIO);  	} -	/* CONTROLLER_LOCKUP */ +	/* +	 * Write the Physical Address of the command-to-be-submitted +	 * into the Controller's Inbound Post Q. +	 */  	if (!(cpqary3p->bddef->bd_flags & SA_BD_SAS)) { -		ddi_put32(cpqary3p->ipq_handle, -		    (uint32_t *)cpqary3p->ipq, cmd_phyaddr); +		ddi_put32(cpqary3p->ipq_handle, cpqary3p->ipq, cmd_phyaddr);  	} else {  		/* The driver always uses the 0th block fetch count always */ -		phys_addr = cmd_phyaddr | 0 | 0x1; -		ddi_put32(cpqary3p->ipq_handle, -		    (uint32_t *)cpqary3p->ipq, phys_addr); -	} +		uint32_t phys_addr = cmd_phyaddr | 0 | 0x1; -	/* PERF */ +		ddi_put32(cpqary3p->ipq_handle, cpqary3p->ipq, phys_addr); +	}  	/*  	 * Command submission can NEVER FAIL since the number of commands that @@ -338,11 +318,7 @@ cpqary3_submit(cpqary3_t *cpqary3p, uint32_t cmd_phyaddr)  	 * allocation is for 225 commands ONLY. Thus, at any given time the  	 * maximum number of commands in the controller is 225.  	 */ - -	/* CONTROLLER_LOCKUP */ -	return (retval); -	/* CONTROLLER_LOCKUP */ - +	return (0);  } @@ -358,29 +334,24 @@ cpqary3_submit(cpqary3_t *cpqary3p, uint32_t cmd_phyaddr)  void  cpqary3_intr_onoff(cpqary3_t *cpqary3p, uint8_t flag)  { -	uint32_t	intr = 0; -	uint32_t	intr_mask = 0; -  	/* -	 * Enable or disable the interrupt based on the flag -	 * Read the Interrupt Mask Register first and then update it -	 * accordingly +	 * Read the Interrupt Mask Register.  	 */ +	uint32_t imr = ddi_get32(cpqary3p->imr_handle, cpqary3p->imr); -	ASSERT(cpqary3p != NULL); - -	intr = ddi_get32(cpqary3p->imr_handle, (uint32_t *)cpqary3p->imr); -	intr_mask = cpqary3p->bddef->bd_intrmask; - +	/* +	 * Enable or disable interrupts from the controller based on the flag. +	 */  	if (flag == CPQARY3_INTR_ENABLE) { -		ddi_put32(cpqary3p->imr_handle, -		    (uint32_t *)cpqary3p->imr, intr & ~(intr_mask)); +		imr &= ~cpqary3p->bddef->bd_intrmask;  	} else { -		ddi_put32(cpqary3p->imr_handle, -		    (uint32_t *)cpqary3p->imr, (intr | intr_mask)); +		VERIFY(flag == CPQARY3_INTR_DISABLE); + +		imr |= cpqary3p->bddef->bd_intrmask;  	} -} +	ddi_put32(cpqary3p->imr_handle, cpqary3p->imr, imr); +}  /*   * Function	: 	cpqary3_lockup_intr_onoff @@ -395,27 +366,139 @@ cpqary3_intr_onoff(cpqary3_t *cpqary3p, uint8_t flag)  void  cpqary3_lockup_intr_onoff(cpqary3_t *cpqary3p, uint8_t flag)  { -	uint32_t	intr = 0; -	uint32_t	intr_lockup_mask = 0; +	/* +	 * Read the Interrupt Mask Register. +	 */ +	uint32_t imr = ddi_get32(cpqary3p->imr_handle, cpqary3p->imr);  	/* -	 * Enable or disable the interrupt based on the flag -	 * Read the Interrupt Mask Register first and then update it -	 * accordingly +	 * Enable or disable firmware lockup interrupts from the controller +	 * based on the flag.  	 */ +	if (flag == CPQARY3_LOCKUP_INTR_ENABLE) { +		imr &= ~cpqary3p->bddef->bd_lockup_intrmask; +	} else { +		VERIFY(flag == CPQARY3_LOCKUP_INTR_DISABLE); -	ASSERT(cpqary3p != NULL); +		imr |= cpqary3p->bddef->bd_lockup_intrmask; +	} -	intr = ddi_get32(cpqary3p->imr_handle, (uint32_t *)cpqary3p->imr); -	intr_lockup_mask = cpqary3p->bddef->bd_lockup_intrmask; +	ddi_put32(cpqary3p->imr_handle, cpqary3p->imr, imr); +} -	if (flag == CPQARY3_INTR_ENABLE) { -		ddi_put32(cpqary3p->imr_handle, -		    (uint32_t *)cpqary3p->imr, intr & ~(intr_lockup_mask)); -	} else { -		ddi_put32(cpqary3p->imr_handle, -		    (uint32_t *)cpqary3p->imr, (intr | intr_lockup_mask)); +/* + * Signal to the controller that we have updated the Configuration Table by + * writing to the Inbound Doorbell Register.  The controller will, after some + * number of seconds, acknowledge this by clearing the bit. + * + * If successful, return CPQARY3_SUCCESS.  If the controller takes too long to + * acknowledge, return CPQARY3_FAILURE. + */ +static int +cpqary3_cfgtbl_flush(cpqary3_t *cpqary3p) +{ +	/* +	 * Read the current value of the Inbound Doorbell Register. +	 */ +	uint32_t idr = ddi_get32(cpqary3p->idr_handle, cpqary3p->idr); + +	/* +	 * Signal the Configuration Table change to the controller. +	 */ +	idr |= CISS_IDR_BIT_CFGTBL_CHANGE; +	ddi_put32(cpqary3p->idr_handle, cpqary3p->idr, idr); + +	/* +	 * Wait for the controller to acknowledge the change. +	 */ +	for (unsigned i = 0; i < CISS_INIT_TIME; i++) { +		idr = ddi_get32(cpqary3p->idr_handle, cpqary3p->idr); + +		if ((idr & CISS_IDR_BIT_CFGTBL_CHANGE) == 0) { +			return (CPQARY3_SUCCESS); +		} + +		/* +		 * Wait for one second before trying again. +		 */ +		delay(drv_usectohz(1000000)); +	} + +	dev_err(cpqary3p->dip, CE_WARN, "time out expired before controller " +	    "configuration completed"); +	return (CPQARY3_FAILURE); +} + +static int +cpqary3_cfgtbl_transport_has_support(cpqary3_t *cpqary3p, int xport) +{ +	VERIFY(xport == CISS_CFGTBL_XPORT_SIMPLE || +	    xport == CISS_CFGTBL_XPORT_PERFORMANT); + +	/* +	 * Read the current value of the TransportSupport field in the +	 * Configuration Table. +	 */ +	uint32_t xport_active = ddi_get32(cpqary3p->ct_handle, +	    &cpqary3p->ct->TransportSupport); + +	/* +	 * Check that the desired transport method is supported by the +	 * controller: +	 */ +	if ((xport_active & xport) == 0) { +		dev_err(cpqary3p->dip, CE_WARN, "controller does not support " +		    "method \"%s\"", xport == CISS_CFGTBL_XPORT_SIMPLE ? +		    "simple" : "performant"); +		return (CPQARY3_FAILURE);  	} + +	return (CPQARY3_SUCCESS); +} + +static void +cpqary3_cfgtbl_transport_set(cpqary3_t *cpqary3p, int xport) +{ +	VERIFY(xport == CISS_CFGTBL_XPORT_SIMPLE || +	    xport == CISS_CFGTBL_XPORT_PERFORMANT); + +	ddi_put32(cpqary3p->ct_handle, +	    &cpqary3p->ct->HostWrite.TransportRequest, xport); +} + +static int +cpqary3_cfgtbl_transport_confirm(cpqary3_t *cpqary3p, int xport) +{ +	VERIFY(xport == CISS_CFGTBL_XPORT_SIMPLE || +	    xport == CISS_CFGTBL_XPORT_PERFORMANT); + +	/* +	 * Read the current value of the TransportActive field in the +	 * Configuration Table. +	 */ +	uint32_t xport_active = ddi_get32(cpqary3p->ct_handle, +	    &cpqary3p->ct->TransportActive); + +	/* +	 * Check that the desired transport method is now active: +	 */ +	if ((xport_active & xport) == 0) { +		dev_err(cpqary3p->dip, CE_WARN, "failed to enable transport " +		    "method \"%s\"", xport == CISS_CFGTBL_XPORT_SIMPLE ? +		    "simple" : "performant"); +		return (CPQARY3_FAILURE); +	} + +	/* +	 * Ensure that the controller is now ready to accept commands. +	 */ +	if ((xport_active & CISS_CFGTBL_READY_FOR_COMMANDS) == 0) { +		dev_err(cpqary3p->dip, CE_WARN, "controller not ready to " +		    "accept commands"); +		return (CPQARY3_FAILURE); +	} + +	return (CPQARY3_SUCCESS);  }  /* @@ -433,9 +516,8 @@ cpqary3_lockup_intr_onoff(cpqary3_t *cpqary3p, uint8_t flag)  uint8_t  cpqary3_init_ctlr(cpqary3_t *cpqary3p)  { -	uint8_t				cntr;  	uint8_t				signature[4] = { 'C', 'I', 'S', 'S' }; -	volatile CfgTable_t		*ctp; +	CfgTable_t			*ctp;  	volatile CfgTrans_Perf_t	*perf_cfg;  	cpqary3_phyctg_t		*cpqary3_phyctgp;  	uint32_t			phy_addr; @@ -469,22 +551,19 @@ cpqary3_init_ctlr(cpqary3_t *cpqary3p)  	DTRACE_PROBE1(ctlr_init_start, CfgTable_t *, ctp);  	/* -	 * Validate the signature - should be "CISS" -	 * Use of cntr in the for loop does not suggest a counter - it just -	 * saves declaration of another variable. +	 * The configuration table contains an ASCII signature ("CISS") which +	 * should be checked as we initialise the controller. +	 * See: "9.1 Configuration Table" in CISS Specification.  	 */ - -	for (cntr = 0; cntr < 4; cntr++) { -		if (DDI_GET8(cpqary3p, &ctp->Signature[cntr]) != -		    signature[cntr]) { -			cmn_err(CE_WARN, "CPQary3 : Controller NOT ready"); -			cmn_err(CE_WARN, "CPQary3 : _cpqary3_init_ctlr : " -			    "Signature not stamped"); +	for (unsigned i = 0; i < 4; i++) { +		if (ddi_get8(cpqary3p->ct_handle, &ctp->Signature[i]) != +		    signature[i]) { +			dev_err(cpqary3p->dip, CE_WARN, "invalid signature " +			    "detected");  			return (CPQARY3_FAILURE);  		}  	} -  	if (!(cpqary3p->bddef->bd_flags & SA_BD_SAS)) {  		CmdsOutMax = DDI_GET32(cpqary3p, &ctp->CmdsOutMax); @@ -520,91 +599,30 @@ cpqary3_init_ctlr(cpqary3_t *cpqary3p)  		/* PERF */ -		/* -		 * Check for support of SIMPLE Transport Method -		 */ -		if (!(DDI_GET32(cpqary3p, &ctp->TransportSupport) & -		    CFGTBL_XPORT_SIMPLE)) { -			cmn_err(CE_WARN, "CPQary3 : Controller " -			    "NOT YET INITIALIZED"); -			cmn_err(CE_CONT, "CPQary3 : For Hot Plug Operations, " -			    "try again later \n"); +		if (cpqary3_cfgtbl_transport_has_support(cpqary3p, +		    CISS_CFGTBL_XPORT_SIMPLE) != CPQARY3_SUCCESS) {  			return (CPQARY3_FAILURE);  		}  		/* -		 * Configuration Table Initialization -		 * Set bit 0 of InBound Door Bell Reg to inform the controller -		 * about the changes related to the Configuration table +		 * Set the Transport Method and flush the changes to the +		 * Configuration Table.  		 */ -		DTRACE_PROBE(cfgtable_init_start); - -		DDI_PUT32(cpqary3p, &ctp->HostWrite.TransportRequest, -		    CFGTBL_XPORT_SIMPLE); -		ddi_put32(cpqary3p->idr_handle, (uint32_t *)cpqary3p->idr, -		    ddi_get32(cpqary3p->idr_handle, (uint32_t *)cpqary3p->idr) | -		    CFGTBL_CHANGE_REQ); - -		/* -		 * Check whether the controller is  ready -		 */ - -		cntr = 0; -		while (ddi_get32(cpqary3p->idr_handle, -		    (uint32_t *)cpqary3p->idr) & CFGTBL_ACC_CMDS) { -			drv_usecwait(1000000); /* Wait for 1 Sec. */ -			cntr++; - -			/* -			 * Wait for a maximum of 90 seconds. No f/w should take -			 * more than 90 secs to initialize. If the controller -			 * is not ready even after 90 secs, it suggests that -			 * something is wrong -			 * (wrt the controller, what else) !!! -			 */ - -			if (cntr > CISS_INIT_TIME) /* 1.30 Mins */ { -				cmn_err(CE_CONT, "CPQary3 : Controller " -				    "Initialization Failed \n"); -				return (CPQARY3_FAILURE); -			} -		} - -		DTRACE_PROBE(cfgtable_init_done); - -		/* -		 * Check whether controller accepts the requested method of -		 * transport -		 */ -		if (!(DDI_GET32(cpqary3p, &ctp->TransportActive) & -		    CFGTBL_XPORT_SIMPLE)) { -			cmn_err(CE_CONT, "CPQary3 : Failed to Initialize " -			    "Controller \n"); -			cmn_err(CE_CONT, "CPQary3 : For Hot Plug Operations, " -			    "try again later\n"); +		cpqary3_cfgtbl_transport_set(cpqary3p, +		    CISS_CFGTBL_XPORT_SIMPLE); +		if (cpqary3_cfgtbl_flush(cpqary3p) != CPQARY3_SUCCESS) {  			return (CPQARY3_FAILURE);  		} -		DTRACE_PROBE(ctlr_init_simple); - -		/* -		 * Check if Controller is ready to accept Commands -		 */ - -		if (!(DDI_GET32(cpqary3p, &ctp->TransportActive) & -		    CFGTBL_ACC_CMDS)) { -			cmn_err(CE_CONT, "CPQary3: Controller NOT ready to " -			    "accept Commands \n"); +		if (cpqary3_cfgtbl_transport_confirm(cpqary3p, +		    CISS_CFGTBL_XPORT_SIMPLE) != CPQARY3_SUCCESS) {  			return (CPQARY3_FAILURE);  		} -		DTRACE_PROBE(ctlr_init_ready); -  		/*  		 * Check if the maximum number of oustanding commands for the  		 * initialized controller is something greater than Zero.  		 */ -  		CmdsOutMax = DDI_GET32(cpqary3p, &ctp->CmdsOutMax);  		if (CmdsOutMax == 0) { @@ -619,7 +637,6 @@ cpqary3_init_ctlr(cpqary3_t *cpqary3p)  		/*  		 * Zero the Upper 32 Address in the Controller  		 */ -  		DDI_PUT32(cpqary3p, &ctp->HostWrite.Upper32Addr, 0x00000000);  		cpqary3p->heartbeat = DDI_GET32(cpqary3p, &ctp->HeartBeat); @@ -632,20 +649,11 @@ cpqary3_init_ctlr(cpqary3_t *cpqary3p)  		    (cpqary3p->host_support | 0x4));  		cpqary3p->host_support =  		    DDI_GET32(cpqary3p, &ctp->HostDrvrSupport); - -		cpqary3p->lockup_logged = CPQARY3_FALSE;  	} else {  	/* PERF */ -		/* -		 * Check for support of PERF Transport Method -		 */ -		if (!(DDI_GET32(cpqary3p, &ctp->TransportSupport) -		    & CFGTBL_XPORT_PERFORMANT)) { -			cmn_err(CE_WARN, "CPQary3 : Controller " -			    "NOT YET INITIALIZED"); -			cmn_err(CE_CONT, "CPQary3 : For Hot Plug Operations, " -			    "try again later \n"); +		if (cpqary3_cfgtbl_transport_has_support(cpqary3p, +		    CISS_CFGTBL_XPORT_PERFORMANT) != CPQARY3_SUCCESS) {  			return (CPQARY3_FAILURE);  		} @@ -731,63 +739,19 @@ cpqary3_init_ctlr(cpqary3_t *cpqary3p)  		DDI_PUT32_CP(cpqary3p, &perf_cfg->BlockFetchCnt[0],  		    BlockFetchCnt[0]); -		DDI_PUT32(cpqary3p, &ctp->HostWrite.TransportRequest, -		    CFGTBL_XPORT_PERFORMANT); -		ddi_put32(cpqary3p->idr_handle, (uint32_t *)cpqary3p->idr, -		    ddi_get32(cpqary3p->idr_handle, (uint32_t *)cpqary3p->idr) | -		    CFGTBL_CHANGE_REQ); - -		/* -		 * Check whether the controller is  ready -		 */ - -		cntr = 0; -		while (ddi_get32(cpqary3p->idr_handle, -		    (uint32_t *)cpqary3p->idr) & CFGTBL_ACC_CMDS) { -			drv_usecwait(1000000); /* Wait for 1 Sec. */ -			cntr++; - - -			/* -			 * Wait for a maximum of 90 seconds. No f/w should take -			 * more than 90 secs to initialize. If the controller -			 * is not ready even after 90 secs, it suggests that -			 * something is wrong -			 * (wrt the controller, what else) !!! -			 */ - -			if (cntr > CISS_INIT_TIME) /* 1.30 Mins */ { -				cmn_err(CE_CONT, "CPQary3 : Controller " -				    "Initialization Failed \n"); -				return (CPQARY3_FAILURE); -			} -		}  		/* -		 * Check whether controller accepts the requested method of -		 * transport +		 * Set the Transport Method and flush the changes to the +		 * Configuration Table.  		 */ - -		if (!(DDI_GET32(cpqary3p, &ctp->TransportActive) & -		    CFGTBL_XPORT_PERFORMANT)) { -			cmn_err(CE_NOTE, "CPQary3 : Failed to Initialize " -			    "Controller"); -			cmn_err(CE_CONT, "CPQary3 : For Hot Plug Operations, " -			    "try again later\n"); -			DTRACE_PROBE1(ctlr_init_perf_fail, CfgTable_t *, ctp); +		cpqary3_cfgtbl_transport_set(cpqary3p, +		    CISS_CFGTBL_XPORT_PERFORMANT); +		if (cpqary3_cfgtbl_flush(cpqary3p) != CPQARY3_SUCCESS) {  			return (CPQARY3_FAILURE);  		} -		DTRACE_PROBE(ctlr_init_simple); - -		/* -		 * Check if Controller is ready to accept Commands -		 */ - -		if (!(DDI_GET32(cpqary3p, &ctp->TransportActive) & -		    CFGTBL_ACC_CMDS)) { -			cmn_err(CE_NOTE, "CPQary3: Controller NOT ready to " -			    "accept Commands"); +		if (cpqary3_cfgtbl_transport_confirm(cpqary3p, +		    CISS_CFGTBL_XPORT_PERFORMANT) != CPQARY3_SUCCESS) {  			return (CPQARY3_FAILURE);  		} @@ -795,7 +759,6 @@ cpqary3_init_ctlr(cpqary3_t *cpqary3p)  		 * Check if the maximum number of oustanding commands for the  		 * initialized controller is something greater than Zero.  		 */ -  		CmdsOutMax = DDI_GET32(cpqary3p, &ctp->MaxPerfModeCmdsOutMax);  		if (CmdsOutMax == 0)  			CmdsOutMax = DDI_GET32(cpqary3p, &ctp->CmdsOutMax); @@ -873,7 +836,6 @@ cpqary3_init_ctlr(cpqary3_t *cpqary3p)  		}  		cpqary3p->host_support =  		    DDI_GET32(cpqary3p, &ctp->HostDrvrSupport); -		cpqary3p->lockup_logged = CPQARY3_FALSE;  	}  	return (CPQARY3_SUCCESS); @@ -890,53 +852,25 @@ cpqary3_init_ctlr(cpqary3_t *cpqary3p)  uint8_t  cpqary3_check_ctlr_init(cpqary3_t *cpqary3p)  { -	int8_t				retvalue; -	uint16_t			i; -	uint32_t			*ctlr_init; -	ddi_acc_handle_t		ctlr_init_handle; -	extern ddi_device_acc_attr_t	cpqary3_dev_attributes; - -	RETURN_FAILURE_IF_NULL(cpqary3p); -  	/* -	 * Set up the mapping for a Register at offset 0xB0 from I2O Bar -	 * The value 0xB0 taken from the CONFIGM utility. -	 * It should read 0xffff0000 if the controller is initialized. -	 * if not yet initialized, read it every second for 300 secs. -	 * If not set even after 300 secs, return FAILURE. -	 * If set, free the mapping and continue +	 * Read from the Scratchpad Register until the expected ready +	 * signature is detected.  This behaviour is not described in +	 * the CISS specification. +	 * +	 * If the device is not ready immediate, sleep for a second and +	 * try again.  If the device has not become ready in 300 seconds, +	 * give up.  	 */ -	retvalue = ddi_regs_map_setup(cpqary3p->dip, INDEX_PCI_BASE0, -	    (caddr_t *)&ctlr_init, (offset_t)I2O_CTLR_INIT, 4, -	    &cpqary3_dev_attributes, &ctlr_init_handle); +	for (unsigned i = 0; i < 300; i++) { +		uint32_t spr = ddi_get32(cpqary3p->spr0_handle, +		    cpqary3p->spr0); -	if (retvalue != DDI_SUCCESS) { -		if (DDI_REGS_ACC_CONFLICT == retvalue) -			cmn_err(CE_WARN, -			    "CPQary3 : HBA Init Register Mapping Conflict"); -		cmn_err(CE_WARN, -		    "CPQary3 : HBA Init Regsiter Mapping Failed"); -		return (CPQARY3_FAILURE); -	} - -	for (i = 0; i < 300; i++) {	/* loop for 300 seconds */ -		if (CISS_CTLR_INIT == ddi_get32(ctlr_init_handle, ctlr_init)) { -			DTRACE_PROBE(ctlr_init_check_ready); -			ddi_regs_map_free(&ctlr_init_handle); -			break; -		} else { -			DTRACE_PROBE(ctlr_init_check_notready); -			delay(drv_usectohz(1000000)); +		if (spr == CISS_SCRATCHPAD_INITIALISED) { +			return (CPQARY3_SUCCESS);  		}  	} -	if (i >= 300) {	/* HBA not initialized even after 300 seconds !!! */ -		ddi_regs_map_free(&ctlr_init_handle); -		cmn_err(CE_WARN, "CPQary3 : %s NOT initialized !!! HBA may not " -		    "function properly. Please replace the hardware or check " -		    "the connections", cpqary3p->hba_name); -		return (CPQARY3_FAILURE); -	} - -	return (CPQARY3_SUCCESS); +	dev_err(cpqary3p->dip, CE_WARN, "time out waiting for controller " +	    "to become ready"); +	return (CPQARY3_FAILURE);  } diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_transport.c b/usr/src/uts/common/io/cpqary3/cpqary3_transport.c index 1880bba69b..939a5dfa31 100644 --- a/usr/src/uts/common/io/cpqary3/cpqary3_transport.c +++ b/usr/src/uts/common/io/cpqary3/cpqary3_transport.c @@ -628,31 +628,25 @@ cpqary3_transport(struct scsi_address *sa, struct scsi_pkt *scsi_pktp)  	memp->complete = cpqary3_oscmd_complete;  	/* PERF */ -	switch (cpqary3_build_cmdlist(memp, SA2TGT(sa))) { -	case CPQARY3_SUCCESS : +	if (cpqary3_build_cmdlist(memp, SA2TGT(sa)) == CPQARY3_SUCCESS) {  		if (scsi_pktp->pkt_flags & FLAG_NOINTR) {  			return (cpqary3_handle_flag_nointr(memp, scsi_pktp));  		}  		cpqary3_pktp->cmd_start_time = ddi_get_lbolt(); +  		mutex_enter(&ctlr->hw_mutex); -		/* CONTROLLER_LOCKUP */ -		if (EIO == cpqary3_submit(ctlr, memp->cmdlist_phyaddr)) { +		if (cpqary3_submit(ctlr, memp->cmdlist_phyaddr) != 0) {  			mutex_exit(&ctlr->hw_mutex);  			cpqary3_cmdlist_release(memp, CPQARY3_HOLD_SW_MUTEX);  			return (TRAN_FATAL_ERROR);  		} -		/* CONTROLLER_LOCKUP */  		mutex_exit(&ctlr->hw_mutex); -		break; -	case CPQARY3_FAILURE : -		cpqary3_cmdlist_release(memp, CPQARY3_HOLD_SW_MUTEX); -		return (TRAN_FATAL_ERROR); -	default: /* Never occurs */ -		cmn_err(CE_NOTE, "CPQary3 : Transport : Unexpected Error"); -		return (TRAN_FATAL_ERROR); + +		return (TRAN_ACCEPT);  	} -	return (TRAN_ACCEPT); +	cpqary3_cmdlist_release(memp, CPQARY3_HOLD_SW_MUTEX); +	return (TRAN_FATAL_ERROR);  }  /* diff --git a/usr/src/uts/common/io/cpqary3/cpqary3_util.c b/usr/src/uts/common/io/cpqary3/cpqary3_util.c index 5ba61be8d4..b4a017d5ce 100644 --- a/usr/src/uts/common/io/cpqary3/cpqary3_util.c +++ b/usr/src/uts/common/io/cpqary3/cpqary3_util.c @@ -83,6 +83,11 @@ cpqary3_read_conf_file(dev_info_t *dip, cpqary3_t *cpqary3p)  	}  } +void +cpqary3_lockup_check(cpqary3_t *cpq) +{ +} +  /*   * Function	: 	cpqary3_tick_hdlr   * Description	: 	This routine is called once in 60 seconds to detect any | 
