i2bsc.c revision 4135:69588295f961
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 2005 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident	"%Z%%M%	%I%	%E% SMI"
27
28/*
29 * i2bsc.c is the nexus driver i2c traffic against devices hidden behind the
30 * Blade Support Chip (BSC).  It supports both interrupt and polled
31 * mode operation, but defaults to interrupt.
32 */
33
34#include <sys/types.h>
35#include <sys/conf.h>
36#include <sys/file.h>
37#include <sys/open.h>
38#include <sys/ddi.h>
39#include <sys/sunddi.h>
40#include <sys/sunndi.h>
41#include <sys/modctl.h>
42#include <sys/stat.h>
43#include <sys/kmem.h>
44#include <sys/platform_module.h>
45#include <sys/stream.h>
46#include <sys/strlog.h>
47#include <sys/log.h>
48#include <sys/debug.h>
49#include <sys/note.h>
50
51#include <sys/bscbus.h>
52#include <sys/lom_ebuscodes.h>
53
54#include <sys/i2c/clients/i2c_client.h>
55#include <sys/i2c/misc/i2c_svc.h>
56#include <sys/i2c/misc/i2c_svc_impl.h>
57#include <sys/i2c/nexus/i2bsc_impl.h>
58
59/*
60 * static function declarations
61 */
62static void i2bsc_resume(dev_info_t *dip);
63static void i2bsc_suspend(dev_info_t *dip);
64static int i2bsc_bus_ctl(dev_info_t *dip, dev_info_t *rdip,
65	ddi_ctl_enum_t op, void *arg, void *result);
66static  void i2bsc_acquire(i2bsc_t *, dev_info_t *dip,
67	i2c_transfer_t *tp);
68static  void i2bsc_release(i2bsc_t *);
69static int i2bsc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
70static int i2bsc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
71static int i2bsc_open(dev_t *devp, int flag, int otyp,
72    cred_t *cred_p);
73static int i2bsc_close(dev_t dev, int flag, int otyp,
74    cred_t *cred_p);
75static int i2bsc_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
76static int i2bsc_initchild(dev_info_t *dip, dev_info_t *cdip);
77static int i2bsc_uninitchild(dev_info_t *dip, dev_info_t *cdip);
78static int i2bsc_setup_regs(i2bsc_t *);
79static void i2bsc_start_session(i2bsc_t *);
80static void i2bsc_fail_session(i2bsc_t *);
81static int i2bsc_end_session(i2bsc_t *);
82static void i2bsc_free_regs(i2bsc_t *);
83static int i2bsc_reportdev(dev_info_t *dip, dev_info_t *rdip);
84int i2bsc_transfer(dev_info_t *dip, i2c_transfer_t *tp);
85static void i2bsc_trace(i2bsc_t *, char, const char *,
86    const char *, ...);
87static int i2bsc_notify_max_transfer_size(i2bsc_t *);
88static int i2bsc_discover_capability(i2bsc_t *);
89static void i2bsc_put8(i2bsc_t *, uint8_t, uint8_t, uint8_t);
90static uint8_t i2bsc_get8(i2bsc_t *, uint8_t, uint8_t);
91static int i2bsc_safe_upload(i2bsc_t *, i2c_transfer_t *);
92static boolean_t i2bsc_is_firmware_broken(i2bsc_t *);
93
94static struct bus_ops i2bsc_busops = {
95	BUSO_REV,
96	nullbusmap,			/* bus_map */
97	NULL,				/* bus_get_intrspec */
98	NULL,				/* bus_add_intrspec */
99	NULL,				/* bus_remove_intrspec */
100	NULL,				/* bus_map_fault */
101	ddi_no_dma_map,			/* bus_dma_map */
102	ddi_no_dma_allochdl,		/* bus_dma_allochdl */
103	ddi_no_dma_freehdl,		/* bus_dma_freehdl */
104	ddi_no_dma_bindhdl,		/* bus_dma_bindhdl */
105	ddi_no_dma_unbindhdl,		/* bus_unbindhdl */
106	ddi_no_dma_flush,		/* bus_dma_flush */
107	ddi_no_dma_win,			/* bus_dma_win */
108	ddi_no_dma_mctl,		/* bus_dma_ctl */
109	i2bsc_bus_ctl,			/* bus_ctl */
110	ddi_bus_prop_op,		/* bus_prop_op */
111	NULL,				/* bus_get_eventcookie */
112	NULL,				/* bus_add_eventcall */
113	NULL,				/* bus_remove_eventcall */
114	NULL,				/* bus_post_event */
115	0,				/* bus_intr_ctl */
116	0,				/* bus_config		*/
117	0,				/* bus_unconfig		*/
118	0,				/* bus_fm_init		*/
119	0,				/* bus_fm_fini		*/
120	0,				/* bus_fm_access_enter	*/
121	0,				/* bus_fm_access_exit	*/
122	0,				/* bus_power		*/
123	i_ddi_intr_ops			/* bus_intr_op		*/
124
125};
126
127struct cb_ops i2bsc_cb_ops = {
128	i2bsc_open,		/* open */
129	i2bsc_close,		/* close */
130	nodev,			/* strategy */
131	nodev,			/* print */
132	nodev,			/* dump */
133	nodev,			/* read */
134	nodev,			/* write */
135	i2bsc_ioctl,		/* ioctl */
136	nodev,			/* devmap */
137	nodev,			/* mmap */
138	nodev,			/* segmap */
139	nochpoll,		/* poll */
140	ddi_prop_op,		/* cb_prop_op */
141	0,			/* streamtab  */
142	D_MP | D_NEW		/* Driver compatibility flag */
143};
144
145static struct dev_ops i2bsc_ops = {
146	DEVO_REV,
147	0,
148	ddi_getinfo_1to1,
149	nulldev,
150	nulldev,
151	i2bsc_attach,
152	i2bsc_detach,
153	nodev,
154	&i2bsc_cb_ops,
155	&i2bsc_busops
156};
157
158#ifdef DEBUG
159#define	I2BSC_VERSION_STRING "i2bsc driver - Debug v%I%"
160#else
161#define	I2BSC_VERSION_STRING "i2bsc driver v%I%"
162#endif
163
164static struct modldrv modldrv = {
165	&mod_driverops, /* Type of module. This one is a driver */
166	I2BSC_VERSION_STRING,	/* Name of the module. */
167	&i2bsc_ops,		/* driver ops */
168};
169
170static struct modlinkage modlinkage = {
171	MODREV_1,
172	&modldrv,
173	NULL
174};
175
176/*
177 * i2bsc soft state
178 */
179static void	*i2bsc_state;
180
181i2c_nexus_reg_t i2bsc_regvec = {
182	I2C_NEXUS_REV,
183	i2bsc_transfer,
184};
185
186int
187_init(void)
188{
189	int status;
190
191	status = ddi_soft_state_init(&i2bsc_state, sizeof (i2bsc_t),
192		I2BSC_INITIAL_SOFT_SPACE);
193	if (status != 0) {
194		return (status);
195	}
196
197	if ((status = mod_install(&modlinkage)) != 0) {
198		ddi_soft_state_fini(&i2bsc_state);
199	}
200
201	return (status);
202}
203
204int
205_fini(void)
206{
207	int status;
208
209	if ((status = mod_remove(&modlinkage)) == 0) {
210		ddi_soft_state_fini(&i2bsc_state);
211	}
212
213	return (status);
214}
215
216/*
217 * The loadable-module _info(9E) entry point
218 */
219int
220_info(struct modinfo *modinfop)
221{
222	return (mod_info(&modlinkage, modinfop));
223}
224
225static void
226i2bsc_dodetach(dev_info_t *dip)
227{
228	i2bsc_t *i2c;
229	int instance = ddi_get_instance(dip);
230
231	i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
232
233	if ((i2c->i2bsc_attachflags & IMUTEX) != 0) {
234		mutex_destroy(&i2c->i2bsc_imutex);
235		cv_destroy(&i2c->i2bsc_icv);
236	}
237	if ((i2c->i2bsc_attachflags & SETUP_REGS) != 0) {
238		i2bsc_free_regs(i2c);
239	}
240	if ((i2c->i2bsc_attachflags & NEXUS_REGISTER) != 0) {
241		i2c_nexus_unregister(dip);
242	}
243	if ((i2c->i2bsc_attachflags & MINOR_NODE) != 0) {
244		ddi_remove_minor_node(dip, NULL);
245	}
246
247	ddi_soft_state_free(i2bsc_state, instance);
248}
249
250static int
251i2bsc_doattach(dev_info_t *dip)
252{
253	i2bsc_t *i2c;
254	int instance = ddi_get_instance(dip);
255
256	/*
257	 * Allocate soft state structure.
258	 */
259	if (ddi_soft_state_zalloc(i2bsc_state, instance) != DDI_SUCCESS) {
260		return (DDI_FAILURE);
261	}
262
263	i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
264
265	i2c->majornum = ddi_driver_major(dip);
266	i2c->minornum = instance;
267	i2c->i2bsc_dip = dip;
268	i2c->debug = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
269		DDI_PROP_DONTPASS, "debug", 0);
270
271	(void) snprintf(i2c->i2bsc_name, sizeof (i2c->i2bsc_name),
272		"%s_%d", ddi_node_name(dip), instance);
273
274	if (i2bsc_setup_regs(i2c) != DDI_SUCCESS) {
275		goto bad;
276	}
277
278	i2c->i2bsc_attachflags |= SETUP_REGS;
279
280	mutex_init(&i2c->i2bsc_imutex, NULL, MUTEX_DRIVER,
281	    (void *) 0);
282	cv_init(&i2c->i2bsc_icv, NULL, CV_DRIVER, NULL);
283	i2c->i2bsc_attachflags |= IMUTEX;
284
285	i2c_nexus_register(dip, &i2bsc_regvec);
286	i2c->i2bsc_attachflags |= NEXUS_REGISTER;
287
288	if (ddi_create_minor_node(dip, "devctl", S_IFCHR, instance,
289	    DDI_NT_NEXUS, 0) == DDI_FAILURE) {
290		cmn_err(CE_WARN, "%s ddi_create_minor_node failed",
291		    i2c->i2bsc_name);
292		goto bad;
293	}
294
295	i2c->i2bsc_attachflags |= MINOR_NODE;
296
297	/*
298	 * Now actually start talking to the microcontroller.  The first
299	 * thing to check is whether the firmware is broken.
300	 */
301	if (i2bsc_is_firmware_broken(i2c)) {
302		cmn_err(CE_WARN, "Underlying BSC hardware not communicating;"
303		    " shutting down my i2c services");
304		goto bad;
305	}
306
307	i2c->i2bsc_attachflags |= FIRMWARE_ALIVE;
308
309	/*
310	 * Now see if the BSC chip supports the i2c service we rely upon.
311	 */
312	(void) i2bsc_discover_capability(i2c);
313
314	if (i2bsc_notify_max_transfer_size(i2c) == DDI_SUCCESS)
315		i2c->i2bsc_attachflags |= TRANSFER_SZ;
316
317	i2bsc_trace(i2c, 'A', "i2bsc_doattach", "attachflags %d",
318	    i2c->i2bsc_attachflags);
319
320	return (DDI_SUCCESS);
321
322bad:
323	i2bsc_dodetach(dip);
324
325	return (DDI_FAILURE);
326}
327
328static int
329i2bsc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
330{
331	switch (cmd) {
332	    case DDI_ATTACH:
333		return (i2bsc_doattach(dip));
334
335	    case DDI_RESUME:
336		i2bsc_resume(dip);
337		return (DDI_SUCCESS);
338
339	    default:
340		return (DDI_FAILURE);
341	}
342}
343
344static int
345i2bsc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
346{
347	switch (cmd) {
348	case DDI_DETACH:
349		i2bsc_dodetach(dip);
350		return (DDI_SUCCESS);
351
352	case DDI_SUSPEND:
353		i2bsc_suspend(dip);
354		return (DDI_SUCCESS);
355
356	default:
357		return (DDI_FAILURE);
358	}
359}
360
361/*ARGSUSED*/
362static int
363i2bsc_open(dev_t  *devp,  int  flag,  int  otyp,  cred_t *cred_p)
364{
365	int instance;
366	i2bsc_t *i2c;
367
368	/*
369	 * Make sure the open is for the right file type
370	 */
371	if (otyp != OTYP_CHR)
372		return (EINVAL);
373
374	instance = getminor(*devp);
375	i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
376	if (i2c == NULL)
377		return (ENXIO);
378
379	/*
380	 * Enforce exclusive access
381	 */
382	mutex_enter(&i2c->i2bsc_imutex);
383	if (i2c->i2bsc_open) {
384		mutex_exit(&i2c->i2bsc_imutex);
385		return (EBUSY);
386	} else
387		i2c->i2bsc_open = 1;
388
389	mutex_exit(&i2c->i2bsc_imutex);
390
391	return (0);
392}
393
394/*ARGSUSED*/
395static int
396i2bsc_close(dev_t  dev,  int  flag,  int  otyp,  cred_t *cred_p)
397{
398	int instance;
399	i2bsc_t *i2c;
400
401	/*
402	 * Make sure the close is for the right file type
403	 */
404	if (otyp != OTYP_CHR)
405		return (EINVAL);
406
407	instance = getminor(dev);
408	i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
409	if (i2c == NULL)
410		return (ENXIO);
411
412	mutex_enter(&i2c->i2bsc_imutex);
413	i2c->i2bsc_open = 0;
414	mutex_exit(&i2c->i2bsc_imutex);
415
416	return (0);
417}
418
419/*ARGSUSED*/
420static int
421i2bsc_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
422	int *rvalp)
423{
424	i2bsc_t *i2c;
425	dev_info_t *self;
426	dev_info_t *child;
427	struct devctl_iocdata *dcp;
428	int rv;
429
430	i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, getminor(dev));
431
432	if (i2c == NULL)
433		return (ENXIO);
434
435	self = (dev_info_t *)i2c->i2bsc_dip;
436
437	/*
438	 * read devctl ioctl data
439	 */
440	if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS) {
441		return (EFAULT);
442	}
443
444	switch (cmd) {
445	    case DEVCTL_BUS_DEV_CREATE:
446		rv = ndi_dc_devi_create(dcp, self, 0, NULL);
447		break;
448
449	    case DEVCTL_DEVICE_REMOVE:
450		if (ndi_dc_getname(dcp) == NULL ||
451			ndi_dc_getaddr(dcp) == NULL) {
452			rv = EINVAL;
453			break;
454		}
455
456		/*
457		 * lookup and hold child device
458		 */
459		child = ndi_devi_find(self,
460			ndi_dc_getname(dcp), ndi_dc_getaddr(dcp));
461		if (child == NULL) {
462			rv = ENXIO;
463			break;
464		}
465
466		if ((rv = ndi_devi_offline(child, NDI_DEVI_REMOVE)) !=
467			NDI_SUCCESS) {
468			rv = (rv == NDI_BUSY) ? EBUSY : EIO;
469		}
470
471		break;
472
473	    default:
474		rv = ENOTSUP;
475	}
476
477	ndi_dc_freehdl(dcp);
478
479	return (rv);
480}
481
482static int
483i2bsc_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t op,
484    void *arg, void *result)
485{
486	i2bsc_t	*i2c;
487	int instance = ddi_get_instance(dip);
488
489	i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
490
491	i2bsc_trace(i2c, 'A', "i2bsc_bus_ctl", "dip/rdip,op/arg"
492	    " %p/%p,%d/%p", dip, rdip, (int)op, arg);
493
494	switch (op) {
495	    case DDI_CTLOPS_INITCHILD:
496		return (i2bsc_initchild(dip, (dev_info_t *)arg));
497
498	    case DDI_CTLOPS_UNINITCHILD:
499		return (i2bsc_uninitchild(dip, (dev_info_t *)arg));
500
501	    case DDI_CTLOPS_REPORTDEV:
502		return (i2bsc_reportdev(dip, rdip));
503
504	    case DDI_CTLOPS_DMAPMAPC:
505	    case DDI_CTLOPS_POKE:
506	    case DDI_CTLOPS_PEEK:
507	    case DDI_CTLOPS_IOMIN:
508	    case DDI_CTLOPS_REPORTINT:
509	    case DDI_CTLOPS_SIDDEV:
510	    case DDI_CTLOPS_SLAVEONLY:
511	    case DDI_CTLOPS_AFFINITY:
512	    case DDI_CTLOPS_PTOB:
513	    case DDI_CTLOPS_BTOP:
514	    case DDI_CTLOPS_BTOPR:
515	    case DDI_CTLOPS_DVMAPAGESIZE:
516		return (DDI_FAILURE);
517
518	    default:
519		return (ddi_ctlops(dip, rdip, op, arg, result));
520	}
521}
522
523/*
524 * i2bsc_suspend() is called before the system suspends.  Existing
525 * transfer in progress or waiting will complete, but new transfers are
526 * effectively blocked by "acquiring" the bus.
527 */
528static void
529i2bsc_suspend(dev_info_t *dip)
530{
531	i2bsc_t *i2c;
532	int instance;
533
534	instance = ddi_get_instance(dip);
535	i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
536
537	i2bsc_acquire(i2c, NULL, NULL);
538}
539
540/*
541 * i2bsc_resume() is called when the system resumes from CPR.  It releases
542 * the hold that was placed on the i2c bus, which allows any real
543 * transfers to continue.
544 */
545static void
546i2bsc_resume(dev_info_t *dip)
547{
548	i2bsc_t *i2c;
549	int instance;
550
551	instance = ddi_get_instance(dip);
552	i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, instance);
553
554	i2bsc_release(i2c);
555}
556
557/*
558 * i2bsc_acquire() is called by a thread wishing to "own" the I2C bus.
559 * It should not be held across multiple transfers.
560 */
561static void
562i2bsc_acquire(i2bsc_t *i2c, dev_info_t *dip, i2c_transfer_t *tp)
563{
564	mutex_enter(&i2c->i2bsc_imutex);
565	while (i2c->i2bsc_busy) {
566		cv_wait(&i2c->i2bsc_icv, &i2c->i2bsc_imutex);
567	}
568	i2c->i2bsc_busy = 1;
569	i2c->i2bsc_cur_tran = tp;
570	i2c->i2bsc_cur_dip = dip;
571	mutex_exit(&i2c->i2bsc_imutex);
572}
573
574/*
575 * i2bsc_release() is called to release a hold made by i2bsc_acquire().
576 */
577static void
578i2bsc_release(i2bsc_t *i2c)
579{
580	mutex_enter(&i2c->i2bsc_imutex);
581	i2c->i2bsc_busy = 0;
582	i2c->i2bsc_cur_tran = NULL;
583	cv_signal(&i2c->i2bsc_icv);
584	mutex_exit(&i2c->i2bsc_imutex);
585}
586
587static int
588i2bsc_initchild(dev_info_t *dip, dev_info_t *cdip)
589{
590	i2bsc_t *i2c;
591	int32_t address_cells;
592	int len;
593	int32_t regs[3];
594	int err;
595	i2bsc_ppvt_t *ppvt;
596	char name[30];
597
598	i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, ddi_get_instance(dip));
599
600	i2bsc_trace(i2c, 'A', "i2bsc_initchild", "dip/cdip %p/%p", dip, cdip);
601
602	ppvt = kmem_alloc(sizeof (i2bsc_ppvt_t), KM_SLEEP);
603
604	len = sizeof (address_cells);
605
606	err = ddi_getlongprop_buf(DDI_DEV_T_ANY, cdip,
607		DDI_PROP_CANSLEEP, "#address-cells",
608		(caddr_t)&address_cells, &len);
609	if (err != DDI_PROP_SUCCESS || len != sizeof (address_cells)) {
610		return (DDI_FAILURE);
611	}
612
613	len = sizeof (regs);
614	err = ddi_getlongprop_buf(DDI_DEV_T_ANY, cdip,
615		DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP,
616		"reg", (caddr_t)regs, &len);
617	if (err != DDI_PROP_SUCCESS)
618		return (DDI_FAILURE);
619
620	if (address_cells == 1) {
621		ppvt->i2bsc_ppvt_bus = I2BSC_DEFAULT_BUS;
622		ppvt->i2bsc_ppvt_addr = regs[0];
623		(void) sprintf(name, "%x", regs[0]);
624		i2bsc_trace(i2c, 'A', "i2bsc_initchild", "#address-cells = 1"
625		    " regs[0] = %d", regs[0]);
626	} else if (address_cells == 2) {
627		ppvt->i2bsc_ppvt_bus = regs[0];
628		ppvt->i2bsc_ppvt_addr = regs[1];
629		(void) sprintf(name, "%x,%x", regs[0], regs[1]);
630		i2bsc_trace(i2c, 'A', "i2bsc_initchild", "#address-cells = 2"
631		    " regs[0] = %d, regs[1] = %d", regs[0], regs[1]);
632	} else {
633		return (DDI_FAILURE);
634	}
635
636	/*
637	 * Attach the parent's private data structure to the child's devinfo
638	 * node, and store the child's address on the nexus in the child's
639	 * devinfo node.
640	 */
641	ddi_set_parent_data(cdip, ppvt);
642	ddi_set_name_addr(cdip, name);
643
644	i2bsc_trace(i2c, 'A', "i2bsc_initchild", "success(%s)",
645	    ddi_node_name(cdip));
646
647	return (DDI_SUCCESS);
648}
649
650static int
651i2bsc_uninitchild(dev_info_t *dip, dev_info_t *cdip)
652{
653	i2bsc_t *i2c;
654	i2bsc_ppvt_t *ppvt;
655
656	i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state, ddi_get_instance(dip));
657
658	i2bsc_trace(i2c, 'D', "i2bsc_uninitchild", "dip/cdip %p/%p", dip, cdip);
659
660	ppvt = ddi_get_parent_data(cdip);
661	kmem_free(ppvt, sizeof (i2bsc_ppvt_t));
662
663	ddi_set_parent_data(cdip, NULL);
664	ddi_set_name_addr(cdip, NULL);
665
666	i2bsc_trace(i2c, 'D', "i2bsc_uninitchild", "success(%s)",
667	    ddi_node_name(cdip));
668
669	return (DDI_SUCCESS);
670}
671
672/*
673 * i2bsc_setup_regs() is called to map in registers specific to
674 * the i2bsc.
675 */
676static int
677i2bsc_setup_regs(i2bsc_t *i2c)
678{
679	int nregs;
680
681	i2c->bscbus_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
682	i2c->bscbus_attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
683	i2c->bscbus_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
684
685	if (ddi_dev_nregs(i2c->i2bsc_dip, &nregs) != DDI_SUCCESS) {
686		return (DDI_FAILURE);
687	}
688
689	if (nregs < 1) {
690		return (DDI_FAILURE);
691	}
692
693	if (ddi_regs_map_setup(i2c->i2bsc_dip, 0,
694	    (caddr_t *)&i2c->bscbus_regs, 0, 0, &i2c->bscbus_attr,
695	    &i2c->bscbus_handle) != DDI_SUCCESS) {
696		return (DDI_FAILURE);
697	}
698
699	return (DDI_SUCCESS);
700}
701
702/*
703 * i2bsc_free_regs() frees any registers previously
704 * allocated.
705 */
706static void
707i2bsc_free_regs(i2bsc_t *i2c)
708{
709	if (i2c->bscbus_regs != NULL) {
710		ddi_regs_map_free(&i2c->bscbus_handle);
711	}
712}
713
714/*ARGSUSED*/
715static int
716i2bsc_reportdev(dev_info_t *dip, dev_info_t *rdip)
717{
718	if (rdip == (dev_info_t *)0)
719		return (DDI_FAILURE);
720
721	cmn_err(CE_CONT, "?i2bsc-device: %s@%s, %s%d\n",
722	    ddi_node_name(rdip), ddi_get_name_addr(rdip), ddi_driver_name(rdip),
723	    ddi_get_instance(rdip));
724
725	return (DDI_SUCCESS);
726}
727
728/*
729 * I/O Functions
730 *
731 * i2bsc_{put,get}8_once are wrapper functions to ddi_{get,put}8.
732 * i2bsc_{put,get}8 are equivalent functions but with retry code.
733 * i2bsc_bscbus_state determines underlying bus error status.
734 * i2bsc_clear_acc_fault clears the underlying bus error status.
735 *
736 * I/O Flags
737 *
738 * bscbus_fault	   -	Error register in underlying bus for last IO operation.
739 * session_failure - 	Set by any failed IO command.  This is a sticky flag
740 * 			reset explicitly using i2bsc_start_session
741 *
742 * Session Management
743 *
744 * i2bsc_{start,end}_session need to be used to detect an error across multiple
745 * gets/puts rather than having to test for an error on each get/put.
746 */
747
748static int i2bsc_bscbus_state(i2bsc_t *i2c)
749{
750	uint32_t retval;
751
752	retval = ddi_get32(i2c->bscbus_handle,
753		    (uint32_t *)I2BSC_NEXUS_ADDR(i2c, EBUS_CMD_SPACE_GENERIC,
754		    LOMBUS_FAULT_REG));
755	i2c->bscbus_fault = retval;
756
757	return ((retval == 0) ? DDI_SUCCESS : DDI_FAILURE);
758}
759
760static void i2bsc_clear_acc_fault(i2bsc_t *i2c)
761{
762	i2bsc_trace(i2c, '@', "i2bsc_clear_acc_fault", "clearing acc fault");
763	ddi_put32(i2c->bscbus_handle,
764	    (uint32_t *)I2BSC_NEXUS_ADDR(i2c, EBUS_CMD_SPACE_GENERIC,
765	    LOMBUS_FAULT_REG), 0);
766}
767
768static void
769i2bsc_start_session(i2bsc_t *i2c)
770{
771	i2bsc_trace(i2c, 'S', "i2bsc_start_session", "session started");
772	i2c->bscbus_session_failure = 0;
773}
774
775static void
776i2bsc_fail_session(i2bsc_t *i2c)
777{
778	i2bsc_trace(i2c, 'S', "i2bsc_fail_session", "session failed");
779	i2c->bscbus_session_failure = 1;
780}
781
782static int
783i2bsc_end_session(i2bsc_t *i2c)
784{
785	/*
786	 * The ONLY way to get the session status is to end the session.
787	 * If clients of the session interface ever wanted the status mid-way
788	 * then they are really working with multiple contigious sessions.
789	 */
790	i2bsc_trace(i2c, 'S', "i2bsc_end_session", "session ended with %d",
791	    i2c->bscbus_session_failure);
792	return ((i2c->bscbus_session_failure) ? DDI_FAILURE : DDI_SUCCESS);
793}
794
795static boolean_t
796i2bsc_is_firmware_broken(i2bsc_t *i2c)
797{
798	int i;
799	int niterations = I2BSC_SHORT_RETRY_LIMIT;
800
801	i2bsc_trace(i2c, 'A', "i2bsc_is_firmware_broken", "called");
802
803	for (i = 0; i < niterations; i++) {
804		(void) ddi_get8(i2c->bscbus_handle,
805		    I2BSC_NEXUS_ADDR(i2c, EBUS_CMD_SPACE_I2C,
806		    EBUS_IDX12_RESULT));
807		if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS) {
808			i2bsc_clear_acc_fault(i2c);
809			continue;
810		} else {
811			/*
812			 * Firmware communication succeeded.
813			 */
814			i2bsc_trace(i2c, 'A', "i2bsc_is_firmware_broken",
815			    "firmware communications okay");
816			return (B_FALSE);
817		}
818	}
819
820	/*
821	 * Firmware is not communicative.  Some possible causes :
822	 *	Broken hardware
823	 *	BSC held in reset
824	 *	Corrupt BSC image
825	 *	OBP incompatiblity preventing drivers loading properly
826	 */
827	i2bsc_trace(i2c, 'A', "i2bsc_is_firmware_broken", "%d read fails",
828	    niterations);
829	return (B_TRUE);
830}
831
832static void
833i2bsc_put8(i2bsc_t *i2c, uint8_t space, uint8_t index, uint8_t value)
834{
835	int retryable = I2BSC_RETRY_LIMIT;
836
837	i2bsc_trace(i2c, '@', "i2bsc_put8", "(space,index)<-val (%d,%d)<-%d",
838	    space, index, value);
839
840	i2bsc_clear_acc_fault(i2c);
841
842	/*
843	 * If a session failure has already occurred, reduce the level of
844	 * retries to a minimum.  This is a optimization of the failure
845	 * recovery strategy.
846	 */
847	if (i2c->bscbus_session_failure)
848		retryable = 1;
849
850	while (retryable--) {
851		ddi_put8(i2c->bscbus_handle,
852		    I2BSC_NEXUS_ADDR(i2c, space, index), value);
853		if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS) {
854			i2bsc_clear_acc_fault(i2c);
855		} else
856			break;
857	}
858
859	if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS)
860		i2bsc_fail_session(i2c);
861
862	i2bsc_trace(i2c, '@', "i2bsc_put8", "tried %d time(s)",
863	    I2BSC_RETRY_LIMIT - retryable);
864}
865
866static uint8_t
867i2bsc_get8(i2bsc_t *i2c, uint8_t space, uint8_t index)
868{
869	uint8_t value;
870	int retryable = I2BSC_RETRY_LIMIT;
871
872	i2bsc_clear_acc_fault(i2c);
873
874	/*
875	 * If a session failure has already occurred, reduce the level of
876	 * retries to a minimum.  This is a optimization of the failure
877	 * recovery strategy.
878	 */
879	if (i2c->bscbus_session_failure)
880		retryable = 1;
881
882	while (retryable--) {
883		value = ddi_get8(i2c->bscbus_handle,
884		    I2BSC_NEXUS_ADDR(i2c, space, index));
885		if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS) {
886			i2bsc_clear_acc_fault(i2c);
887		} else
888			break;
889	}
890
891	if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS)
892		i2bsc_fail_session(i2c);
893
894	i2bsc_trace(i2c, '@', "i2bsc_get8", "tried %d time(s)",
895	    I2BSC_RETRY_LIMIT - retryable);
896
897	i2bsc_trace(i2c, '@', "i2bsc_get8", "(space,index)->val (%d,%d)->%d",
898	    space, index, value);
899	return (value);
900}
901
902static void
903i2bsc_put8_once(i2bsc_t *i2c, uint8_t space, uint8_t index, uint8_t value)
904{
905	i2bsc_trace(i2c, '@', "i2bsc_put8_once",
906	    "(space,index)<-val (%d,%d)<-%d", space, index, value);
907
908	i2bsc_clear_acc_fault(i2c);
909
910	ddi_put8(i2c->bscbus_handle,
911	    I2BSC_NEXUS_ADDR(i2c, space, index), value);
912
913	if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS)
914		i2bsc_fail_session(i2c);
915}
916
917static uint8_t
918i2bsc_get8_once(i2bsc_t *i2c, uint8_t space, uint8_t index)
919{
920	uint8_t value;
921
922	i2bsc_clear_acc_fault(i2c);
923
924	value = ddi_get8(i2c->bscbus_handle,
925	    I2BSC_NEXUS_ADDR(i2c, space, index));
926
927	if (i2bsc_bscbus_state(i2c) != DDI_SUCCESS)
928		i2bsc_fail_session(i2c);
929
930	i2bsc_trace(i2c, '@', "i2bsc_get8_once",
931	    "(space,index)->val (%d,%d)->%d", space, index, value);
932
933	return (value);
934}
935
936static int
937i2bsc_notify_max_transfer_size(i2bsc_t *i2c)
938{
939	/*
940	 * If the underlying hardware does not support the i2c service and
941	 * we are not running in fake_mode, then we cannot set the
942	 * MAX_TRANSFER_SZ.
943	 */
944	if (i2c->i2c_proxy_support == 0)
945		return (DDI_FAILURE);
946
947	i2bsc_start_session(i2c);
948
949	i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_MAX_TRANSFER_SZ,
950	    I2BSC_MAX_TRANSFER_SZ);
951
952	if (i2bsc_end_session(i2c) != DDI_SUCCESS)
953		return (DDI_FAILURE);
954
955	return (DDI_SUCCESS);
956}
957
958/*
959 * Discover if the microcontroller implements the I2C Proxy Service this
960 * driver requires.  If it does not, i2c transactions will abort with
961 * I2C_FAILURE, unless fake_mode is being used.
962 */
963static int
964i2bsc_discover_capability(i2bsc_t *i2c)
965{
966	i2bsc_start_session(i2c);
967
968	i2c->i2c_proxy_support = i2bsc_get8(i2c, EBUS_CMD_SPACE_GENERIC,
969	    EBUS_IDX_CAP0);
970	i2c->i2c_proxy_support &= EBUS_CAP0_I2C_PROXY;
971
972	if (i2bsc_end_session(i2c) != DDI_SUCCESS)
973		return (DDI_FAILURE);
974
975	return (DDI_SUCCESS);
976}
977
978static int
979i2bsc_upload_preamble(i2bsc_t *i2c, i2c_transfer_t *tp)
980{
981	i2bsc_ppvt_t *ppvt;
982	int wr_rd;
983
984	ppvt = ddi_get_parent_data(i2c->i2bsc_cur_dip);
985
986	/* Get a lock on the i2c devices owned by the microcontroller */
987	i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_TRANSACTION_LOCK, 1);
988	if (!i2bsc_get8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_TRANSACTION_LOCK)) {
989		/*
990		 * i2c client driver must timeout retry, NOT this nexus
991		 */
992		tp->i2c_result = I2C_INCOMPLETE;
993		i2bsc_trace(i2c, 'U', "i2bsc_upload_preamble",
994		    "Couldn't get transaction lock");
995		return (tp->i2c_result);
996	}
997
998	i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_BUS_ADDRESS,
999	    ppvt->i2bsc_ppvt_bus);
1000
1001	/*
1002	 * The Solaris architecture for I2C uses 10-bit I2C addresses where
1003	 * bit-0 is zero (the read/write bit).  The microcontroller uses 7 bit
1004	 * I2C addresses (read/write bit excluded).  Hence we need to convert
1005	 * the address by bit-shifting.
1006	 */
1007	i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_CLIENT_ADDRESS,
1008	    ppvt->i2bsc_ppvt_addr >> 1);
1009
1010	i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_TRANSFER_TYPE,
1011	    tp->i2c_flags);
1012
1013	/*
1014	 * We have only one register used for data input and output.  When
1015	 * a WR_RD is issued, this means we want to do a Random-Access-Read.
1016	 * First a series of bytes are written which define the address to
1017	 * read from.  In hardware this sets an address pointer.  Then a series
1018	 * of bytes are read.  The read/write boundary tells you how many
1019	 * bytes are to be written before reads will be issued.
1020	 */
1021	if (tp->i2c_flags == I2C_WR_RD)
1022		wr_rd = tp->i2c_wlen;
1023	else
1024		wr_rd = 0;
1025
1026	i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_WR_RD_BOUNDARY, wr_rd);
1027
1028	return (I2C_SUCCESS);
1029}
1030
1031/*
1032 * Function	i2bsc_upload
1033 *
1034 * Description	This function runs the i2c transfer protocol down to the
1035 *		microcontroller.  Its goal is to be as reliable as possible.
1036 *		This is achieved by making all the state-less aspects
1037 *		re-tryable.  For stateful aspects, we take care to ensure the
1038 *		counters are decremented only when data transfer has been
1039 *		successful.
1040 */
1041static int
1042i2bsc_upload(i2bsc_t *i2c, i2c_transfer_t *tp)
1043{
1044	int quota = I2BSC_MAX_TRANSFER_SZ;
1045	uint8_t res;
1046	int residual;
1047
1048	/*
1049	 * Total amount of data outstanding
1050	 */
1051	residual = tp->i2c_w_resid + tp->i2c_r_resid;
1052
1053	/*
1054	 * Anything in this session *could* be re-tried without side-effects.
1055	 * Therefore, error exit codes are I2C_INCOMPLETE rather than
1056	 * I2C_FAILURE.
1057	 */
1058	i2bsc_start_session(i2c);
1059	if (i2bsc_upload_preamble(i2c, tp) != I2C_SUCCESS)
1060		return (I2C_INCOMPLETE);
1061	if (i2bsc_end_session(i2c) != DDI_SUCCESS)
1062		return (I2C_INCOMPLETE);
1063
1064	/* The writes done here are not retryable */
1065	while (tp->i2c_w_resid && quota) {
1066		i2bsc_put8_once(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_DATA_INOUT,
1067		    tp->i2c_wbuf[tp->i2c_wlen - tp->i2c_w_resid]);
1068		if (i2bsc_bscbus_state(i2c) == DDI_SUCCESS) {
1069			tp->i2c_w_resid--;
1070			quota--;
1071			residual--;
1072		} else {
1073			i2bsc_trace(i2c, 'T', "i2bsc_upload", "write failed");
1074			return (tp->i2c_result = I2C_INCOMPLETE);
1075		}
1076	}
1077
1078	/* The reads done here are not retryable */
1079	while (tp->i2c_r_resid && quota) {
1080		tp->i2c_rbuf[tp->i2c_rlen - tp->i2c_r_resid] =
1081		    i2bsc_get8_once(i2c, EBUS_CMD_SPACE_I2C,
1082		    EBUS_IDX12_DATA_INOUT);
1083		if (i2bsc_bscbus_state(i2c) == DDI_SUCCESS) {
1084			tp->i2c_r_resid--;
1085			quota--;
1086			residual--;
1087		} else {
1088			i2bsc_trace(i2c, 'T', "i2bsc_upload", "read failed");
1089			return (tp->i2c_result = I2C_INCOMPLETE);
1090		}
1091	}
1092
1093	i2bsc_start_session(i2c);
1094
1095	/*
1096	 * A possible future enhancement would be to allow early breakout of the
1097	 * loops seen above.  In such circumstances, "residual" would be non-
1098	 * zero.  This may be useful if we want to support the interruption of
1099	 * transfer part way through an i2c_transfer_t.
1100	 */
1101	i2bsc_put8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_RESIDUAL_DATA, residual);
1102	res = i2bsc_get8(i2c, EBUS_CMD_SPACE_I2C, EBUS_IDX12_RESULT);
1103	if (i2bsc_end_session(i2c) != DDI_SUCCESS)
1104		return (tp->i2c_result = I2C_INCOMPLETE);
1105
1106	switch (res) {
1107	    case EBUS_I2C_SUCCESS:
1108		tp->i2c_result = I2C_SUCCESS;
1109		break;
1110	    case EBUS_I2C_FAILURE:
1111		/*
1112		 * This is rare but possible.  A retry may still fix this
1113		 * so lets allow that by returning I2C_INCOMPLETE.
1114		 * "hifTxRing still contains 1 bytes" is reported by the
1115		 * microcontroller when this return value is seen.
1116		 */
1117		i2bsc_trace(i2c, 'T', "i2bsc_upload", "EBUS_I2C_FAILURE"
1118		    " but returning I2C_INCOMPLETE for possible re-try");
1119		tp->i2c_result = I2C_INCOMPLETE;
1120		break;
1121	    case EBUS_I2C_INCOMPLETE:
1122		tp->i2c_result = I2C_INCOMPLETE;
1123		break;
1124	    default:
1125		tp->i2c_result = I2C_FAILURE;
1126	}
1127
1128	return (tp->i2c_result);
1129}
1130
1131/*
1132 * Function	i2bsc_safe_upload
1133 *
1134 * Description	This function is called "safe"-upload because it attempts to
1135 *		do transaction re-tries for cases where state is not spoiled
1136 *		by a transaction-level retry.
1137 */
1138static int
1139i2bsc_safe_upload(i2bsc_t *i2c, i2c_transfer_t *tp)
1140{
1141	int retryable = I2BSC_RETRY_LIMIT;
1142	int result;
1143
1144	i2bsc_trace(i2c, 'T', "i2bsc_safe_upload", "Transaction %s",
1145	    (tp->i2c_flags == I2C_WR_RD) ? "retryable" : "single-shot");
1146
1147	/*
1148	 * The only re-tryable transaction type is I2C_WR_RD.  If we don't
1149	 * have this we can only use session-based recovery offered by
1150	 * i2bsc_upload.
1151	 */
1152	if (tp->i2c_flags != I2C_WR_RD)
1153		return (i2bsc_upload(i2c, tp));
1154
1155	while (retryable--) {
1156		result = i2bsc_upload(i2c, tp);
1157		if (result == I2C_INCOMPLETE) {
1158			/* Have another go */
1159			tp->i2c_r_resid = tp->i2c_rlen;
1160			tp->i2c_w_resid = tp->i2c_wlen;
1161			tp->i2c_result = I2C_SUCCESS;
1162			i2bsc_trace(i2c, 'T', "i2bsc_safe_upload",
1163			    "Retried (%d)", I2BSC_RETRY_LIMIT - retryable);
1164			continue;
1165		} else {
1166			i2bsc_trace(i2c, 'T', "i2bsc_safe_upload",
1167			    "Exiting while loop on result %d", result);
1168			return (result);
1169		}
1170	}
1171
1172	i2bsc_trace(i2c, 'T', "i2bsc_safe_upload", "Exiting on %d", result);
1173	return (result);
1174}
1175
1176/*
1177 * Function	i2bsc_transfer
1178 *
1179 * Description	This is the entry-point that clients use via the Solaris i2c
1180 *		framework.  It kicks off the servicing of i2c transfer requests.
1181 */
1182int
1183i2bsc_transfer(dev_info_t *dip, i2c_transfer_t *tp)
1184{
1185	i2bsc_t *i2c;
1186
1187	i2c = (i2bsc_t *)ddi_get_soft_state(i2bsc_state,
1188		ddi_get_instance(ddi_get_parent(dip)));
1189
1190	i2bsc_acquire(i2c, dip, tp);
1191
1192	tp->i2c_r_resid = tp->i2c_rlen;
1193	tp->i2c_w_resid = tp->i2c_wlen;
1194	tp->i2c_result = I2C_SUCCESS;
1195
1196	i2bsc_trace(i2c, 'T', "i2bsc_transfer", "Transaction i2c_version/flags"
1197	    " %d/%d", tp->i2c_version, tp->i2c_flags);
1198	i2bsc_trace(i2c, 'T', "i2bsc_transfer", "Transaction buffer rlen/wlen"
1199	    " %d/%d", tp->i2c_rlen, tp->i2c_wlen);
1200	i2bsc_trace(i2c, 'T', "i2bsc_transfer", "Transaction ptrs wbuf/rbuf"
1201	    " %p/%p", tp->i2c_wbuf, tp->i2c_rbuf);
1202
1203	if (i2c->i2c_proxy_support)
1204		(void) i2bsc_safe_upload(i2c, tp);
1205	else
1206		tp->i2c_result = I2C_FAILURE;
1207
1208	i2bsc_trace(i2c, 'T', "i2bsc_transfer", "Residual writes/reads"
1209	    " %d/%d", tp->i2c_w_resid, tp->i2c_r_resid);
1210	i2bsc_trace(i2c, 'T', "i2bsc_transfer", "i2c_result"
1211	    " %d", tp->i2c_result);
1212
1213	i2bsc_release(i2c);
1214
1215	return (tp->i2c_result);
1216}
1217
1218/*
1219 *  General utility routines ...
1220 */
1221
1222#ifdef DEBUG
1223
1224static void
1225i2bsc_trace(i2bsc_t *ssp, char code, const char *caller,
1226	const char *fmt, ...)
1227{
1228	char buf[256];
1229	char *p;
1230	va_list va;
1231
1232	if (ssp->debug & (1 << (code-'@'))) {
1233		p = buf;
1234		(void) snprintf(p, sizeof (buf) - (p - buf),
1235			"%s/%s: ", ssp->i2bsc_name, caller);
1236		p += strlen(p);
1237
1238		va_start(va, fmt);
1239		(void) vsnprintf(p, sizeof (buf) - (p - buf), fmt, va);
1240		va_end(va);
1241
1242		buf[sizeof (buf) - 1] = '\0';
1243		(void) strlog(ssp->majornum, ssp->minornum, code, SL_TRACE,
1244		    buf);
1245	}
1246}
1247
1248#else /* DEBUG */
1249
1250_NOTE(ARGSUSED(0))
1251static void
1252i2bsc_trace(i2bsc_t *ssp, char code, const char *caller,
1253	const char *fmt, ...)
1254{
1255}
1256
1257#endif /* DEBUG */
1258