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, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#pragma ident	"%Z%%M%	%I%	%E% SMI"
28
29/*
30 * This is the PCMCIA Card Services kernel stubs module. It provides
31 *	the various PCMCIA kernel framework entry points.
32 */
33
34#if defined(DEBUG)
35#define	CS_STUBS_DEBUG
36#endif
37
38#include <sys/types.h>
39#include <sys/systm.h>
40#include <sys/user.h>
41#include <sys/buf.h>
42#include <sys/file.h>
43#include <sys/uio.h>
44#include <sys/conf.h>
45#include <sys/stat.h>
46#include <sys/autoconf.h>
47#include <sys/vtoc.h>
48#include <sys/dkio.h>
49#include <sys/ddi.h>
50#include <sys/sunddi.h>
51#include <sys/debug.h>
52#include <sys/varargs.h>
53#include <sys/var.h>
54#include <sys/proc.h>
55#include <sys/thread.h>
56#include <sys/utsname.h>
57#include <sys/vtrace.h>
58#include <sys/kstat.h>
59#include <sys/kmem.h>
60#include <sys/modctl.h>
61#include <sys/kobj.h>
62#include <sys/callb.h>
63
64#include <sys/pctypes.h>
65#include <pcmcia/sys/cs_types.h>
66#include <sys/pcmcia.h>
67#include <sys/sservice.h>
68#include <pcmcia/sys/cis.h>
69#include <pcmcia/sys/cis_handlers.h>
70#include <pcmcia/sys/cs.h>
71#include <pcmcia/sys/cs_priv.h>
72#include <pcmcia/sys/cs_stubs.h>
73
74#ifdef	CS_STUBS_DEBUG
75int cs_stubs_debug = 0;
76#endif
77
78static csfunction_t *cardservices = NULL;
79static int do_cs_call = 0;
80static int cs_no_carservices(void);
81
82#define	CardServices	(do_cs_call ? (*cardservices) :		\
83			((csfunction_t *)cs_no_carservices))
84
85#ifdef	USE_CS_STUBS_MODULE
86
87/*
88 * Module linkage information for the kernel.
89 */
90static struct modlmisc modlmisc = {
91	&mod_miscops,
92	"PCMCIA Card Services stub module"
93};
94
95static struct modlinkage modlinkage = {
96	MODREV_1,
97	(void *)&modlmisc,
98	NULL
99};
100
101int
102_init(void)
103{
104	return (mod_install(&modlinkage));
105}
106
107int
108_fini(void)
109{
110	if (!do_cs_call)
111	    return (mod_remove(&modlinkage));
112	else
113	    return (EBUSY);
114}
115
116int
117_info(struct modinfo *modinfop)
118{
119	return (mod_info(&modlinkage, modinfop));
120}
121#endif	/* USE_CS_STUBS_MODULE */
122
123/*
124 * csx_register_cardservices - The Card Services loadable module
125 *	calls this runction to register it's entry point.
126 *
127 * Returns:	CS_SUCCESS - if operation sucessful
128 *		CS_UNSUPPORTED_FUNCTION - if invalid function code
129 *		CS_BAD_HANDLE - if Card Services is not registered
130 */
131int32_t
132csx_register_cardservices(cs_register_cardservices_t *rcs)
133{
134#ifdef	CS_STUBS_DEBUG
135	if (cs_stubs_debug > 2)
136	    cmn_err(CE_CONT, "csx_register_cardservices: "
137		"magic: 0x%x function: 0x%x cardservices: 0x%p\n",
138		rcs->magic, rcs->function, (void *)rcs->cardservices);
139#endif
140
141	if (rcs->magic != CS_STUBS_MAGIC)
142	    return (CS_BAD_ARGS);
143
144	switch (rcs->function) {
145	    case CS_ENTRY_REGISTER:
146		cardservices = rcs->cardservices;
147		do_cs_call = 1;
148#ifdef	CS_STUBS_DEBUG
149	if (cs_stubs_debug > 2)
150	    cmn_err(CE_CONT, "csx_register_cardservices: CS_ENTRY_REGISTER\n");
151#endif
152
153		return (CS_SUCCESS);
154
155	    case CS_ENTRY_DEREGISTER:
156		do_cs_call = 0;
157		cardservices = (csfunction_t *)cs_no_carservices;
158#ifdef	CS_STUBS_DEBUG
159	if (cs_stubs_debug > 2)
160	    cmn_err(CE_CONT,
161		"csx_register_cardservices: CS_ENTRY_DEREGISTER\n");
162#endif
163		return (CS_UNSUPPORTED_FUNCTION);
164
165	    case CS_ENTRY_INQUIRE:
166		rcs->cardservices = cardservices;
167#ifdef	CS_STUBS_DEBUG
168	if (cs_stubs_debug > 2)
169	    cmn_err(CE_CONT, "csx_register_cardservices: CS_ENTRY_INQUIRE\n");
170#endif
171
172		if (do_cs_call)
173		    return (CS_SUCCESS);
174		else
175		    return (CS_BAD_HANDLE);
176
177	    default:
178#ifdef	CS_STUBS_DEBUG
179	if (cs_stubs_debug > 2)
180	    cmn_err(CE_CONT, "csx_register_cardservices: (unknown function)\n");
181#endif
182		return (CS_UNSUPPORTED_FUNCTION);
183	}
184
185}
186
187int32_t
188csx_RegisterClient(client_handle_t *ch, client_reg_t *cr)
189{
190#ifdef	CS_STUBS_DEBUG
191	if (cs_stubs_debug > 3)
192	    cmn_err(CE_CONT, "csx_RegisterClient: (no handle yet)\n");
193#endif
194	return (CardServices(RegisterClient, ch, cr));
195}
196
197int32_t
198csx_DeregisterClient(client_handle_t ch)
199{
200#ifdef	CS_STUBS_DEBUG
201	if (cs_stubs_debug > 3)
202	    cmn_err(CE_CONT, "csx_DeregisterClient: handle: 0x%x\n", ch);
203#endif
204	return (CardServices(DeregisterClient, ch));
205}
206
207int32_t
208csx_GetStatus(client_handle_t ch, get_status_t *gs)
209{
210#ifdef	CS_STUBS_DEBUG
211	if (cs_stubs_debug > 3)
212	    cmn_err(CE_CONT, "csx_GetStatus: handle: 0x%x\n", ch);
213#endif
214	return (CardServices(GetStatus, ch, gs));
215}
216
217int32_t
218csx_SetEventMask(client_handle_t ch, sockevent_t *se)
219{
220#ifdef	CS_STUBS_DEBUG
221	if (cs_stubs_debug > 3)
222	    cmn_err(CE_CONT, "csx_SetEventMask: handle: 0x%x\n", ch);
223#endif
224	return (CardServices(SetEventMask, ch, se));
225}
226
227int32_t
228csx_GetEventMask(client_handle_t ch, sockevent_t *se)
229{
230#ifdef	CS_STUBS_DEBUG
231	if (cs_stubs_debug > 3)
232	    cmn_err(CE_CONT, "csx_GetEventMask: handle: 0x%x\n", ch);
233#endif
234	return (CardServices(GetEventMask, ch, se));
235}
236
237int32_t
238csx_RequestIO(client_handle_t ch, io_req_t *ior)
239{
240#ifdef	CS_STUBS_DEBUG
241	if (cs_stubs_debug > 3)
242	    cmn_err(CE_CONT, "csx_RequestIO: handle: 0x%x\n", ch);
243#endif
244	return (CardServices(RequestIO, ch, ior));
245}
246
247int32_t
248csx_ReleaseIO(client_handle_t ch, io_req_t *ior)
249{
250#ifdef	CS_STUBS_DEBUG
251	if (cs_stubs_debug > 3)
252	    cmn_err(CE_CONT, "csx_ReleaseIO: handle: 0x%x\n", ch);
253#endif
254	return (CardServices(ReleaseIO, ch, ior));
255}
256
257int32_t
258csx_RequestIRQ(client_handle_t ch, irq_req_t *irqr)
259{
260#ifdef	CS_STUBS_DEBUG
261	if (cs_stubs_debug > 3)
262	    cmn_err(CE_CONT, "csx_RequestIRQ: handle: 0x%x\n", ch);
263#endif
264	return (CardServices(RequestIRQ, ch, irqr));
265}
266
267int32_t
268csx_ReleaseIRQ(client_handle_t ch, irq_req_t *irqr)
269{
270#ifdef	CS_STUBS_DEBUG
271	if (cs_stubs_debug > 3)
272	    cmn_err(CE_CONT, "csx_ReleaseIRQ: handle: 0x%x\n", ch);
273#endif
274	return (CardServices(ReleaseIRQ, ch, irqr));
275}
276
277int32_t
278csx_RequestWindow(client_handle_t ch, window_handle_t *wh, win_req_t *wr)
279{
280#ifdef	CS_STUBS_DEBUG
281	if (cs_stubs_debug > 3)
282	    cmn_err(CE_CONT, "csx_RequestWindow: handle: 0x%x\n", ch);
283#endif
284	return (CardServices(RequestWindow, ch, wh, wr));
285}
286
287int32_t
288csx_ReleaseWindow(window_handle_t wh)
289{
290#ifdef	CS_STUBS_DEBUG
291	if (cs_stubs_debug > 3)
292	    cmn_err(CE_CONT, "csx_ReleaseWindow: handle: 0x%x\n", wh);
293#endif
294	return (CardServices(ReleaseWindow, wh));
295}
296
297int32_t
298csx_ModifyWindow(window_handle_t wh, modify_win_t *mw)
299{
300#ifdef	CS_STUBS_DEBUG
301	if (cs_stubs_debug > 3)
302	    cmn_err(CE_CONT, "csx_ModifyWindow: handle: 0x%x\n", wh);
303#endif
304	return (CardServices(ModifyWindow, wh, mw));
305}
306
307int32_t
308csx_MapMemPage(window_handle_t wh, map_mem_page_t *mmp)
309{
310#ifdef	CS_STUBS_DEBUG
311	if (cs_stubs_debug > 3)
312	    cmn_err(CE_CONT, "csx_MapMemPage: handle: 0x%x\n", wh);
313#endif
314	return (CardServices(MapMemPage, wh, mmp));
315}
316
317int32_t
318csx_RequestSocketMask(client_handle_t ch, request_socket_mask_t *sm)
319{
320#ifdef	CS_STUBS_DEBUG
321	if (cs_stubs_debug > 3)
322	    cmn_err(CE_CONT, "csx_RequestSocketMask: handle: 0x%x\n", ch);
323#endif
324	return (CardServices(RequestSocketMask, ch, sm));
325}
326
327int32_t
328csx_ReleaseSocketMask(client_handle_t ch, release_socket_mask_t *rsm)
329{
330#ifdef	CS_STUBS_DEBUG
331	if (cs_stubs_debug > 3)
332	    cmn_err(CE_CONT, "csx_ReleaseSocketMask: handle: 0x%x\n", ch);
333#endif
334	return (CardServices(ReleaseSocketMask, ch, rsm));
335}
336
337int32_t
338csx_RequestConfiguration(client_handle_t ch, config_req_t *cr)
339{
340#ifdef	CS_STUBS_DEBUG
341	if (cs_stubs_debug > 3)
342	    cmn_err(CE_CONT, "csx_RequestConfiguration: handle: 0x%x\n", ch);
343#endif
344	return (CardServices(RequestConfiguration, ch, cr));
345}
346
347int32_t
348csx_ModifyConfiguration(client_handle_t ch, modify_config_t *mc)
349{
350#ifdef	CS_STUBS_DEBUG
351	if (cs_stubs_debug > 3)
352	    cmn_err(CE_CONT, "csx_ModifyConfiguration: handle: 0x%x\n", ch);
353#endif
354	return (CardServices(ModifyConfiguration, ch, mc));
355}
356
357int32_t
358csx_ReleaseConfiguration(client_handle_t ch, release_config_t *rc)
359{
360#ifdef	CS_STUBS_DEBUG
361	if (cs_stubs_debug > 3)
362	    cmn_err(CE_CONT, "csx_ReleaseConfiguration: handle: 0x%x\n", ch);
363#endif
364	return (CardServices(ReleaseConfiguration, ch, rc));
365}
366
367int32_t
368csx_AccessConfigurationRegister(client_handle_t ch, access_config_reg_t *acr)
369{
370#ifdef	CS_STUBS_DEBUG
371	if (cs_stubs_debug > 3)
372	    cmn_err(CE_CONT,
373		"csx_AccessConfigurationRegister: handle: 0x%x\n", ch);
374#endif
375	return (CardServices(AccessConfigurationRegister, ch, acr));
376}
377
378int32_t
379csx_GetFirstTuple(client_handle_t ch, tuple_t *tp)
380{
381#ifdef	CS_STUBS_DEBUG
382	if (cs_stubs_debug > 3)
383	    cmn_err(CE_CONT, "csx_GetFirstTuple: handle: 0x%x\n", ch);
384#endif
385	return (CardServices(GetFirstTuple, ch, tp));
386}
387
388int32_t
389csx_GetNextTuple(client_handle_t ch, tuple_t *tp)
390{
391#ifdef	CS_STUBS_DEBUG
392	if (cs_stubs_debug > 3)
393	    cmn_err(CE_CONT, "csx_GetNextTuple: handle: 0x%x\n", ch);
394#endif
395	return (CardServices(GetNextTuple, ch, tp));
396}
397
398int32_t
399csx_GetTupleData(client_handle_t ch, tuple_t *tp)
400{
401#ifdef	CS_STUBS_DEBUG
402	if (cs_stubs_debug > 3)
403	    cmn_err(CE_CONT, "csx_GetTupleData: handle: 0x%x\n", ch);
404#endif
405	return (CardServices(GetTupleData, ch, tp));
406}
407
408int32_t
409csx_MapLogSocket(client_handle_t ch, map_log_socket_t *mls)
410{
411#ifdef	CS_STUBS_DEBUG
412	if (cs_stubs_debug > 3)
413	    cmn_err(CE_CONT, "csx_MapLogSocket: handle: 0x%x\n", ch);
414#endif
415	return (CardServices(MapLogSocket, ch, mls));
416}
417
418int32_t
419csx_ValidateCIS(client_handle_t ch, cisinfo_t *ci)
420{
421#ifdef	CS_STUBS_DEBUG
422	if (cs_stubs_debug > 3)
423	    cmn_err(CE_CONT, "csx_ValidateCIS: handle: 0x%x\n", ch);
424#endif
425	return (CardServices(ValidateCIS, ch, ci));
426}
427
428int32_t
429csx_MakeDeviceNode(client_handle_t ch, make_device_node_t *mdn)
430{
431#ifdef	CS_STUBS_DEBUG
432	if (cs_stubs_debug > 3)
433	    cmn_err(CE_CONT, "csx_MakeDeviceNode: handle: 0x%x\n", ch);
434#endif
435	return (CardServices(MakeDeviceNode, ch, mdn));
436}
437
438int32_t
439csx_RemoveDeviceNode(client_handle_t ch, remove_device_node_t *rdn)
440{
441#ifdef	CS_STUBS_DEBUG
442	if (cs_stubs_debug > 3)
443	    cmn_err(CE_CONT, "csx_RemoveDeviceNode: handle: 0x%x\n", ch);
444#endif
445	return (CardServices(RemoveDeviceNode, ch, rdn));
446}
447
448int32_t
449csx_ConvertSpeed(convert_speed_t *cp)
450{
451#ifdef	CS_STUBS_DEBUG
452	if (cs_stubs_debug > 3)
453	    cmn_err(CE_CONT, "csx_ConvertSpeed\n");
454#endif
455	return (CardServices(ConvertSpeed, cp));
456}
457
458int32_t
459csx_ConvertSize(convert_size_t *cp)
460{
461#ifdef	CS_STUBS_DEBUG
462	if (cs_stubs_debug > 3)
463	    cmn_err(CE_CONT, "csx_ConvertSize\n");
464#endif
465	return (CardServices(ConvertSize, cp));
466}
467
468int32_t
469csx_Event2Text(event2text_t *e2t)
470{
471#ifdef	CS_STUBS_DEBUG
472	if (cs_stubs_debug > 3)
473	    cmn_err(CE_CONT, "csx_Event2Text\n");
474#endif
475	return (CardServices(Event2Text, e2t));
476}
477
478int32_t
479csx_Error2Text(error2text_t *e2t)
480{
481#ifdef	CS_STUBS_DEBUG
482	if (cs_stubs_debug > 3)
483	    cmn_err(CE_CONT, "csx_Error2Text\n");
484#endif
485	return (CardServices(Error2Text, e2t));
486}
487
488int32_t
489csx_CS_DDI_Info(cs_ddi_info_t *cp)
490{
491#ifdef	CS_STUBS_DEBUG
492	if (cs_stubs_debug > 3)
493	    cmn_err(CE_CONT, "csx_CS_DDI_Info\n");
494#endif
495	return (CardServices(CS_DDI_Info, cp));
496}
497
498int32_t
499csx_CS_Sys_Ctl(cs_sys_ctl_t *csc)
500{
501#ifdef	CS_STUBS_DEBUG
502	if (cs_stubs_debug > 3)
503	    cmn_err(CE_CONT, "csx_CS_Sys_Ctl\n");
504#endif
505	return (CardServices(CS_Sys_Ctl, csc));
506}
507
508int32_t
509csx_GetClientInfo(client_handle_t ch, client_info_t *ci)
510{
511#ifdef	CS_STUBS_DEBUG
512	if (cs_stubs_debug > 3)
513	    cmn_err(CE_CONT, "csx_GetClientInfo: handle: 0x%x\n", ch);
514#endif
515
516	return (CardServices(GetClientInfo, ch, ci));
517}
518
519int32_t
520csx_GetFirstClient(get_firstnext_client_t *fnc)
521{
522#ifdef	CS_STUBS_DEBUG
523	if (cs_stubs_debug > 3)
524	    cmn_err(CE_CONT, "csx_GetFirstClient\n");
525#endif
526
527	return (CardServices(GetFirstClient, fnc));
528}
529
530int32_t
531csx_GetNextClient(get_firstnext_client_t *fnc)
532{
533#ifdef	CS_STUBS_DEBUG
534	if (cs_stubs_debug > 3)
535	    cmn_err(CE_CONT, "csx_GetNextClient\n");
536#endif
537
538	return (CardServices(GetNextClient, fnc));
539}
540
541int32_t
542csx_ResetFunction(client_handle_t ch, reset_function_t *rf)
543{
544#ifdef	CS_STUBS_DEBUG
545	if (cs_stubs_debug > 3)
546	    cmn_err(CE_CONT, "csx_ResetFunction: handle: 0x%x\n", ch);
547#endif
548
549	return (CardServices(ResetFunction, ch, rf));
550}
551
552int32_t
553csx_GetCardServicesInfo(client_handle_t ch, get_cardservices_info_t *gcsi)
554{
555#ifdef	CS_STUBS_DEBUG
556	if (cs_stubs_debug > 3)
557	    cmn_err(CE_CONT, "csx_GetCardServicesInfo: handle: 0x%x\n", ch);
558#endif
559
560	return (CardServices(GetCardServicesInfo, ch, gcsi));
561}
562
563int32_t
564csx_GetConfigurationInfo(client_handle_t *ch, get_configuration_info_t *gci)
565{
566#ifdef	CS_STUBS_DEBUG
567	if (cs_stubs_debug > 3)
568	    cmn_err(CE_CONT, "csx_GetConfigurationInfo: "
569		"handle: (no handle yet)\n");
570#endif
571
572	return (CardServices(GetConfigurationInfo, ch, gci));
573}
574
575int32_t
576csx_GetPhysicalAdapterInfo(client_handle_t ch, get_physical_adapter_info_t *gp)
577{
578#ifdef	CS_STUBS_DEBUG
579	if (cs_stubs_debug > 3)
580	    cmn_err(CE_CONT, "csx_GetPhysicalAdapterInfo: handle: 0x%x\n", ch);
581#endif
582
583	return (CardServices(GetPhysicalAdapterInfo, ch, gp));
584}
585
586/*
587 * CIS tuple parsing functions - one entrypoint per tuple that we know
588 *	how to parse
589 */
590int32_t
591csx_Parse_CISTPL_CONFIG(client_handle_t ch, tuple_t *tp, cistpl_config_t *pt)
592{
593#ifdef	CS_STUBS_DEBUG
594	if (cs_stubs_debug > 3)
595	    cmn_err(CE_CONT, "csx_Parse_CISTPL_CONFIG: handle: 0x%x\n", ch);
596#endif
597	tp->DesiredTuple = CISTPL_CONFIG;
598	return (CardServices(ParseTuple, ch, tp, pt));
599}
600
601int32_t
602csx_Parse_CISTPL_DEVICE(client_handle_t ch, tuple_t *tp, cistpl_device_t *pt)
603{
604#ifdef	CS_STUBS_DEBUG
605	if (cs_stubs_debug > 3)
606	    cmn_err(CE_CONT, "csx_Parse_CISTPL_DEVICE: handle: 0x%x\n", ch);
607#endif
608	tp->DesiredTuple = CISTPL_DEVICE;
609	return (CardServices(ParseTuple, ch, tp, pt));
610}
611
612int32_t
613csx_Parse_CISTPL_DEVICE_A(client_handle_t ch, tuple_t *tp, cistpl_device_t *pt)
614{
615#ifdef	CS_STUBS_DEBUG
616	if (cs_stubs_debug > 3)
617	    cmn_err(CE_CONT, "csx_Parse_CISTPL_DEVICE_A: handle: 0x%x\n", ch);
618#endif
619	tp->DesiredTuple = CISTPL_DEVICE_A;
620	return (CardServices(ParseTuple, ch, tp, pt));
621}
622
623int32_t
624csx_Parse_CISTPL_DEVICE_OA(client_handle_t ch, tuple_t *tp, cistpl_device_t *pt)
625{
626#ifdef	CS_STUBS_DEBUG
627	if (cs_stubs_debug > 3)
628	    cmn_err(CE_CONT, "csx_Parse_CISTPL_DEVICE_OA: handle: 0x%x\n", ch);
629#endif
630	tp->DesiredTuple = CISTPL_DEVICE_OA;
631	return (CardServices(ParseTuple, ch, tp, pt));
632}
633
634int32_t
635csx_Parse_CISTPL_DEVICE_OC(client_handle_t ch, tuple_t *tp, cistpl_device_t *pt)
636{
637#ifdef	CS_STUBS_DEBUG
638	if (cs_stubs_debug > 3)
639	    cmn_err(CE_CONT, "csx_Parse_CISTPL_DEVICE_OC: handle: 0x%x\n", ch);
640#endif
641	tp->DesiredTuple = CISTPL_DEVICE_OC;
642	return (CardServices(ParseTuple, ch, tp, pt));
643}
644
645int32_t
646csx_Parse_CISTPL_VERS_1(client_handle_t ch, tuple_t *tp, cistpl_vers_1_t *pt)
647{
648#ifdef	CS_STUBS_DEBUG
649	if (cs_stubs_debug > 3)
650	    cmn_err(CE_CONT, "csx_Parse_CISTPL_VERS_1: handle: 0x%x\n", ch);
651#endif
652	tp->DesiredTuple = CISTPL_VERS_1;
653	return (CardServices(ParseTuple, ch, tp, pt));
654}
655
656int32_t
657csx_Parse_CISTPL_VERS_2(client_handle_t ch, tuple_t *tp, cistpl_vers_2_t *pt)
658{
659#ifdef	CS_STUBS_DEBUG
660	if (cs_stubs_debug > 3)
661	    cmn_err(CE_CONT, "csx_Parse_CISTPL_VERS_2: handle: 0x%x\n", ch);
662#endif
663	tp->DesiredTuple = CISTPL_VERS_2;
664	return (CardServices(ParseTuple, ch, tp, pt));
665}
666
667int32_t
668csx_Parse_CISTPL_JEDEC_A(client_handle_t ch, tuple_t *tp, cistpl_jedec_t *pt)
669{
670#ifdef	CS_STUBS_DEBUG
671	if (cs_stubs_debug > 3)
672	    cmn_err(CE_CONT, "csx_Parse_CISTPL_JEDEC_A: handle: 0x%x\n", ch);
673#endif
674	tp->DesiredTuple = CISTPL_JEDEC_A;
675	return (CardServices(ParseTuple, ch, tp, pt));
676}
677
678int32_t
679csx_Parse_CISTPL_JEDEC_C(client_handle_t ch, tuple_t *tp, cistpl_jedec_t *pt)
680{
681#ifdef	CS_STUBS_DEBUG
682	if (cs_stubs_debug > 3)
683	    cmn_err(CE_CONT, "csx_Parse_CISTPL_JEDEC_C: handle: 0x%x\n", ch);
684#endif
685	tp->DesiredTuple = CISTPL_JEDEC_C;
686	return (CardServices(ParseTuple, ch, tp, pt));
687}
688
689int32_t
690csx_Parse_CISTPL_FORMAT(client_handle_t ch, tuple_t *tp, cistpl_format_t *pt)
691{
692#ifdef	CS_STUBS_DEBUG
693	if (cs_stubs_debug > 3)
694	    cmn_err(CE_CONT, "csx_Parse_CISTPL_FORMAT: handle: 0x%x\n", ch);
695#endif
696	tp->DesiredTuple = CISTPL_FORMAT;
697	return (CardServices(ParseTuple, ch, tp, pt));
698}
699
700int32_t
701csx_Parse_CISTPL_FORMAT_A(client_handle_t ch, tuple_t *tp, cistpl_format_t *pt)
702{
703#ifdef	CS_STUBS_DEBUG
704	if (cs_stubs_debug > 3)
705	    cmn_err(CE_CONT, "csx_Parse_CISTPL_FORMAT_A: handle: 0x%x\n", ch);
706#endif
707	tp->DesiredTuple = CISTPL_FORMAT_A;
708	return (CardServices(ParseTuple, ch, tp, pt));
709}
710
711int32_t
712csx_Parse_CISTPL_GEOMETRY(client_handle_t ch, tuple_t *tp,
713    cistpl_geometry_t *pt)
714{
715#ifdef	CS_STUBS_DEBUG
716	if (cs_stubs_debug > 3)
717	    cmn_err(CE_CONT, "csx_Parse_CISTPL_GEOMETRY: handle: 0x%x\n", ch);
718#endif
719	tp->DesiredTuple = CISTPL_GEOMETRY;
720	return (CardServices(ParseTuple, ch, tp, pt));
721}
722
723int32_t
724csx_Parse_CISTPL_BYTEORDER(client_handle_t ch, tuple_t *tp,
725    cistpl_byteorder_t *pt)
726{
727#ifdef	CS_STUBS_DEBUG
728	if (cs_stubs_debug > 3)
729	    cmn_err(CE_CONT, "csx_Parse_CISTPL_BYTEORDER: handle: 0x%x\n", ch);
730#endif
731	tp->DesiredTuple = CISTPL_BYTEORDER;
732	return (CardServices(ParseTuple, ch, tp, pt));
733}
734
735int32_t
736csx_Parse_CISTPL_DATE(client_handle_t ch, tuple_t *tp, cistpl_date_t *pt)
737{
738#ifdef	CS_STUBS_DEBUG
739	if (cs_stubs_debug > 3)
740	    cmn_err(CE_CONT, "csx_Parse_CISTPL_DATE: handle: 0x%x\n", ch);
741#endif
742	tp->DesiredTuple = CISTPL_DATE;
743	return (CardServices(ParseTuple, ch, tp, pt));
744}
745
746int32_t
747csx_Parse_CISTPL_BATTERY(client_handle_t ch, tuple_t *tp, cistpl_battery_t *pt)
748{
749#ifdef	CS_STUBS_DEBUG
750	if (cs_stubs_debug > 3)
751	    cmn_err(CE_CONT, "csx_Parse_CISTPL_BATTERY: handle: 0x%x\n", ch);
752#endif
753	tp->DesiredTuple = CISTPL_BATTERY;
754	return (CardServices(ParseTuple, ch, tp, pt));
755}
756
757int32_t
758csx_Parse_CISTPL_ORG(client_handle_t ch, tuple_t *tp, cistpl_org_t *pt)
759{
760#ifdef	CS_STUBS_DEBUG
761	if (cs_stubs_debug > 3)
762	    cmn_err(CE_CONT, "csx_Parse_CISTPL_ORG: handle: 0x%x\n", ch);
763#endif
764	tp->DesiredTuple = CISTPL_ORG;
765	return (CardServices(ParseTuple, ch, tp, pt));
766}
767
768int32_t
769csx_Parse_CISTPL_MANFID(client_handle_t ch, tuple_t *tp, cistpl_manfid_t *pt)
770{
771#ifdef	CS_STUBS_DEBUG
772	if (cs_stubs_debug > 3)
773	    cmn_err(CE_CONT, "csx_Parse_CISTPL_MANFID: handle: 0x%x\n", ch);
774#endif
775	tp->DesiredTuple = CISTPL_MANFID;
776	return (CardServices(ParseTuple, ch, tp, pt));
777}
778
779int32_t
780csx_Parse_CISTPL_FUNCID(client_handle_t ch, tuple_t *tp, cistpl_funcid_t *pt)
781{
782#ifdef	CS_STUBS_DEBUG
783	if (cs_stubs_debug > 3)
784	    cmn_err(CE_CONT, "csx_Parse_CISTPL_FUNCID: handle: 0x%x\n", ch);
785#endif
786	tp->DesiredTuple = CISTPL_FUNCID;
787	return (CardServices(ParseTuple, ch, tp, pt));
788}
789
790int32_t
791csx_Parse_CISTPL_FUNCE(client_handle_t ch, tuple_t *tp,
792    cistpl_funce_t *pt, uint32_t function)
793{
794#ifdef	CS_STUBS_DEBUG
795	if (cs_stubs_debug > 3)
796	    cmn_err(CE_CONT, "csx_Parse_CISTPL_FUNCE: handle: 0x%x\n", ch);
797#endif
798	tp->DesiredTuple = CISTPL_FUNCE;
799	return (CardServices(ParseTuple, ch, tp, pt, function));
800}
801
802int32_t
803csx_Parse_CISTPL_CFTABLE_ENTRY(client_handle_t ch, tuple_t *tp,
804    cistpl_cftable_entry_t *pt)
805{
806#ifdef	CS_STUBS_DEBUG
807	if (cs_stubs_debug > 3)
808	    cmn_err(CE_CONT,
809		"csx_Parse_CISTPL_CFTABLE_ENTRY: handle: 0x%x\n", ch);
810#endif
811	tp->DesiredTuple = CISTPL_CFTABLE_ENTRY;
812	return (CardServices(ParseTuple, ch, tp, pt));
813}
814
815int32_t
816csx_Parse_CISTPL_LINKTARGET(client_handle_t ch, tuple_t *tp,
817    cistpl_linktarget_t *pt)
818{
819#ifdef	CS_STUBS_DEBUG
820	if (cs_stubs_debug > 3)
821	    cmn_err(CE_CONT, "csx_Parse_CISTPL_LINKTARGET: handle: 0x%x\n", ch);
822#endif
823	tp->DesiredTuple = CISTPL_LINKTARGET;
824	return (CardServices(ParseTuple, ch, tp, pt));
825}
826
827int32_t
828csx_Parse_CISTPL_LONGLINK_A(client_handle_t ch, tuple_t *tp,
829    cistpl_longlink_ac_t *pt)
830{
831#ifdef	CS_STUBS_DEBUG
832	if (cs_stubs_debug > 3)
833	    cmn_err(CE_CONT, "csx_Parse_CISTPL_LONGLINK_A: handle: 0x%x\n", ch);
834#endif
835	tp->DesiredTuple = CISTPL_LONGLINK_A;
836	return (CardServices(ParseTuple, ch, tp, pt));
837}
838
839int32_t
840csx_Parse_CISTPL_LONGLINK_C(client_handle_t ch, tuple_t *tp,
841    cistpl_longlink_ac_t *pt)
842{
843#ifdef	CS_STUBS_DEBUG
844	if (cs_stubs_debug > 3)
845	    cmn_err(CE_CONT, "csx_Parse_CISTPL_LONGLINK_C: handle: 0x%x\n", ch);
846#endif
847	tp->DesiredTuple = CISTPL_LONGLINK_C;
848	return (CardServices(ParseTuple, ch, tp, pt));
849}
850
851int32_t
852csx_Parse_CISTPL_LONGLINK_MFC(client_handle_t ch, tuple_t *tp,
853    cistpl_longlink_mfc_t *pt)
854{
855#ifdef	CS_STUBS_DEBUG
856	if (cs_stubs_debug > 3)
857	    cmn_err(CE_CONT, "csx_Parse_CISTPL_LONGLINK_MFC: "
858						"handle: 0x%x\n", ch);
859#endif
860	tp->DesiredTuple = CISTPL_LONGLINK_MFC;
861	return (CardServices(ParseTuple, ch, tp, pt));
862}
863
864int32_t csx_Parse_CISTPL_LONGLINK_CB(client_handle_t ch, tuple_t *tp,
865    cistpl_longlink_cb_t *pt)
866{
867#ifdef	CS_STUBS_DEBUG
868	if (cs_stubs_debug > 3)
869	    cmn_err(CE_CONT, "csx_Parse_CISTPL_LONGLINK_CB: "
870						"handle: 0x%x\n", ch);
871#endif
872	tp->DesiredTuple = CISTPL_LONGLINK_CB;
873	return (CardServices(ParseTuple, ch, tp, pt));
874}
875
876int32_t
877csx_Parse_CISTPL_SPCL(client_handle_t ch, tuple_t *tp,
878    cistpl_spcl_t *pt)
879{
880#ifdef	CS_STUBS_DEBUG
881	if (cs_stubs_debug > 3)
882	    cmn_err(CE_CONT, "csx_Parse_CISTPL_SPCL: handle: 0x%x\n", ch);
883#endif
884	tp->DesiredTuple = CISTPL_SPCL;
885	return (CardServices(ParseTuple, ch, tp, pt));
886}
887
888int32_t
889csx_Parse_CISTPL_SWIL(client_handle_t ch, tuple_t *tp,
890    cistpl_swil_t *pt)
891{
892#ifdef	CS_STUBS_DEBUG
893	if (cs_stubs_debug > 3)
894	    cmn_err(CE_CONT, "csx_Parse_CISTPL_SWIL: handle: 0x%x\n", ch);
895#endif
896	tp->DesiredTuple = CISTPL_SWIL;
897	return (CardServices(ParseTuple, ch, tp, pt));
898}
899
900int32_t csx_Parse_CISTPL_BAR(client_handle_t ch, tuple_t *tp,
901    cistpl_bar_t *pt)
902{
903#ifdef	CS_STUBS_DEBUG
904	if (cs_stubs_debug > 3)
905	    cmn_err(CE_CONT, "csx_Parse_CISTPL_BAR: handle: 0x%x\n", ch);
906#endif
907	tp->DesiredTuple = CISTPL_BAR;
908	return (CardServices(ParseTuple, ch, tp, pt));
909}
910
911int32_t
912csx_Parse_CISTPL_DEVICEGEO(client_handle_t ch, tuple_t *tp,
913    cistpl_devicegeo_t *pt)
914{
915#ifdef	CS_STUBS_DEBUG
916	if (cs_stubs_debug > 3)
917	    cmn_err(CE_CONT, "csx_Parse_CISTPL_DEVICEGEO: handle: 0x%x\n", ch);
918#endif
919	tp->DesiredTuple = CISTPL_DEVICEGEO;
920	return (CardServices(ParseTuple, ch, tp, pt));
921}
922
923int32_t
924csx_Parse_CISTPL_DEVICEGEO_A(client_handle_t ch, tuple_t *tp,
925    cistpl_devicegeo_t *pt)
926{
927#ifdef	CS_STUBS_DEBUG
928	if (cs_stubs_debug > 3)
929	    cmn_err(CE_CONT, "csx_Parse_CISTPL_DEVICEGEO_A: "
930						"handle: 0x%x\n", ch);
931#endif
932	tp->DesiredTuple = CISTPL_DEVICEGEO_A;
933	return (CardServices(ParseTuple, ch, tp, pt));
934}
935
936int32_t
937csx_ParseTuple(client_handle_t ch, tuple_t *tp, cisparse_t *cp, uint32_t ef)
938{
939#ifdef	CS_STUBS_DEBUG
940	if (cs_stubs_debug > 3)
941	    cmn_err(CE_CONT, "csx_ParseTuple: handle: 0x%x\n", ch);
942#endif
943	return (CardServices(ParseTuple, ch, tp, cp, ef));
944}
945
946/*
947 * The following functions are used to access various datatypes.
948 *	These functions are not specific to PCMCIA client drivers
949 *	and they don't depend on Card Services being present to
950 *	operate.
951 */
952void
953csx_Put8(acc_handle_t handle, uint32_t offset, uint8_t value)
954{
955	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
956
957	ddi_put8(handle, (uint8_t *)(hp->ah_addr + offset), value);
958}
959
960void
961csx_Put16(acc_handle_t handle, uint32_t offset, uint16_t value)
962{
963	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
964
965	ddi_put16(handle, (uint16_t *)(hp->ah_addr + offset), value);
966}
967
968void
969csx_Put32(acc_handle_t handle, uint32_t offset, uint32_t value)
970{
971	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
972
973	ddi_put32(handle, (uint32_t *)(hp->ah_addr + offset), value);
974}
975
976void
977csx_Put64(acc_handle_t handle, uint32_t offset, uint64_t value)
978{
979	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
980
981	ddi_put64(handle, (uint64_t *)(hp->ah_addr + offset), value);
982}
983
984uint8_t
985csx_Get8(acc_handle_t handle, uint32_t offset)
986{
987	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
988
989	return (ddi_get8(handle, (uint8_t *)(hp->ah_addr + offset)));
990}
991
992uint16_t
993csx_Get16(acc_handle_t handle, uint32_t offset)
994{
995	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
996
997	return (ddi_get16(handle, (uint16_t *)(hp->ah_addr + offset)));
998}
999
1000uint32_t
1001csx_Get32(acc_handle_t handle, uint32_t offset)
1002{
1003	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1004
1005	return (ddi_get32(handle, (uint32_t *)(hp->ah_addr + offset)));
1006}
1007
1008uint64_t
1009csx_Get64(acc_handle_t handle, uint32_t offset)
1010{
1011	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1012
1013	return (ddi_get64(handle, (uint64_t *)(hp->ah_addr + offset)));
1014}
1015
1016void
1017csx_RepPut8(acc_handle_t handle, uint8_t *hostaddr, uint32_t offset,
1018						uint32_t rc, uint32_t flags)
1019{
1020	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1021
1022	ddi_rep_put8(handle, hostaddr, (uint8_t *)(hp->ah_addr + offset),
1023		rc, (uint32_t)flags);
1024}
1025
1026void
1027csx_RepPut16(acc_handle_t handle, uint16_t *hostaddr, uint32_t offset,
1028						uint32_t rc, uint32_t flags)
1029{
1030	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1031
1032	ddi_rep_put16(handle, hostaddr, (uint16_t *)(hp->ah_addr + offset),
1033		rc, (uint32_t)flags);
1034}
1035
1036void
1037csx_RepPut32(acc_handle_t handle, uint32_t *hostaddr, uint32_t offset,
1038						uint32_t rc, uint32_t flags)
1039{
1040	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1041
1042	ddi_rep_put32(handle, hostaddr, (uint32_t *)(hp->ah_addr + offset),
1043		rc, (uint32_t)flags);
1044}
1045
1046void
1047csx_RepPut64(acc_handle_t handle, uint64_t *hostaddr, uint32_t offset,
1048						uint32_t rc, uint32_t flags)
1049{
1050	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1051
1052	ddi_rep_put64(handle, hostaddr, (uint64_t *)(hp->ah_addr + offset),
1053		rc, (uint32_t)flags);
1054}
1055
1056void
1057csx_RepGet8(acc_handle_t handle, uint8_t *hostaddr, uint32_t offset,
1058						uint32_t rc, uint32_t flags)
1059{
1060	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1061
1062	ddi_rep_get8(handle, hostaddr, (uint8_t *)(hp->ah_addr + offset),
1063		rc, (uint32_t)flags);
1064}
1065
1066void
1067csx_RepGet16(acc_handle_t handle, uint16_t *hostaddr, uint32_t offset,
1068						uint32_t rc, uint32_t flags)
1069{
1070	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1071
1072	ddi_rep_get16(handle, hostaddr, (uint16_t *)(hp->ah_addr + offset),
1073		rc, (uint32_t)flags);
1074}
1075
1076void
1077csx_RepGet32(acc_handle_t handle, uint32_t *hostaddr, uint32_t offset,
1078						uint32_t rc, uint32_t flags)
1079{
1080	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1081
1082	ddi_rep_get32(handle, hostaddr, (uint32_t *)(hp->ah_addr + offset),
1083		rc, (uint32_t)flags);
1084}
1085
1086void
1087csx_RepGet64(acc_handle_t handle, uint64_t *hostaddr, uint32_t offset,
1088						uint32_t rc, uint32_t flags)
1089{
1090	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1091
1092	ddi_rep_get64(handle, hostaddr, (uint64_t *)(hp->ah_addr + offset),
1093		rc, (uint32_t)flags);
1094}
1095
1096/*
1097 * The following two functions return the mapped (virtual) or physical
1098 *	base address associated with the passed handle if the address
1099 *	can be directly accessed by the caller. If the object represented
1100 *	by the handle needs to be accessed through a common access
1101 *	function, CS_BAD_BASE is returned.
1102 *
1103 * XXX - Need to figure out how to determine when to return CS_BAD_BASE
1104 *	and also we need more generic return codes not tied to CS.
1105 */
1106int32_t
1107csx_GetMappedAddr(acc_handle_t handle, void **addr)
1108{
1109	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1110
1111#ifdef	CS_STUBS_DEBUG
1112	if (cs_stubs_debug > 3)
1113	    cmn_err(CE_CONT, "csx_GetMappedAddr: handle: 0x%p\n", handle);
1114#endif
1115
1116	*addr = hp->ah_addr;
1117
1118	return (CS_SUCCESS);	/* XXX should be generic return code */
1119}
1120
1121int32_t
1122csx_GetPhysAddr(acc_handle_t handle, void **addr)
1123{
1124#ifndef	lint
1125	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1126#endif	/* lint */
1127
1128#ifdef	CS_STUBS_DEBUG
1129	if (cs_stubs_debug > 3)
1130	    cmn_err(CE_CONT, "csx_GetPhysAddr: handle: 0x%p\n", handle);
1131#endif
1132
1133	*addr = NULL;
1134
1135	return (CS_BAD_BASE);
1136}
1137
1138/*ARGSUSED*/
1139int32_t
1140csx_DupHandle(acc_handle_t handle, acc_handle_t *dup, uint32_t flags)
1141{
1142#ifndef	lint
1143	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1144#endif	/* lint */
1145
1146#ifdef	CS_STUBS_DEBUG
1147	if (cs_stubs_debug > 3)
1148	    cmn_err(CE_CONT, "csx_DupHandle: handle: 0x%p\n", handle);
1149#endif
1150
1151	return (CS_BAD_HANDLE);
1152
1153#ifdef	XXX
1154	*dup = (acc_handle_t)kmem_alloc(sizeof (acc_hdl_t), KM_SLEEP);
1155	((acc_hdl_t *)*dup)->ddi_handle =
1156		(ddi_acc_handle_t *)kmem_alloc(sizeof (ddi_acc_impl_t),
1157		    KM_SLEEP);
1158
1159	bcopy((caddr_t)hp, (caddr_t)((acc_hdl_t *)*dup)->ddi_handle,
1160	    sizeof (ddi_acc_impl_t));
1161
1162	return (CS_SUCCESS);
1163#endif
1164}
1165
1166int32_t
1167csx_FreeHandle(acc_handle_t *handle)
1168{
1169#ifdef	CS_STUBS_DEBUG
1170	if (cs_stubs_debug > 3)
1171	    cmn_err(CE_CONT, "csx_FreeHandle: handle: 0x%p\n", *handle);
1172#endif
1173	return (CS_BAD_HANDLE);
1174
1175#ifdef	XXX
1176
1177	kmem_free((void *)((acc_hdl_t *)*handle)->ddi_handle,
1178		sizeof (ddi_acc_impl_t));
1179	kmem_free((void *)(acc_hdl_t *)*handle, sizeof (acc_hdl_t));
1180
1181	return (CS_SUCCESS);
1182#endif
1183}
1184
1185/*
1186 * XXX - Probably want to remove these fucntions soon
1187 */
1188int32_t
1189csx_GetHandleOffset(acc_handle_t handle, uint32_t *offset)
1190{
1191	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1192
1193#ifdef	CS_STUBS_DEBUG
1194	if (cs_stubs_debug > 3)
1195	    cmn_err(CE_CONT, "csx_GetHandleOffset: handle: 0x%p\n", handle);
1196#endif
1197
1198	*offset = hp->ah_offset;
1199
1200	return (CS_SUCCESS);
1201}
1202
1203int32_t
1204csx_SetHandleOffset(acc_handle_t handle, uint32_t offset)
1205{
1206	ddi_acc_hdl_t *hp = impl_acc_hdl_get(handle);
1207
1208#ifdef	CS_STUBS_DEBUG
1209	if (cs_stubs_debug > 3)
1210	    cmn_err(CE_CONT, "csx_SetHandleOffset: handle: 0x%p\n", handle);
1211#endif
1212
1213	hp->ah_offset = offset;
1214
1215	return (CS_SUCCESS);
1216}
1217
1218static int
1219cs_no_carservices()
1220{
1221#ifdef	CS_STUBS_DEBUG
1222	if (cs_stubs_debug > 3)
1223	    cmn_err(CE_CONT, "cs_no_carservices\n");
1224#endif
1225	return (CS_UNSUPPORTED_FUNCTION);
1226}
1227