Home | History | Annotate | Download | only in io
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  *
     25  * The "bscbus" driver provides access to the LOMlite2 virtual registers,
     26  * so that its clients (children) need not be concerned with the details
     27  * of the access mechanism, which in this case is implemented via a
     28  * packet-based protocol over a Xbus (similar to ebus) parallel link to the
     29  * H8 host interface registers.
     30  *
     31  * On the other hand, this driver doesn't generally know what the virtual
     32  * registers signify - only the clients need this information.
     33  */
     34 
     35 
     36 #include <sys/note.h>
     37 #include <sys/types.h>
     38 #include <sys/conf.h>
     39 #include <sys/debug.h>
     40 #include <sys/errno.h>
     41 #include <sys/file.h>
     42 
     43 #if defined(__sparc)
     44 #include <sys/intr.h>
     45 #include <sys/membar.h>
     46 #endif
     47 
     48 #include <sys/kmem.h>
     49 #include <sys/modctl.h>
     50 #include <sys/note.h>
     51 #include <sys/open.h>
     52 #include <sys/poll.h>
     53 #include <sys/spl.h>
     54 #include <sys/stat.h>
     55 #include <sys/strlog.h>
     56 #include <sys/atomic.h>
     57 
     58 #include <sys/ddi.h>
     59 #include <sys/sunddi.h>
     60 #include <sys/sunndi.h>
     61 
     62 #include <sys/bscbus.h>
     63 
     64 #if	defined(NDI_ACC_HDL_V2)
     65 
     66 /*
     67  * Compiling for Solaris 10+ with access handle enhancements
     68  */
     69 #define	HANDLE_TYPE		ndi_acc_handle_t
     70 #define	HANDLE_ADDR(hdlp)	(hdlp->ah_addr)
     71 #define	HANDLE_FAULT(hdlp)	(hdlp->ah_fault)
     72 #define	HANDLE_MAPLEN(hdlp)	(hdlp->ah_len)
     73 #define	HANDLE_PRIVATE(hdlp)	(hdlp->ah_bus_private)
     74 
     75 #else
     76 
     77 /*
     78  * Compatibility definitions for backport to Solaris 8/9
     79  */
     80 #define	HANDLE_TYPE		ddi_acc_impl_t
     81 #define	HANDLE_ADDR(hdlp)	(hdlp->ahi_common.ah_addr)
     82 #define	HANDLE_FAULT(hdlp)	(hdlp->ahi_fault)
     83 #define	HANDLE_MAPLEN(hdlp)	(hdlp->ahi_common.ah_len)
     84 #define	HANDLE_PRIVATE(hdlp)	(hdlp->ahi_common.ah_bus_private)
     85 
     86 #define	ddi_driver_major(dip)	ddi_name_to_major(ddi_binding_name(dip))
     87 
     88 #endif	/* NDI_ACC_HDL_V2 */
     89 
     90 
     91 /*
     92  * Local definitions
     93  */
     94 #define	MYNAME			"bscbus"
     95 #define	NOMAJOR			(~(major_t)0)
     96 #define	DUMMY_VALUE		(~(int8_t)0)
     97 
     98 #define	BSCBUS_INST_TO_MINOR(i)	(i)
     99 #define	BSCBUS_MINOR_TO_INST(m)	(m)
    100 
    101 #define	BSCBUS_MAX_CHANNELS	(4)
    102 
    103 #define	BSCBUS_DUMMY_ADDRESS	((caddr_t)0x0CADD1ED)
    104 #define	ADDR_TO_OFFSET(a, hdlp)	((caddr_t)(a) - HANDLE_ADDR(hdlp))
    105 #define	ADDR_TO_VREG(a)		((caddr_t)(a) - BSCBUS_DUMMY_ADDRESS)
    106 #define	VREG_TO_ADDR(v)		(BSCBUS_DUMMY_ADDRESS + (v))
    107 
    108 #ifdef DEBUG
    109 #define	BSCBUS_LOGSTATUS
    110 #endif /* DEBUG */
    111 
    112 #ifdef BSCBUS_LOGSTATUS
    113 /*
    114  * BSC command logging routines.
    115  * Record the data passing to and from the BSC
    116  */
    117 
    118 typedef enum {
    119 	BSC_CMD_BUSY = 1,		/* bsc reports busy	*/
    120 	BSC_CMD_CLEARING = 2,		/* clearing bsc busy	*/
    121 	BSC_CMD_CLEARED = 3,		/* cleared bsc busy	*/
    122 	BSC_CMD_SENDING = 4,		/* sending next byte	*/
    123 	BSC_CMD_SENT = 5,		/* sending last byte	*/
    124 	BSC_CMD_PENDING = 6,		/* got sent byte ack	*/
    125 	BSC_CMD_REPLY = 7,		/* got reply byte	*/
    126 	BSC_CMD_COMPLETE = 8,		/* command complete	*/
    127 	BSC_CMD_ERROR_SEQ = 9,		/* error status		*/
    128 	BSC_CMD_ERROR_STATUS = 10,	/* error status		*/
    129 	BSC_CMD_ERROR_OFLOW = 11,	/* error status		*/
    130 	BSC_CMD_ERROR_TOUT = 12,	/* error status		*/
    131 
    132 	BSC_CMD_PROCESS = 13,		/* async intr		*/
    133 	BSC_CMD_V1INTR = 14,		/* v1 intr		*/
    134 	BSC_CMD_V1INTRUNCL = 15,	/* v1 intr unclaim	*/
    135 	BSC_CMD_DOGPAT = 17		/* watchdog pat		*/
    136 } bsc_cmd_stamp_t;
    137 
    138 typedef struct {
    139 	hrtime_t	bcl_now;
    140 	int		bcl_seq;
    141 	bsc_cmd_stamp_t	bcl_cat;
    142 	uint8_t		bcl_chno;
    143 	uint8_t		bcl_cmdstate;
    144 	uint8_t		bcl_status;
    145 	uint8_t		bcl_data;
    146 } bsc_cmd_log_t;
    147 
    148 uint32_t	bscbus_cmd_log_size = 1024;
    149 
    150 uint32_t	bscbus_cmd_log_flags = 0xffffffff;
    151 
    152 #endif /* BSCBUS_LOGSTATUS */
    153 
    154 /*
    155  * The following definitions are taken from the Hardware Manual for
    156  * the Hitachi H8S/2148 in conjunction with the hardware specification
    157  * for the Stiletto blade.
    158  *
    159  * Each instance of the host interface has 3 registers on the H8:
    160  * IDRn  - Input Data Register	- write-only for Solaris.
    161  *				  writes to this can be done via two
    162  *				  addresses - control and data.
    163  *				  The H8 can determine which address was
    164  *				  written by examining the C/D bit in
    165  *				  the status register.
    166  * ODRn  - Output Data Register - read-only for Solaris.
    167  *				  A read has the side effect of acknowledging
    168  *				  interrupts.
    169  * STRn  - Status Register	- read-only for Solaris.
    170  *
    171  *
    172  *
    173  * In terms of host access to this the Input and Output data registers are
    174  * mapped at the same address.
    175  */
    176 #define	H8_IDRD	0
    177 #define	H8_IDRC	1
    178 #define	H8_ODR	0
    179 #define	H8_STR	1
    180 
    181 #define	H8_STR_OBF		0x01	/* data available in ODR */
    182 #define	H8_STR_IBF		0x02	/* data for H8 in IDR */
    183 #define	H8_STR_IDRC		0x08	/* last write to IDR was to IDRC */
    184 					/* 0=data, 1=command */
    185 #define	H8_STR_BUSY		0x04	/* H8 busy processing command */
    186 #define	H8_STR_TOKENPROTOCOL	0x80	/* token-passing protocol */
    187 
    188 /*
    189  * Packet format ...
    190  */
    191 #define	BSCBUS_MASK		0xc0	/* Byte-type bits		*/
    192 #define	BSCBUS_PARAM		0x00	/* Parameter byte: 0b0xxxxxxx	*/
    193 #define	BSCBUS_LAST		0x80	/* Last byte of packet		*/
    194 #define	BSCBUS_CMD		0x80	/* Command byte:   0b10###XWV	*/
    195 #define	BSCBUS_STATUS		0xc0	/* Status  byte:   0b11###AEV	*/
    196 
    197 #define	BSCBUS_SEQ		0x38	/* Sequence number bits		*/
    198 #define	BSCBUS_SEQ_LSB		0x08	/* Sequence number LSB		*/
    199 #define	BSCBUS_CMD_XADDR	0x04	/* Extended (2-byte) addressing	*/
    200 #define	BSCBUS_CMD_WRITE	0x02	/* Write command		*/
    201 #define	BSCBUS_CMD_WMSB		0x01	/* Set MSB on Write		*/
    202 #define	BSCBUS_CMD_READ		0x01	/* Read command			*/
    203 #define	BSCBUS_CMD_NOP		0x00	/* NOP command			*/
    204 
    205 #define	BSCBUS_STATUS_ASYNC	0x04	/* Asynchronous event pending	*/
    206 #define	BSCBUS_STATUS_ERR	0x02	/* Error in command processing	*/
    207 #define	BSCBUS_STATUS_MSB	0x01	/* MSB of Value read		*/
    208 
    209 #define	BSCBUS_VREG_LO(x)	((x) & ((1 << 7) - 1))
    210 #define	BSCBUS_VREG_HI(x)	((x) >> 7)
    211 
    212 #define	BSCBUS_BUFSIZE		8
    213 
    214 #define	BSCBUS_CHANNEL_TO_OFFSET(chno)	((chno) * 2)	/* Register offset */
    215 
    216 /*
    217  * Time periods, in nanoseconds
    218  *
    219  * Note that LOMBUS_ONE_SEC and some other time
    220  * periods are defined in <sys/lombus.h>
    221  */
    222 #define	BSCBUS_CMD_POLL			(LOMBUS_ONE_SEC)
    223 #define	BSCBUS_CMD_POLLNOINTS		(LOMBUS_ONE_SEC/20)
    224 #define	BSCBUS_HWRESET_POLL		(LOMBUS_ONE_SEC/20)
    225 #define	BSCBUS_HWRESET_TIMEOUT		(LOMBUS_ONE_SEC*2)
    226 
    227 #define	BSCBUS_DOG_PAT_POLL_LIMIT	(1000)
    228 #define	BSCBUS_DOG_PAT_POLL		(1)
    229 #define	BSCBUS_PAT_RETRY_LIMIT	5
    230 
    231 /*
    232  * Local datatypes
    233  */
    234 enum bscbus_cmdstate {
    235 	BSCBUS_CMDSTATE_IDLE,		/* No transaction in progress */
    236 	BSCBUS_CMDSTATE_BUSY,		/* Setting up command */
    237 	BSCBUS_CMDSTATE_CLEARING,	/* Clearing firmware busy status */
    238 	BSCBUS_CMDSTATE_SENDING,	/* Waiting to send data to f/w */
    239 	BSCBUS_CMDSTATE_PENDING,	/* Waiting for ack from f/w */
    240 	BSCBUS_CMDSTATE_WAITING,	/* Waiting for status from f/w */
    241 	BSCBUS_CMDSTATE_READY,		/* Status received/command done */
    242 	BSCBUS_CMDSTATE_ERROR		/* Command failed with error */
    243 };
    244 
    245 struct bscbus_channel_state {
    246 	/* Changes to these are protected by the instance ch_mutex mutex */
    247 	struct bscbus_state	*ssp;
    248 	uint8_t			*ch_regs;
    249 	ddi_acc_handle_t	ch_handle;  /* per channel access handle */
    250 	unsigned int		chno;
    251 	unsigned int		map_count; /* Number of mappings to channel */
    252 	boolean_t		map_dog;   /* channel is mapped for watchdog */
    253 
    254 	/*
    255 	 * Flag to indicate that we've incurred a hardware fault on
    256 	 * accesses to the H8; once this is set, we fake all further
    257 	 * accesses in order not to provoke additional bus errors.
    258 	 */
    259 	boolean_t		xio_fault;
    260 
    261 	/*
    262 	 * Data protected by the dog_mutex: the watchdog-patting
    263 	 * protocol data (since the dog can be patted from a high-level
    264 	 * cyclic), and the interrupt-enabled flag.
    265 	 */
    266 	kmutex_t		dog_mutex[1];
    267 	unsigned int		pat_retry_count;
    268 	unsigned int		pat_fail_count;
    269 
    270 	/*
    271 	 * Serial protocol state data, protected by lo_mutex
    272 	 * (which is initialised using <lo_iblk>)
    273 	 */
    274 	kmutex_t		lo_mutex[1];
    275 	ddi_iblock_cookie_t	lo_iblk;
    276 	kcondvar_t		lo_cv[1];
    277 	int			unclaimed_count;
    278 
    279 	volatile enum bscbus_cmdstate cmdstate;
    280 	clock_t			deadline;
    281 	clock_t			poll_hz;
    282 	boolean_t		interrupt_failed;
    283 	uint8_t 		cmdbuf[BSCBUS_BUFSIZE];
    284 	uint8_t			*cmdp;	/* Points to last tx'd in cmdbuf */
    285 	uint8_t			reply[BSCBUS_BUFSIZE];
    286 	uint8_t			async;
    287 	uint8_t			index;
    288 	uint8_t			result;
    289 	uint8_t			sequence;
    290 	uint32_t		error;
    291 };
    292 
    293 #define	BSCBUS_TX_PENDING(csp)		((csp)->cmdp > (csp)->cmdbuf)
    294 
    295 /*
    296  * This driver's soft-state structure
    297  */
    298 
    299 struct bscbus_state {
    300 	/*
    301 	 * Configuration data, set during attach
    302 	 */
    303 	dev_info_t		*dip;
    304 	major_t			majornum;
    305 	int			instance;
    306 
    307 	ddi_acc_handle_t	h8_handle;
    308 	uint8_t			*h8_regs;
    309 
    310 	/*
    311 	 * Parameters derived from .conf properties
    312 	 */
    313 	uint32_t		debug;
    314 
    315 	/*
    316 	 * Flag to indicate that we are using per channel
    317 	 * mapping of the register sets and interrupts.
    318 	 * reg set 0 is chan 0
    319 	 * reg set 1 is chan 1 ...
    320 	 *
    321 	 * Interrupts are specified in that order but later
    322 	 * channels may not have interrupts.
    323 	 */
    324 	boolean_t		per_channel_regs;
    325 
    326 	/*
    327 	 * channel state data, protected by ch_mutex
    328 	 * channel claim/release requests are protected by this mutex.
    329 	 */
    330 	kmutex_t		ch_mutex[1];
    331 	struct bscbus_channel_state	channel[BSCBUS_MAX_CHANNELS];
    332 
    333 #ifdef BSCBUS_LOGSTATUS
    334 	/*
    335 	 * Command logging buffer for recording transactions with the
    336 	 * BSC. This is useful for debugging failed transactions and other
    337 	 * such funnies.
    338 	 */
    339 	bsc_cmd_log_t		*cmd_log;
    340 	uint32_t		cmd_log_idx;
    341 	uint32_t		cmd_log_size;
    342 	uint32_t		cmd_log_flags;
    343 #endif /* BSCBUS_LOGSTATUS */
    344 };
    345 
    346 /*
    347  * The auxiliary structure attached to each child
    348  * (the child's parent-private-data points to this).
    349  */
    350 struct bscbus_child_info {
    351 	lombus_regspec_t *rsp;
    352 	int nregs;
    353 };
    354 
    355 #ifdef BSCBUS_LOGSTATUS
    356 void bscbus_cmd_log(struct bscbus_channel_state *, bsc_cmd_stamp_t,
    357     uint8_t, uint8_t);
    358 #else /* BSCBUS_LOGSTATUS */
    359 #define	bscbus_cmd_log(state, stamp, status, data)
    360 #endif /* BSCBUS_LOGSTATUS */
    361 
    362 
    363 /*
    364  * Local data
    365  */
    366 
    367 static void *bscbus_statep;
    368 
    369 static major_t bscbus_major = NOMAJOR;
    370 
    371 static ddi_device_acc_attr_t bscbus_dev_acc_attr[1] = {
    372 	DDI_DEVICE_ATTR_V0,
    373 	DDI_STRUCTURE_LE_ACC,
    374 	DDI_STRICTORDER_ACC
    375 };
    376 
    377 
    378 /*
    379  *  General utility routines ...
    380  */
    381 
    382 #ifdef DEBUG
    383 static void
    384 bscbus_trace(struct bscbus_channel_state *csp, char code, const char *caller,
    385 	const char *fmt, ...)
    386 {
    387 	char buf[256];
    388 	char *p;
    389 	va_list va;
    390 
    391 	if (csp->ssp->debug & (1 << (code-'@'))) {
    392 		p = buf;
    393 		(void) snprintf(p, sizeof (buf) - (p - buf),
    394 		    "%s/%s: ", MYNAME, caller);
    395 		p += strlen(p);
    396 
    397 		va_start(va, fmt);
    398 		(void) vsnprintf(p, sizeof (buf) - (p - buf), fmt, va);
    399 		va_end(va);
    400 
    401 		buf[sizeof (buf) - 1] = '\0';
    402 		(void) strlog(csp->ssp->majornum, csp->ssp->instance,
    403 		    code, SL_TRACE, buf);
    404 	}
    405 }
    406 #else /* DEBUG */
    407 #define	bscbus_trace
    408 #endif /* DEBUG */
    409 
    410 static struct bscbus_state *
    411 bscbus_getstate(dev_info_t *dip, int instance, const char *caller)
    412 {
    413 	struct bscbus_state *ssp = NULL;
    414 	dev_info_t *sdip = NULL;
    415 	major_t dmaj = NOMAJOR;
    416 
    417 	if (dip != NULL) {
    418 		/*
    419 		 * Use the instance number from the <dip>; also,
    420 		 * check that it really corresponds to this driver
    421 		 */
    422 		instance = ddi_get_instance(dip);
    423 		dmaj = ddi_driver_major(dip);
    424 		if (bscbus_major == NOMAJOR && dmaj != NOMAJOR)
    425 			bscbus_major = dmaj;
    426 		else if (dmaj != bscbus_major) {
    427 			cmn_err(CE_WARN,
    428 			    "%s: major number mismatch (%d vs. %d) in %s(),"
    429 			    "probably due to child misconfiguration",
    430 			    MYNAME, bscbus_major, dmaj, caller);
    431 			instance = -1;
    432 		}
    433 	}
    434 
    435 	if (instance >= 0)
    436 		ssp = ddi_get_soft_state(bscbus_statep, instance);
    437 	if (ssp != NULL) {
    438 		sdip = ssp->dip;
    439 		if (dip == NULL && sdip == NULL)
    440 			ssp = NULL;
    441 		else if (dip != NULL && sdip != NULL && sdip != dip) {
    442 			cmn_err(CE_WARN,
    443 			    "%s: devinfo mismatch (%p vs. %p) in %s(), "
    444 			    "probably due to child misconfiguration",
    445 			    MYNAME, (void *)dip, (void *)sdip, caller);
    446 			ssp = NULL;
    447 		}
    448 	}
    449 
    450 	return (ssp);
    451 }
    452 
    453 /*
    454  * Lowest-level I/O register read/write
    455  */
    456 
    457 static void
    458 bscbus_put_reg(struct bscbus_channel_state *csp, uint_t reg, uint8_t val)
    459 {
    460 	if (csp->ch_handle != NULL && !csp->xio_fault) {
    461 		ddi_put8(csp->ch_handle,
    462 		    csp->ch_regs + reg, val);
    463 	}
    464 }
    465 
    466 static uint8_t
    467 bscbus_get_reg(struct bscbus_channel_state *csp, uint_t reg)
    468 {
    469 	uint8_t val;
    470 
    471 	if (csp->ch_handle != NULL && !csp->xio_fault)
    472 		val = ddi_get8(csp->ch_handle,
    473 		    csp->ch_regs + reg);
    474 	else
    475 		val = DUMMY_VALUE;
    476 
    477 	return (val);
    478 }
    479 
    480 static void
    481 bscbus_check_fault_status(struct bscbus_channel_state *csp)
    482 {
    483 	csp->xio_fault =
    484 	    ddi_check_acc_handle(csp->ch_handle) != DDI_SUCCESS;
    485 }
    486 
    487 static boolean_t
    488 bscbus_faulty(struct bscbus_channel_state *csp)
    489 {
    490 	if (!csp->xio_fault)
    491 		bscbus_check_fault_status(csp);
    492 	return (csp->xio_fault);
    493 }
    494 
    495 /*
    496  * Write data into h8 registers
    497  */
    498 static void
    499 bscbus_pat_dog(struct bscbus_channel_state *csp, uint8_t val)
    500 {
    501 	uint8_t status;
    502 	uint32_t doglimit = BSCBUS_DOG_PAT_POLL_LIMIT;
    503 
    504 	bscbus_trace(csp, 'W', "bscbus_pat_dog:", "");
    505 
    506 	bscbus_cmd_log(csp, BSC_CMD_DOGPAT, 0, val);
    507 	status = bscbus_get_reg(csp, H8_STR);
    508 	while (status & H8_STR_IBF) {
    509 		if (csp->pat_retry_count > BSCBUS_PAT_RETRY_LIMIT) {
    510 			/*
    511 			 * Previous attempts to contact BSC have failed.
    512 			 * Do not bother waiting for it to eat previous
    513 			 * data.
    514 			 * Pat anyway just in case the BSC is really alive
    515 			 * and the IBF bit is lying.
    516 			 */
    517 			bscbus_put_reg(csp, H8_IDRC, val);
    518 			bscbus_trace(csp, 'W', "bscbus_pat_dog:",
    519 			    "retry count exceeded");
    520 			return;
    521 		}
    522 		if (--doglimit == 0) {
    523 			/* The BSC is not responding - give up */
    524 			csp->pat_fail_count++;
    525 			csp->pat_retry_count++;
    526 			/* Pat anyway just in case the BSC is really alive */
    527 			bscbus_put_reg(csp, H8_IDRC, val);
    528 			bscbus_trace(csp, 'W', "bscbus_pat_dog:",
    529 			    "poll limit exceeded");
    530 			return;
    531 		}
    532 		drv_usecwait(BSCBUS_DOG_PAT_POLL);
    533 		status = bscbus_get_reg(csp, H8_STR);
    534 	}
    535 	bscbus_put_reg(csp, H8_IDRC, val);
    536 	csp->pat_retry_count = 0;
    537 }
    538 
    539 /*
    540  * State diagrams for how bscbus_process works.
    541  *	BSCBUS_CMDSTATE_IDLE		No transaction in progress
    542  *	BSCBUS_CMDSTATE_BUSY		Setting up command
    543  *	BSCBUS_CMDSTATE_CLEARING	Clearing firmware busy status
    544  *	BSCBUS_CMDSTATE_SENDING		Waiting to send data to f/w
    545  *	BSCBUS_CMDSTATE_PENDING		Waiting for ack from f/w
    546  *	BSCBUS_CMDSTATE_WAITING		Waiting for status from f/w
    547  *	BSCBUS_CMDSTATE_READY		Status received/command done
    548  *	BSCBUS_CMDSTATE_ERROR		Command failed with error
    549  *
    550  *	+----------+
    551  *	|	   |
    552  *	| IDLE/BUSY|
    553  *	|   (0/1)  |  abnormal
    554  *	+----------+  state
    555  *	    |	  \   detected
    556  *	    |	   \------>------+  +----<---+
    557  *	bsc |			 |  |	     |
    558  *	is  |			 V  V	     |
    559  *     ready|		     +----------+    |
    560  *	    |		     |		|    ^
    561  *	    |		     | CLEARING |    |
    562  *	    |		     |	 (2)	|    |
    563  *	    |		     +----------+    |
    564  *	    |		 cleared /  | \	     | more to clear
    565  *	    |			/   |  \-->--+
    566  *	    |  +-------<-------/    V
    567  *	    |  |		    |
    568  *	    V  V		    |timeout
    569  *	+----------+ timeout	    |
    570  *	|	   |------>---------+--------+
    571  *	| SENDING  |			     |
    572  *	|   (3)	   |------<-------+	     |
    573  *	+----------+		  |	     V
    574  *	sent|	 \ send		  ^ack	     |
    575  *	last|	  \ next	  |received  |
    576  *	    |	   \	     +----------+    |
    577  *	    |	    \	     |		|    |
    578  *	    |	     \------>| PENDING	|-->-+
    579  *	    |		     |	 (4)	|    |
    580  *	    |		     +----------+    |timeout
    581  *	    |	 +---<----+		     |
    582  *	    |	 |	  |		     |
    583  *	    V	 V	  |		     |
    584  *	+----------+	  |		     |
    585  *	|	   |	  |		     |
    586  *	| WAITING  |	  ^		     |
    587  *	|   (5)	   |	  |		     |
    588  *	+----------+	  |		     |
    589  *	    |  | |more	  |		     |
    590  *	    |  V |required|		     |
    591  *	done|  | +--->----+		     |
    592  *	    |  +--->--------------+  +---<---+
    593  *	    |	error/timeout	  |  |
    594  *	    V			  V  V
    595  *	+----------+	      +----------+
    596  *	|	   |	      |		 |
    597  *	| READY	   |	      |	 ERROR	 |
    598  *	|   (7)	   |	      |	  (6)	 |
    599  *	+----------+	      +----------+
    600  *	    |			  |
    601  *	    V			  V
    602  *	    |			  |
    603  *	    +------>---+---<------+
    604  *		       |
    605  *		       |
    606  *		     Back to
    607  *		      Idle
    608  */
    609 
    610 static void
    611 bscbus_process_sending(struct bscbus_channel_state *csp, uint8_t status)
    612 {
    613 	/*
    614 	 * When we get here we actually expect H8_STR_IBF to
    615 	 * be clear but we check just in case of problems.
    616 	 */
    617 	ASSERT(BSCBUS_TX_PENDING(csp));
    618 	if (!(status & H8_STR_IBF)) {
    619 		bscbus_put_reg(csp, H8_IDRD, *--csp->cmdp);
    620 		bscbus_trace(csp, 'P', "bscbus_process_sending",
    621 		    "state %d; val $%x",
    622 		    csp->cmdstate, *csp->cmdp);
    623 		if (!BSCBUS_TX_PENDING(csp)) {
    624 			bscbus_cmd_log(csp, BSC_CMD_SENT,
    625 			    status, *csp->cmdp);
    626 			/* No more pending - move to waiting state */
    627 			bscbus_trace(csp, 'P', "bscbus_process_sending",
    628 			    "moving to waiting");
    629 			csp->cmdstate = BSCBUS_CMDSTATE_WAITING;
    630 			/* Extend deadline because time has moved on */
    631 			csp->deadline = ddi_get_lbolt() +
    632 			    drv_usectohz(LOMBUS_CMD_TIMEOUT/1000);
    633 		} else {
    634 			/* Wait for ack of this byte */
    635 			bscbus_cmd_log(csp, BSC_CMD_SENDING,
    636 			    status, *csp->cmdp);
    637 			csp->cmdstate = BSCBUS_CMDSTATE_PENDING;
    638 			bscbus_trace(csp, 'P', "bscbus_process_sending",
    639 			    "moving to pending");
    640 		}
    641 	}
    642 }
    643 
    644 static void
    645 bscbus_process_clearing(struct bscbus_channel_state *csp,
    646     uint8_t status, uint8_t data)
    647 {
    648 	/*
    649 	 * We only enter this state if H8_STR_BUSY was set when
    650 	 * we started the transaction. We just ignore all received
    651 	 * data until we see OBF set AND BUSY cleared.
    652 	 * It is not good enough to see BUSY clear on its own
    653 	 */
    654 	if ((status & H8_STR_OBF) && !(status & H8_STR_BUSY)) {
    655 		bscbus_cmd_log(csp, BSC_CMD_CLEARED, status, data);
    656 		csp->cmdstate = BSCBUS_CMDSTATE_SENDING;
    657 		/* Throw away any data received up until now */
    658 		bscbus_trace(csp, 'P', "bscbus_process_clearing",
    659 		    "busy cleared");
    660 		/*
    661 		 * Send the next byte immediately.
    662 		 * At this stage we should clear the OBF flag because that
    663 		 * data has been used. IBF is still valid so do not clear that.
    664 		 */
    665 		status &= ~(H8_STR_OBF);
    666 		bscbus_process_sending(csp, status);
    667 	} else {
    668 		if (status & H8_STR_OBF) {
    669 			bscbus_cmd_log(csp, BSC_CMD_CLEARING, status, data);
    670 		}
    671 	}
    672 }
    673 
    674 static void
    675 bscbus_process_pending(struct bscbus_channel_state *csp, uint8_t status)
    676 {
    677 	/* We are waiting for an acknowledgement of a byte */
    678 	if (status & H8_STR_OBF) {
    679 		bscbus_cmd_log(csp, BSC_CMD_PENDING,
    680 		    status, *csp->cmdp);
    681 		bscbus_trace(csp, 'P', "bscbus_process_pending",
    682 		    "moving to sending");
    683 		csp->cmdstate = BSCBUS_CMDSTATE_SENDING;
    684 		/*
    685 		 * Send the next byte immediately.
    686 		 * At this stage we should clear the OBF flag because that
    687 		 * data has been used. IBF is still valid so do not clear that.
    688 		 */
    689 		status &= ~(H8_STR_OBF);
    690 		bscbus_process_sending(csp, status);
    691 	}
    692 }
    693 
    694 static boolean_t
    695 bscbus_process_waiting(struct bscbus_channel_state *csp,
    696     uint8_t status, uint8_t data)
    697 {
    698 	uint8_t rcvd = 0;
    699 	boolean_t ready = B_FALSE;
    700 	uint8_t tmp;
    701 
    702 	if (status & H8_STR_OBF) {
    703 		csp->reply[rcvd = csp->index] = data;
    704 		if (++rcvd < BSCBUS_BUFSIZE)
    705 			csp->index = rcvd;
    706 
    707 		bscbus_trace(csp, 'D', "bscbus_process_waiting",
    708 		    "rcvd %d: $%02x $%02x $%02x $%02x $%02x $%02x $%02x $%02x",
    709 		    rcvd,
    710 		    csp->reply[0], csp->reply[1],
    711 		    csp->reply[2], csp->reply[3],
    712 		    csp->reply[4], csp->reply[5],
    713 		    csp->reply[6], csp->reply[7]);
    714 	}
    715 
    716 	if (rcvd == 0) {
    717 		/*
    718 		 * No bytes received this time through (though there
    719 		 * might be a partial packet sitting in the buffer).
    720 		 */
    721 		/* EMPTY */
    722 		;
    723 	} else if (rcvd >= BSCBUS_BUFSIZE) {
    724 		/*
    725 		 * Buffer overflow; discard the data & treat as an error
    726 		 * (even if the last byte read did claim to terminate a
    727 		 * packet, it can't be a valid one 'cos it's too long!)
    728 		 */
    729 		bscbus_cmd_log(csp, BSC_CMD_ERROR_OFLOW, status, data);
    730 		csp->index = 0;
    731 		csp->cmdstate = BSCBUS_CMDSTATE_ERROR;
    732 		csp->error = LOMBUS_ERR_OFLOW;
    733 		ready = B_TRUE;
    734 	} else if ((data & BSCBUS_LAST) == 0) {
    735 		/*
    736 		 * Packet not yet complete; leave the partial packet in
    737 		 * the buffer for later ...
    738 		 */
    739 		bscbus_cmd_log(csp, BSC_CMD_REPLY, status, data);
    740 	} else if ((data & BSCBUS_MASK) != BSCBUS_STATUS) {
    741 		/* Invalid "status" byte - maybe an echo of the command? */
    742 		bscbus_cmd_log(csp, BSC_CMD_ERROR_STATUS, status, data);
    743 
    744 		csp->cmdstate = BSCBUS_CMDSTATE_ERROR;
    745 		csp->error = LOMBUS_ERR_BADSTATUS;
    746 		ready = B_TRUE;
    747 	} else if ((data & BSCBUS_SEQ) != csp->sequence) {
    748 		/* Wrong sequence number!  Flag this as an error */
    749 		bscbus_cmd_log(csp, BSC_CMD_ERROR_SEQ, status, data);
    750 
    751 		csp->cmdstate = BSCBUS_CMDSTATE_ERROR;
    752 		csp->error = LOMBUS_ERR_SEQUENCE;
    753 		ready = B_TRUE;
    754 	} else {
    755 		/*
    756 		 * Finally, we know that's it's a valid reply to our
    757 		 * last command.  Update the ASYNC status, derive the
    758 		 * reply parameter (if any), and check the ERROR bit
    759 		 * to find out what the parameter means.
    760 		 *
    761 		 * Note that not all the values read/assigned here
    762 		 * are meaningful, but it doesn't matter; the waiting
    763 		 * thread will know which one(s) it should check.
    764 		 */
    765 		bscbus_cmd_log(csp, BSC_CMD_COMPLETE, status, data);
    766 		csp->async = (data & BSCBUS_STATUS_ASYNC) ? 1 : 0;
    767 
    768 		tmp = ((data & BSCBUS_STATUS_MSB) ? 0x80 : 0) | csp->reply[0];
    769 		if (data & BSCBUS_STATUS_ERR) {
    770 			csp->cmdstate = BSCBUS_CMDSTATE_ERROR;
    771 			csp->error = tmp;
    772 		} else {
    773 			csp->cmdstate = BSCBUS_CMDSTATE_READY;
    774 			csp->result = tmp;
    775 		}
    776 		ready = B_TRUE;
    777 	}
    778 	return (ready);
    779 }
    780 
    781 /*
    782  * Packet receive handler
    783  *
    784  * This routine should be called from the low-level softint,
    785  * or bscbus_cmd() (for polled operation), with the
    786  * low-level mutex already held.
    787  */
    788 static void
    789 bscbus_process(struct bscbus_channel_state *csp,
    790     uint8_t status, uint8_t data)
    791 {
    792 	boolean_t ready = B_FALSE;
    793 
    794 	ASSERT(mutex_owned(csp->lo_mutex));
    795 
    796 	if ((status & H8_STR_OBF) || (status & H8_STR_IBF)) {
    797 		bscbus_trace(csp, 'D', "bscbus_process",
    798 		    "state %d; error $%x",
    799 		    csp->cmdstate, csp->error);
    800 	}
    801 
    802 	switch (csp->cmdstate) {
    803 	case BSCBUS_CMDSTATE_CLEARING:
    804 		bscbus_process_clearing(csp, status, data);
    805 		break;
    806 	case BSCBUS_CMDSTATE_SENDING:
    807 		bscbus_process_sending(csp, status);
    808 		break;
    809 	case BSCBUS_CMDSTATE_PENDING:
    810 		bscbus_process_pending(csp, status);
    811 		break;
    812 	case BSCBUS_CMDSTATE_WAITING:
    813 		ready = bscbus_process_waiting(csp, status, data);
    814 		break;
    815 	default:
    816 		/* Nothing to do */
    817 		break;
    818 	}
    819 
    820 	/*
    821 	 * Check for timeouts - but only if the command has not yet
    822 	 * completed (ready is true when command completes in this
    823 	 * call to bscbus_process OR cmdstate is READY or ERROR if
    824 	 * this is a spurious call to bscbus_process i.e. a spurious
    825 	 * interrupt)
    826 	 */
    827 	if (!ready &&
    828 	    ((ddi_get_lbolt() - csp->deadline) > 0) &&
    829 	    csp->cmdstate != BSCBUS_CMDSTATE_READY &&
    830 	    csp->cmdstate != BSCBUS_CMDSTATE_ERROR) {
    831 		bscbus_trace(csp, 'P', "bscbus_process",
    832 		    "timeout previous state %d; error $%x",
    833 		    csp->cmdstate, csp->error);
    834 		bscbus_cmd_log(csp, BSC_CMD_ERROR_TOUT, status, data);
    835 		if (csp->cmdstate == BSCBUS_CMDSTATE_CLEARING) {
    836 			/* Move onto sending because busy might be stuck */
    837 			csp->cmdstate = BSCBUS_CMDSTATE_SENDING;
    838 			/* Extend timeout relative to original start time */
    839 			csp->deadline += drv_usectohz(LOMBUS_CMD_TIMEOUT/1000);
    840 		} else if (csp->cmdstate != BSCBUS_CMDSTATE_IDLE) {
    841 			csp->cmdstate = BSCBUS_CMDSTATE_ERROR;
    842 			csp->error = LOMBUS_ERR_TIMEOUT;
    843 		}
    844 		ready = B_TRUE;
    845 	}
    846 
    847 	if ((status & H8_STR_OBF) || (status & H8_STR_IBF) || ready) {
    848 		bscbus_trace(csp, 'D', "bscbus_process",
    849 		    "last $%02x; state %d; error $%x; ready %d",
    850 		    data, csp->cmdstate, csp->error, ready);
    851 	}
    852 	if (ready)
    853 		cv_broadcast(csp->lo_cv);
    854 }
    855 
    856 static uint_t
    857 bscbus_hwintr(caddr_t arg)
    858 {
    859 	struct bscbus_channel_state *csp = (void *)arg;
    860 
    861 	uint8_t status;
    862 	uint8_t data = 0xb0 /* Dummy value */;
    863 
    864 	mutex_enter(csp->lo_mutex);
    865 	/*
    866 	 * Read the registers to ensure that the interrupt is cleared.
    867 	 * Status must be read first because reading data changes the
    868 	 * status.
    869 	 * We always read the data because that clears the interrupt down.
    870 	 * This is horrible hardware semantics but we have to do it!
    871 	 */
    872 	status = bscbus_get_reg(csp, H8_STR);
    873 	data = bscbus_get_reg(csp, H8_ODR);
    874 	if (!(status & H8_STR_OBF)) {
    875 		bscbus_cmd_log(csp, BSC_CMD_V1INTRUNCL, status, data);
    876 		csp->unclaimed_count++;
    877 	} else {
    878 		bscbus_cmd_log(csp, BSC_CMD_V1INTR, status, data);
    879 	}
    880 	if (status & H8_STR_TOKENPROTOCOL) {
    881 		bscbus_process(csp, status, data);
    882 		if (csp->interrupt_failed) {
    883 			bscbus_trace(csp, 'I', "bscbus_hwintr:",
    884 			    "interrupt fault cleared channel %d", csp->chno);
    885 			csp->interrupt_failed = B_FALSE;
    886 			csp->poll_hz = drv_usectohz(BSCBUS_CMD_POLL / 1000);
    887 		}
    888 	}
    889 
    890 	mutex_exit(csp->lo_mutex);
    891 	return (DDI_INTR_CLAIMED);
    892 }
    893 
    894 void
    895 bscbus_poll(struct bscbus_channel_state *csp)
    896 {
    897 	/*
    898 	 * This routine is only called if we timeout in userland
    899 	 * waiting for an interrupt. This generally means that we have
    900 	 * lost interrupt capabilities or that something has gone
    901 	 * wrong.  In this case we are allowed to access the hardware
    902 	 * and read the data register if necessary.
    903 	 * If interrupts return then recovery actions should mend us!
    904 	 */
    905 	uint8_t status;
    906 	uint8_t data = 0xfa; /* Dummy value */
    907 
    908 	ASSERT(mutex_owned(csp->lo_mutex));
    909 
    910 	/* Should look for data to receive */
    911 	status = bscbus_get_reg(csp, H8_STR);
    912 	if (status & H8_STR_OBF) {
    913 		/* There is data available */
    914 		data = bscbus_get_reg(csp, H8_ODR);
    915 		bscbus_cmd_log(csp, BSC_CMD_PROCESS, status, data);
    916 	}
    917 	bscbus_process(csp, status, data);
    918 }
    919 
    920 /*
    921  * Serial protocol
    922  *
    923  * This routine builds a command and sets it in progress.
    924  */
    925 static uint8_t
    926 bscbus_cmd(HANDLE_TYPE *hdlp, ptrdiff_t vreg, uint_t val, uint_t cmd)
    927 {
    928 	struct bscbus_channel_state *csp;
    929 	clock_t start;
    930 	clock_t tick;
    931 	uint8_t status;
    932 
    933 	/*
    934 	 * First of all, wait for the interface to be available.
    935 	 *
    936 	 * NOTE: we blow through all the mutex/cv/state checking and
    937 	 * preempt any command in progress if the system is panicking!
    938 	 */
    939 	csp = HANDLE_PRIVATE(hdlp);
    940 	mutex_enter(csp->lo_mutex);
    941 	while (csp->cmdstate != BSCBUS_CMDSTATE_IDLE && !ddi_in_panic())
    942 		cv_wait(csp->lo_cv, csp->lo_mutex);
    943 
    944 	csp->cmdstate = BSCBUS_CMDSTATE_BUSY;
    945 	csp->sequence = (csp->sequence + BSCBUS_SEQ_LSB) & BSCBUS_SEQ;
    946 
    947 	/*
    948 	 * We have exclusive ownership, so assemble the command (backwards):
    949 	 *
    950 	 * [byte 0]	Command:	modified by XADDR and/or WMSB bits
    951 	 * [Optional] Parameter: 	Value to write (low 7 bits)
    952 	 * [Optional] Parameter: 	Register number (high 7 bits)
    953 	 * [Optional] Parameter: 	Register number (low 7 bits)
    954 	 */
    955 	csp->cmdp = &csp->cmdbuf[0];
    956 	*csp->cmdp++ = BSCBUS_CMD | csp->sequence | cmd;
    957 	switch (cmd) {
    958 	case BSCBUS_CMD_WRITE:
    959 		*csp->cmdp++ = val & 0x7f;
    960 		if (val >= 0x80)
    961 			csp->cmdbuf[0] |= BSCBUS_CMD_WMSB;
    962 		/*FALLTHRU*/
    963 	case BSCBUS_CMD_READ:
    964 		if (BSCBUS_VREG_HI(vreg) != 0) {
    965 			*csp->cmdp++ = BSCBUS_VREG_HI(vreg);
    966 			csp->cmdbuf[0] |= BSCBUS_CMD_XADDR;
    967 		}
    968 		*csp->cmdp++ = BSCBUS_VREG_LO(vreg);
    969 		/*FALLTHRU*/
    970 	case BSCBUS_CMD_NOP:
    971 		break;
    972 	}
    973 
    974 	/*
    975 	 * Check and update the H8 h/w fault status before accessing
    976 	 * the chip registers.  If there's a (new or previous) fault,
    977 	 * we'll run through the protocol but won't really touch the
    978 	 * hardware and all commands will timeout.  If a previously
    979 	 * discovered fault has now gone away (!), then we can (try to)
    980 	 * proceed with the new command (probably a probe).
    981 	 */
    982 	bscbus_check_fault_status(csp);
    983 
    984 	/*
    985 	 * Prepare for the command (to be processed by the interrupt
    986 	 * handler and/or polling loop below), and wait for a response
    987 	 * or timeout.
    988 	 */
    989 	start = ddi_get_lbolt();
    990 	csp->deadline = start + drv_usectohz(LOMBUS_CMD_TIMEOUT/1000);
    991 	csp->error = 0;
    992 	csp->index = 0;
    993 	csp->result = DUMMY_VALUE;
    994 
    995 	status = bscbus_get_reg(csp, H8_STR);
    996 	if (status & H8_STR_BUSY) {
    997 		bscbus_cmd_log(csp, BSC_CMD_BUSY, status, 0xfd);
    998 		/*
    999 		 * Must ensure that the busy state has cleared before
   1000 		 * sending the command
   1001 		 */
   1002 		csp->cmdstate = BSCBUS_CMDSTATE_CLEARING;
   1003 		bscbus_trace(csp, 'P', "bscbus_cmd",
   1004 		    "h8 reporting status (%x) busy - clearing", status);
   1005 	} else {
   1006 		/* It is clear to send the command immediately */
   1007 		csp->cmdstate = BSCBUS_CMDSTATE_SENDING;
   1008 		bscbus_trace(csp, 'P', "bscbus_cmd",
   1009 		    "sending first byte of command, status %x", status);
   1010 		bscbus_poll(csp);
   1011 	}
   1012 
   1013 	csp->poll_hz = drv_usectohz(
   1014 	    (csp->interrupt_failed ?
   1015 	    BSCBUS_CMD_POLLNOINTS : BSCBUS_CMD_POLL) / 1000);
   1016 
   1017 	while ((csp->cmdstate != BSCBUS_CMDSTATE_READY) &&
   1018 	    (csp->cmdstate != BSCBUS_CMDSTATE_ERROR)) {
   1019 		ASSERT(csp->cmdstate != BSCBUS_CMDSTATE_IDLE);
   1020 
   1021 		tick = ddi_get_lbolt() + csp->poll_hz;
   1022 		if ((cv_timedwait(csp->lo_cv, csp->lo_mutex, tick) == -1) &&
   1023 		    csp->cmdstate != BSCBUS_CMDSTATE_READY &&
   1024 		    csp->cmdstate != BSCBUS_CMDSTATE_ERROR) {
   1025 			if (!csp->interrupt_failed) {
   1026 				bscbus_trace(csp, 'I', "bscbus_cmd:",
   1027 				    "interrupt_failed channel %d", csp->chno);
   1028 				csp->interrupt_failed = B_TRUE;
   1029 				csp->poll_hz = drv_usectohz(
   1030 				    BSCBUS_CMD_POLLNOINTS / 1000);
   1031 			}
   1032 			bscbus_poll(csp);
   1033 		}
   1034 	}
   1035 
   1036 	/*
   1037 	 * The return value may not be meaningful but retrieve it anyway
   1038 	 */
   1039 	val = csp->result;
   1040 	if (bscbus_faulty(csp)) {
   1041 		val = DUMMY_VALUE;
   1042 		HANDLE_FAULT(hdlp) = LOMBUS_ERR_SIOHW;
   1043 	} else if (csp->cmdstate != BSCBUS_CMDSTATE_READY) {
   1044 		/*
   1045 		 * Some problem here ... transfer the error code from
   1046 		 * the per-instance state to the per-handle fault flag.
   1047 		 * The error code shouldn't be zero!
   1048 		 */
   1049 		if (csp->error != 0)
   1050 			HANDLE_FAULT(hdlp) = csp->error;
   1051 		else
   1052 			HANDLE_FAULT(hdlp) = LOMBUS_ERR_BADERRCODE;
   1053 	}
   1054 
   1055 	/*
   1056 	 * All done now!
   1057 	 */
   1058 	csp->index = 0;
   1059 	csp->cmdstate = BSCBUS_CMDSTATE_IDLE;
   1060 	cv_broadcast(csp->lo_cv);
   1061 	mutex_exit(csp->lo_mutex);
   1062 
   1063 	return (val);
   1064 }
   1065 
   1066 /*
   1067  * Space 0 - LOM virtual register access
   1068  * Only 8-bit accesses are supported.
   1069  */
   1070 static uint8_t
   1071 bscbus_vreg_get8(HANDLE_TYPE *hdlp, uint8_t *addr)
   1072 {
   1073 	ptrdiff_t offset;
   1074 
   1075 	/*
   1076 	 * Check the offset that the caller has added to the base address
   1077 	 * against the length of the mapping originally requested.
   1078 	 */
   1079 	offset = ADDR_TO_OFFSET(addr, hdlp);
   1080 	if</