1 /*
2  *
3  * Alchemy Semi Au1000 pcmcia driver
4  *
5  * Copyright 2001-2003 MontaVista Software Inc.
6  * Author: MontaVista Software, Inc.
7  *         	ppopov@mvista.com or source@mvista.com
8  *
9  * ########################################################################
10  *
11  *  This program is free software; you can distribute it and/or modify it
12  *  under the terms of the GNU General Public License (Version 2) as
13  *  published by the Free Software Foundation.
14  *
15  *  This program is distributed in the hope it will be useful, but WITHOUT
16  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18  *  for more details.
19  *
20  *  You should have received a copy of the GNU General Public License along
21  *  with this program; if not, write to the Free Software Foundation, Inc.,
22  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
23  *
24  * ########################################################################
25  *
26  *
27  */
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/config.h>
31 #include <linux/delay.h>
32 #include <linux/ioport.h>
33 #include <linux/kernel.h>
34 #include <linux/tqueue.h>
35 #include <linux/timer.h>
36 #include <linux/mm.h>
37 #include <linux/proc_fs.h>
38 #include <linux/version.h>
39 #include <linux/types.h>
40 #include <linux/vmalloc.h>
41 
42 #include <pcmcia/version.h>
43 #include <pcmcia/cs_types.h>
44 #include <pcmcia/cs.h>
45 #include <pcmcia/ss.h>
46 #include <pcmcia/bulkmem.h>
47 #include <pcmcia/cistpl.h>
48 #include <pcmcia/bus_ops.h>
49 #include "cs_internal.h"
50 
51 #include <asm/io.h>
52 #include <asm/irq.h>
53 #include <asm/system.h>
54 
55 #include <asm/au1000.h>
56 #include <asm/au1000_pcmcia.h>
57 
58 #ifdef PCMCIA_DEBUG
59 static int pc_debug;
60 #endif
61 
62 MODULE_LICENSE("GPL");
63 MODULE_AUTHOR("Pete Popov, MontaVista Software <ppopov@mvista.com>");
64 MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller");
65 
66 #define MAP_SIZE 0x1000000
67 
68 /* This structure maintains housekeeping state for each socket, such
69  * as the last known values of the card detect pins, or the Card Services
70  * callback value associated with the socket:
71  */
72 static struct au1000_pcmcia_socket *pcmcia_socket;
73 
74 /* Some boards like to support CF cards as IDE root devices, so they
75  * grab pcmcia sockets directly.
76  */
77 int socket_count;
78 u32 *pcmcia_base_vaddrs[2];
79 
80 
81 /* Returned by the low-level PCMCIA interface: */
82 static struct pcmcia_low_level *pcmcia_low_level;
83 
84 /* Event poll timer structure */
85 static struct timer_list poll_timer;
86 
87 
88 /* Prototypes for routines which are used internally: */
89 
90 static int  au1000_pcmcia_driver_init(void);
91 static void au1000_pcmcia_driver_shutdown(void);
92 static void au1000_pcmcia_task_handler(void *data);
93 static void au1000_pcmcia_poll_event(unsigned long data);
94 static void au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
95 static struct tq_struct au1000_pcmcia_task;
96 
97 #ifdef CONFIG_PROC_FS
98 static int au1000_pcmcia_proc_status(char *buf, char **start,
99 		off_t pos, int count, int *eof, void *data);
100 #endif
101 
102 
103 /* Prototypes for operations which are exported to the
104  * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
105  */
106 
107 static int au1000_pcmcia_init(u32 sock);
108 static int au1000_pcmcia_suspend(u32 sock);
109 static int au1000_pcmcia_register_callback(u32 sock,
110 		void (*handler)(void *, u32), void *info);
111 static int au1000_pcmcia_inquire_socket(u32 sock, socket_cap_t *cap);
112 static int au1000_pcmcia_get_status(u32 sock, u_int *value);
113 static int au1000_pcmcia_get_socket(u32 sock, socket_state_t *state);
114 static int au1000_pcmcia_set_socket(u32 sock, socket_state_t *state);
115 static int au1000_pcmcia_get_io_map(u32 sock, struct pccard_io_map *io);
116 static int au1000_pcmcia_set_io_map(u32 sock, struct pccard_io_map *io);
117 static int au1000_pcmcia_get_mem_map(u32 sock, struct pccard_mem_map *mem);
118 static int au1000_pcmcia_set_mem_map(u32 sock, struct pccard_mem_map *mem);
119 #ifdef CONFIG_PROC_FS
120 static void au1000_pcmcia_proc_setup(u32 sock, struct proc_dir_entry *base);
121 #endif
122 
123 static struct pccard_operations au1000_pcmcia_operations = {
124 	au1000_pcmcia_init,
125 	au1000_pcmcia_suspend,
126 	au1000_pcmcia_register_callback,
127 	au1000_pcmcia_inquire_socket,
128 	au1000_pcmcia_get_status,
129 	au1000_pcmcia_get_socket,
130 	au1000_pcmcia_set_socket,
131 	au1000_pcmcia_get_io_map,
132 	au1000_pcmcia_set_io_map,
133 	au1000_pcmcia_get_mem_map,
134 	au1000_pcmcia_set_mem_map,
135 #ifdef CONFIG_PROC_FS
136 	au1000_pcmcia_proc_setup
137 #endif
138 };
139 
140 static spinlock_t pcmcia_lock = SPIN_LOCK_UNLOCKED;
141 
142 extern const unsigned long mips_io_port_base;
143 
au1000_pcmcia_driver_init(void)144 static int __init au1000_pcmcia_driver_init(void)
145 {
146 	servinfo_t info;
147 	struct pcmcia_init pcmcia_init;
148 	struct pcmcia_state state;
149 	unsigned int i;
150 
151 	printk("\nAu1x00 PCMCIA (CS release %s)\n", CS_RELEASE);
152 
153 #ifndef CONFIG_64BIT_PHYS_ADDR
154 	printk(KERN_ERR "Au1x00 PCMCIA 36 bit IO support not enabled\n");
155 	return -1;
156 #endif
157 
158 	CardServices(GetCardServicesInfo, &info);
159 
160 	if(info.Revision!=CS_RELEASE_CODE){
161 		printk(KERN_ERR "Card Services release codes do not match\n");
162 		return -1;
163 	}
164 
165 	pcmcia_low_level=&au1x00_pcmcia_ops;
166 	pcmcia_init.handler=au1000_pcmcia_interrupt;
167 	if((socket_count=pcmcia_low_level->init(&pcmcia_init))<0) {
168 		printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
169 		return -EIO;
170 	}
171 
172 	/* NOTE: the chip select must already be setup */
173 
174 	pcmcia_socket =
175 		kmalloc(sizeof(struct au1000_pcmcia_socket) * socket_count,
176 				GFP_KERNEL);
177 	if (!pcmcia_socket) {
178 		printk(KERN_ERR "Card Services can't get memory \n");
179 		return -1;
180 	}
181 	memset(pcmcia_socket, 0,
182 			sizeof(struct au1000_pcmcia_socket) * socket_count);
183 
184 	/*
185 	 * Assuming max of 2 sockets, which the Au1000 supports.
186 	 * WARNING: the Pb1000 has two sockets, and both work, but you
187 	 * can't use them both at the same time due to glue logic conflicts.
188 	 */
189 	for(i=0; i < socket_count; i++) {
190 
191 		if(pcmcia_low_level->socket_state(i, &state)<0){
192 			printk(KERN_ERR "Unable to get PCMCIA status\n");
193 			return -EIO;
194 		}
195 		pcmcia_socket[i].k_state=state;
196 		pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
197 
198 		/*
199 		 * PCMCIA drivers use the inb/outb macros to access the
200 		 * IO registers. Since mips_io_port_base is added to the
201 		 * access address, we need to subtract it here.
202 		 */
203 		if (i == 0) {
204 			pcmcia_socket[i].virt_io =
205 				(u32)ioremap((ioaddr_t)AU1X_SOCK0_IO, 0x1000) -
206 				mips_io_port_base;
207 			pcmcia_socket[i].phys_attr =
208 				(ioaddr_t)AU1X_SOCK0_PHYS_ATTR;
209 			pcmcia_socket[i].phys_mem =
210 				(ioaddr_t)AU1X_SOCK0_PHYS_MEM;
211 		}
212 #ifdef AU1X_SOCK1_IO /* revisit */
213 		else  {
214 			pcmcia_socket[i].virt_io =
215 				(u32)ioremap((ioaddr_t)AU1X_SOCK1_IO, 0x1000) -
216 				mips_io_port_base;
217 			pcmcia_socket[i].phys_attr =
218 				(ioaddr_t)AU1X_SOCK1_PHYS_ATTR;
219 			pcmcia_socket[i].phys_mem =
220 				(ioaddr_t)AU1X_SOCK1_PHYS_MEM;
221 		}
222 #endif
223 		pcmcia_base_vaddrs[i] = (u32 *)pcmcia_socket[i].virt_io;
224 	}
225 
226 	/* Only advertise as many sockets as we can detect: */
227 	if(register_ss_entry(socket_count, &au1000_pcmcia_operations)<0){
228 		printk(KERN_ERR "Unable to register socket service routine\n");
229 		return -ENXIO;
230 	}
231 
232 	/* Start the event poll timer.
233 	 * It will reschedule by itself afterwards.
234 	 */
235 	au1000_pcmcia_poll_event(0);
236 
237 	DEBUG(1, "au1000: initialization complete\n");
238 	return 0;
239 
240 }  /* au1000_pcmcia_driver_init() */
241 
242 module_init(au1000_pcmcia_driver_init);
243 
au1000_pcmcia_driver_shutdown(void)244 static void __exit au1000_pcmcia_driver_shutdown(void)
245 {
246 	int i;
247 
248 	del_timer_sync(&poll_timer);
249 	unregister_ss_entry(&au1000_pcmcia_operations);
250 	pcmcia_low_level->shutdown();
251 	flush_scheduled_tasks();
252 	for(i=0; i < socket_count; i++) {
253 		if (pcmcia_socket[i].virt_io)
254 			iounmap((void *)pcmcia_socket[i].virt_io +
255 					mips_io_port_base);
256 	}
257 	DEBUG(1, "au1000: shutdown complete\n");
258 }
259 
260 module_exit(au1000_pcmcia_driver_shutdown);
261 
au1000_pcmcia_init(unsigned int sock)262 static int au1000_pcmcia_init(unsigned int sock) { return 0; }
263 
au1000_pcmcia_suspend(unsigned int sock)264 static int au1000_pcmcia_suspend(unsigned int sock)
265 {
266 	return 0;
267 }
268 
269 
270 static inline unsigned
au1000_pcmcia_events(struct pcmcia_state * state,struct pcmcia_state * prev_state,unsigned int mask,unsigned int flags)271 au1000_pcmcia_events(struct pcmcia_state *state,
272 		struct pcmcia_state *prev_state,
273 		unsigned int mask, unsigned int flags)
274 {
275 	unsigned int events=0;
276 
277 	if(state->detect!=prev_state->detect){
278 		DEBUG(2, "%s(): card detect value %u\n",
279 				__FUNCTION__, state->detect);
280 		events |= mask&SS_DETECT;
281 	}
282 
283 
284 	if(state->ready!=prev_state->ready){
285 		DEBUG(2, "%s(): card ready value %u\n",
286 				__FUNCTION__, state->ready);
287 		events |= mask&((flags&SS_IOCARD)?0:SS_READY);
288 	}
289 
290 	*prev_state=*state;
291 	return events;
292 
293 }  /* au1000_pcmcia_events() */
294 
295 
296 /*
297  * Au1000_pcmcia_task_handler()
298  * Processes socket events.
299  */
au1000_pcmcia_task_handler(void * data)300 static void au1000_pcmcia_task_handler(void *data)
301 {
302 	struct pcmcia_state state;
303 	int i, events, irq_status;
304 
305 	for(i=0; i<socket_count; i++)  {
306 		if((irq_status = pcmcia_low_level->socket_state(i, &state))<0)
307 			printk(KERN_ERR "low-level PCMCIA error\n");
308 
309 		events = au1000_pcmcia_events(&state,
310 				&pcmcia_socket[i].k_state,
311 				pcmcia_socket[i].cs_state.csc_mask,
312 				pcmcia_socket[i].cs_state.flags);
313 		if(pcmcia_socket[i].handler!=NULL) {
314 			pcmcia_socket[i].handler(pcmcia_socket[i].handler_info,
315 					events);
316 		}
317 	}
318 
319 }  /* au1000_pcmcia_task_handler() */
320 
321 static struct tq_struct au1000_pcmcia_task = {
322 	routine: au1000_pcmcia_task_handler
323 };
324 
325 
au1000_pcmcia_poll_event(unsigned long dummy)326 static void au1000_pcmcia_poll_event(unsigned long dummy)
327 {
328 	poll_timer.function = au1000_pcmcia_poll_event;
329 	poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD;
330 	add_timer(&poll_timer);
331 	schedule_task(&au1000_pcmcia_task);
332 }
333 
334 
335 /*
336  * au1000_pcmcia_interrupt()
337  * The actual interrupt work is performed by au1000_pcmcia_task(),
338  * because the Card Services event handling code performs scheduling
339  * operations which cannot be executed from within an interrupt context.
340  */
341 static void
au1000_pcmcia_interrupt(int irq,void * dev,struct pt_regs * regs)342 au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
343 {
344 	schedule_task(&au1000_pcmcia_task);
345 }
346 
347 
348 static int
au1000_pcmcia_register_callback(unsigned int sock,void (* handler)(void *,unsigned int),void * info)349 au1000_pcmcia_register_callback(unsigned int sock,
350 		void (*handler)(void *, unsigned int), void *info)
351 {
352 	if(handler==NULL){
353 		pcmcia_socket[sock].handler=NULL;
354 		MOD_DEC_USE_COUNT;
355 	} else {
356 		MOD_INC_USE_COUNT;
357 		pcmcia_socket[sock].handler=handler;
358 		pcmcia_socket[sock].handler_info=info;
359 	}
360 	return 0;
361 }
362 
363 
364 /* au1000_pcmcia_inquire_socket()
365  *
366  * From the sa1100 socket driver :
367  *
368  * Implements the inquire_socket() operation for the in-kernel PCMCIA
369  * service (formerly SS_InquireSocket in Card Services).  We set
370  * SS_CAP_STATIC_MAP, which disables the memory resource database check.
371  * (Mapped memory is set up within the socket driver itself.)
372  *
373  * In conjunction with the STATIC_MAP capability is a new field,
374  * `io_offset', recommended by David Hinds. Rather than go through
375  * the SetIOMap interface (which is not quite suited for communicating
376  * window locations up from the socket driver), we just pass up
377  * an offset which is applied to client-requested base I/O addresses
378  * in alloc_io_space().
379  *
380  * Returns: 0 on success, -1 if no pin has been configured for `sock'
381  */
au1000_pcmcia_inquire_socket(unsigned int sock,socket_cap_t * cap)382 static int au1000_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
383 {
384 	struct pcmcia_irq_info irq_info;
385 
386 	if(sock > socket_count){
387 		printk(KERN_ERR "au1000: socket %u not configured\n", sock);
388 		return -1;
389 	}
390 
391 	/* from the sa1100_generic driver: */
392 
393 	/* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
394 	*   force_low argument to validate_mem() in rsrc_mgr.c -- since in
395 	*   general, the mapped * addresses of the PCMCIA memory regions
396 	*   will not be within 0xffff, setting force_low would be
397 	*   undesirable.
398 	*
399 	* SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
400 	*   resource database; we instead pass up physical address ranges
401 	*   and allow other parts of Card Services to deal with remapping.
402 	*
403 	* SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
404 	*   not 32-bit CardBus devices.
405 	*/
406 	cap->features=(SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
407 
408 	irq_info.sock=sock;
409 	irq_info.irq=-1;
410 
411 	if(pcmcia_low_level->get_irq_info(&irq_info)<0){
412 		printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock);
413 		return -1;
414 	}
415 
416 	cap->irq_mask=0;
417 	cap->map_size=MAP_SIZE;
418 	cap->pci_irq=irq_info.irq;
419 	cap->io_offset=pcmcia_socket[sock].virt_io;
420 
421 	return 0;
422 
423 }  /* au1000_pcmcia_inquire_socket() */
424 
425 
426 static int
au1000_pcmcia_get_status(unsigned int sock,unsigned int * status)427 au1000_pcmcia_get_status(unsigned int sock, unsigned int *status)
428 {
429 	struct pcmcia_state state;
430 
431 
432 	if((pcmcia_low_level->socket_state(sock, &state))<0){
433 		printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
434 		return -1;
435 	}
436 
437 	pcmcia_socket[sock].k_state = state;
438 
439 	*status = state.detect?SS_DETECT:0;
440 
441 	*status |= state.ready?SS_READY:0;
442 
443 	*status |= pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;
444 
445 	if(pcmcia_socket[sock].cs_state.flags&SS_IOCARD)
446 		*status |= state.bvd1?SS_STSCHG:0;
447 	else {
448 		if(state.bvd1==0)
449 			*status |= SS_BATDEAD;
450 		else if(state.bvd2 == 0)
451 			*status |= SS_BATWARN;
452 	}
453 
454 	*status|=state.vs_3v?SS_3VCARD:0;
455 
456 	*status|=state.vs_Xv?SS_XVCARD:0;
457 
458 	DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n",
459 	(*status&SS_DETECT)?"DETECT ":"",
460 	(*status&SS_READY)?"READY ":"",
461 	(*status&SS_BATDEAD)?"BATDEAD ":"",
462 	(*status&SS_BATWARN)?"BATWARN ":"",
463 	(*status&SS_POWERON)?"POWERON ":"",
464 	(*status&SS_STSCHG)?"STSCHG ":"",
465 	(*status&SS_3VCARD)?"3VCARD ":"",
466 	(*status&SS_XVCARD)?"XVCARD ":"");
467 
468 	return 0;
469 
470 }  /* au1000_pcmcia_get_status() */
471 
472 
473 static int
au1000_pcmcia_get_socket(unsigned int sock,socket_state_t * state)474 au1000_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
475 {
476 	*state = pcmcia_socket[sock].cs_state;
477 	return 0;
478 }
479 
480 
481 static int
au1000_pcmcia_set_socket(unsigned int sock,socket_state_t * state)482 au1000_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
483 {
484 	struct pcmcia_configure configure;
485 
486 	DEBUG(2, "\tmask:  %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
487 	"\tVcc %d  Vpp %d  irq %d\n",
488 	(state->csc_mask==0)?"<NONE>":"",
489 	(state->csc_mask&SS_DETECT)?"DETECT ":"",
490 	(state->csc_mask&SS_READY)?"READY ":"",
491 	(state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
492 	(state->csc_mask&SS_BATWARN)?"BATWARN ":"",
493 	(state->csc_mask&SS_STSCHG)?"STSCHG ":"",
494 	(state->flags==0)?"<NONE>":"",
495 	(state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
496 	(state->flags&SS_IOCARD)?"IOCARD ":"",
497 	(state->flags&SS_RESET)?"RESET ":"",
498 	(state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
499 	(state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
500 	state->Vcc, state->Vpp, state->io_irq);
501 
502 	configure.sock=sock;
503 	configure.vcc=state->Vcc;
504 	configure.vpp=state->Vpp;
505 	configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;
506 	configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;
507 	configure.reset=(state->flags&SS_RESET)?1:0;
508 
509 	if(pcmcia_low_level->configure_socket(&configure)<0){
510 		printk(KERN_ERR "Unable to configure socket %u\n", sock);
511 		return -1;
512 	}
513 
514 	pcmcia_socket[sock].cs_state = *state;
515 	return 0;
516 
517 }  /* au1000_pcmcia_set_socket() */
518 
519 
520 static int
au1000_pcmcia_get_io_map(unsigned int sock,struct pccard_io_map * map)521 au1000_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
522 {
523 	DEBUG(1, "au1000_pcmcia_get_io_map: sock %d\n", sock);
524 	if(map->map>=MAX_IO_WIN){
525 		printk(KERN_ERR "%s(): map (%d) out of range\n",
526 				__FUNCTION__, map->map);
527 		return -1;
528 	}
529 	*map=pcmcia_socket[sock].io_map[map->map];
530 	return 0;
531 }
532 
533 
534 int
au1000_pcmcia_set_io_map(unsigned int sock,struct pccard_io_map * map)535 au1000_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
536 {
537 	unsigned int speed;
538 	unsigned long start;
539 
540 	if(map->map>=MAX_IO_WIN){
541 		printk(KERN_ERR "%s(): map (%d) out of range\n",
542 				__FUNCTION__, map->map);
543 		return -1;
544 	}
545 
546 	if(map->flags&MAP_ACTIVE){
547 		speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED;
548 		pcmcia_socket[sock].speed_io=speed;
549 	}
550 
551 	start=map->start;
552 
553 	if(map->stop==1) {
554 		map->stop=PAGE_SIZE-1;
555 	}
556 
557 	map->start=pcmcia_socket[sock].virt_io;
558 	map->stop=map->start+(map->stop-start);
559 	pcmcia_socket[sock].io_map[map->map]=*map;
560 	DEBUG(3, "set_io_map %d start %x stop %x\n",
561 			map->map, map->start, map->stop);
562 	return 0;
563 
564 }  /* au1000_pcmcia_set_io_map() */
565 
566 
567 static int
au1000_pcmcia_get_mem_map(unsigned int sock,struct pccard_mem_map * map)568 au1000_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
569 {
570 
571 	if(map->map>=MAX_WIN) {
572 		printk(KERN_ERR "%s(): map (%d) out of range\n",
573 				__FUNCTION__, map->map);
574 		return -1;
575 	}
576 	*map=pcmcia_socket[sock].mem_map[map->map];
577 	return 0;
578 }
579 
580 
581 static int
au1000_pcmcia_set_mem_map(unsigned int sock,struct pccard_mem_map * map)582 au1000_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
583 {
584 	unsigned int speed;
585 	unsigned long start;
586 	u_long flags;
587 
588 	if(map->map>=MAX_WIN){
589 		printk(KERN_ERR "%s(): map (%d) out of range\n",
590 				__FUNCTION__, map->map);
591 		return -1;
592 	}
593 
594 	if(map->flags&MAP_ACTIVE){
595 		speed=(map->speed>0)?map->speed:AU1000_PCMCIA_MEM_SPEED;
596 
597 		/* TBD */
598 		if(map->flags&MAP_ATTRIB){
599 			pcmcia_socket[sock].speed_attr=speed;
600 		}
601 		else {
602 			pcmcia_socket[sock].speed_mem=speed;
603 		}
604 	}
605 
606 	spin_lock_irqsave(&pcmcia_lock, flags);
607 
608 	if(map->sys_stop==0)
609 		map->sys_stop=MAP_SIZE-1;
610 
611 	if (map->flags & MAP_ATTRIB) {
612 		map->sys_start = pcmcia_socket[sock].phys_attr +
613 			map->card_start;
614 	}
615 	else {
616 		map->sys_start = pcmcia_socket[sock].phys_mem +
617 			map->card_start;
618 	}
619 
620 	map->sys_stop=map->sys_start+MAP_SIZE;
621 	pcmcia_socket[sock].mem_map[map->map]=*map;
622 	spin_unlock_irqrestore(&pcmcia_lock, flags);
623 	DEBUG(3, "set_mem_map %d start %x stop %x card_start %x\n",
624 			map->map, map->sys_start, map->sys_stop,
625 			map->card_start);
626 	return 0;
627 
628 }  /* au1000_pcmcia_set_mem_map() */
629 
630 
631 #if defined(CONFIG_PROC_FS)
632 
633 static void
au1000_pcmcia_proc_setup(unsigned int sock,struct proc_dir_entry * base)634 au1000_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
635 {
636 	struct proc_dir_entry *entry;
637 
638 	if((entry=create_proc_entry("status", 0, base))==NULL){
639 		printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
640 		return;
641 	}
642 
643 	entry->read_proc=au1000_pcmcia_proc_status;
644 	entry->data=(void *)sock;
645 }
646 
647 
648 /* au1000_pcmcia_proc_status()
649  * Implements the /proc/bus/pccard/??/status file.
650  *
651  * Returns: the number of characters added to the buffer
652  */
653 static int
au1000_pcmcia_proc_status(char * buf,char ** start,off_t pos,int count,int * eof,void * data)654 au1000_pcmcia_proc_status(char *buf, char **start, off_t pos,
655 		int count, int *eof, void *data)
656 {
657 	char *p=buf;
658 	unsigned int sock=(unsigned int)data;
659 
660 	p+=sprintf(p, "k_flags  : %s%s%s%s%s%s%s\n",
661 	     pcmcia_socket[sock].k_state.detect?"detect ":"",
662 	     pcmcia_socket[sock].k_state.ready?"ready ":"",
663 	     pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",
664 	     pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",
665 	     pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",
666 	     pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",
667 	     pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");
668 
669 	p+=sprintf(p, "status   : %s%s%s%s%s%s%s%s%s\n",
670 	     pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",
671 	     pcmcia_socket[sock].k_state.ready?"SS_READY ":"",
672 	     pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",
673 	     pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
674 	     "SS_IOCARD ":"",
675 	     (pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&
676 	      pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",
677 	     ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
678 	      (pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",
679 	     ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
680 	      (pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",
681 	     pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",
682 	     pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");
683 
684 	p+=sprintf(p, "mask     : %s%s%s%s%s\n",
685 	     pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\
686 	     "SS_DETECT ":"",
687 	     pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\
688 	     "SS_READY ":"",
689 	     pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\
690 	     "SS_BATDEAD ":"",
691 	     pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\
692 	     "SS_BATWARN ":"",
693 	     pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\
694 	     "SS_STSCHG ":"");
695 
696 	p+=sprintf(p, "cs_flags : %s%s%s%s%s\n",
697 	     pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\
698 	     "SS_PWR_AUTO ":"",
699 	     pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
700 	     "SS_IOCARD ":"",
701 	     pcmcia_socket[sock].cs_state.flags&SS_RESET?\
702 	     "SS_RESET ":"",
703 	     pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\
704 	     "SS_SPKR_ENA ":"",
705 	     pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\
706 	     "SS_OUTPUT_ENA ":"");
707 
708 	p+=sprintf(p, "Vcc      : %d\n", pcmcia_socket[sock].cs_state.Vcc);
709 	p+=sprintf(p, "Vpp      : %d\n", pcmcia_socket[sock].cs_state.Vpp);
710 	p+=sprintf(p, "irq      : %d\n", pcmcia_socket[sock].cs_state.io_irq);
711 	p+=sprintf(p, "I/O      : %u\n", pcmcia_socket[sock].speed_io);
712 	p+=sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr);
713 	p+=sprintf(p, "common   : %u\n", pcmcia_socket[sock].speed_mem);
714 	return p-buf;
715 }
716 
717 
718 #endif  /* defined(CONFIG_PROC_FS) */
719