au1000_generic.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:19k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *
  3.  * Alchemy Semi Au1000 pcmcia driver
  4.  *
  5.  * Copyright 2001 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. #include <pcmcia/version.h>
  42. #include <pcmcia/cs_types.h>
  43. #include <pcmcia/cs.h>
  44. #include <pcmcia/ss.h>
  45. #include <pcmcia/bulkmem.h>
  46. #include <pcmcia/cistpl.h>
  47. #include <pcmcia/bus_ops.h>
  48. #include "cs_internal.h"
  49. #include <asm/io.h>
  50. #include <asm/irq.h>
  51. #include <asm/system.h>
  52. #include <asm/au1000.h>
  53. #include <asm/au1000_pcmcia.h>
  54. #ifdef PCMCIA_DEBUG
  55. static int pc_debug;
  56. #endif
  57. MODULE_LICENSE("GPL");
  58. MODULE_AUTHOR("Pete Popov, MontaVista Software <ppopov@mvista.com>");
  59. MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller");
  60. #define MAP_SIZE 0x1000000
  61. /* This structure maintains housekeeping state for each socket, such
  62.  * as the last known values of the card detect pins, or the Card Services
  63.  * callback value associated with the socket:
  64.  */
  65. static struct au1000_pcmcia_socket *pcmcia_socket;
  66. static int socket_count;
  67. /* Returned by the low-level PCMCIA interface: */
  68. static struct pcmcia_low_level *pcmcia_low_level;
  69. /* Event poll timer structure */
  70. static struct timer_list poll_timer;
  71. /* Prototypes for routines which are used internally: */
  72. static int  au1000_pcmcia_driver_init(void);
  73. static void au1000_pcmcia_driver_shutdown(void);
  74. static void au1000_pcmcia_task_handler(void *data);
  75. static void au1000_pcmcia_poll_event(unsigned long data);
  76. static void au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs);
  77. static struct tq_struct au1000_pcmcia_task;
  78. #ifdef CONFIG_PROC_FS
  79. static int au1000_pcmcia_proc_status(char *buf, char **start, 
  80. off_t pos, int count, int *eof, void *data);
  81. #endif
  82. /* Prototypes for operations which are exported to the
  83.  * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
  84.  */
  85. static int au1000_pcmcia_init(u32 sock);
  86. static int au1000_pcmcia_suspend(u32 sock);
  87. static int au1000_pcmcia_register_callback(u32 sock, 
  88. void (*handler)(void *, u32), void *info);
  89. static int au1000_pcmcia_inquire_socket(u32 sock, socket_cap_t *cap);
  90. static int au1000_pcmcia_get_status(u32 sock, u_int *value);
  91. static int au1000_pcmcia_get_socket(u32 sock, socket_state_t *state);
  92. static int au1000_pcmcia_set_socket(u32 sock, socket_state_t *state);
  93. static int au1000_pcmcia_get_io_map(u32 sock, struct pccard_io_map *io);
  94. static int au1000_pcmcia_set_io_map(u32 sock, struct pccard_io_map *io);
  95. static int au1000_pcmcia_get_mem_map(u32 sock, struct pccard_mem_map *mem);
  96. static int au1000_pcmcia_set_mem_map(u32 sock, struct pccard_mem_map *mem);
  97. #ifdef CONFIG_PROC_FS
  98. static void au1000_pcmcia_proc_setup(u32 sock, struct proc_dir_entry *base);
  99. #endif
  100. static struct pccard_operations au1000_pcmcia_operations = {
  101. au1000_pcmcia_init,
  102. au1000_pcmcia_suspend,
  103. au1000_pcmcia_register_callback,
  104. au1000_pcmcia_inquire_socket,
  105. au1000_pcmcia_get_status,
  106. au1000_pcmcia_get_socket,
  107. au1000_pcmcia_set_socket,
  108. au1000_pcmcia_get_io_map,
  109. au1000_pcmcia_set_io_map,
  110. au1000_pcmcia_get_mem_map,
  111. au1000_pcmcia_set_mem_map,
  112. #ifdef CONFIG_PROC_FS
  113. au1000_pcmcia_proc_setup
  114. #endif
  115. };
  116. static int __init au1000_pcmcia_driver_init(void)
  117. {
  118. servinfo_t info;
  119. struct pcmcia_init pcmcia_init;
  120. struct pcmcia_state state;
  121. unsigned int i;
  122. unsigned long timing3;
  123. printk("nAu1x00 PCMCIA (CS release %s)n", CS_RELEASE);
  124. #ifndef CONFIG_64BIT_PHYS_ADDR
  125. printk(KERN_ERR "Au1x00 PCMCIA 36 bit IO support not enabledn");
  126. return -1;
  127. #endif
  128. CardServices(GetCardServicesInfo, &info);
  129. if(info.Revision!=CS_RELEASE_CODE){
  130. printk(KERN_ERR "Card Services release codes do not matchn");
  131. return -1;
  132. }
  133. #if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_PB1500)
  134. pcmcia_low_level=&pb1x00_pcmcia_ops;
  135. #else
  136. #error Unsupported AU1000 board.
  137. #endif
  138. pcmcia_init.handler=au1000_pcmcia_interrupt;
  139. if((socket_count=pcmcia_low_level->init(&pcmcia_init))<0) {
  140. printk(KERN_ERR "Unable to initialize PCMCIA service.n");
  141. return -EIO;
  142. }
  143. /* NOTE: the chip select must already be setup */
  144. pcmcia_socket = 
  145. kmalloc(sizeof(struct au1000_pcmcia_socket) * socket_count, 
  146. GFP_KERNEL);
  147. if (!pcmcia_socket) {
  148. printk(KERN_ERR "Card Services can't get memory n");
  149. return -1;
  150. }
  151. memset(pcmcia_socket, 0,
  152. sizeof(struct au1000_pcmcia_socket) * socket_count);
  153. /* 
  154.  * Assuming max of 2 sockets, which the Au1000 supports.
  155.  * WARNING: the Pb1000 has two sockets, and both work, but you
  156.  * can't use them both at the same time due to glue logic conflicts.
  157.  */
  158. for(i=0; i < socket_count; i++) {
  159. if(pcmcia_low_level->socket_state(i, &state)<0){
  160. printk(KERN_ERR "Unable to get PCMCIA statusn");
  161. return -EIO;
  162. }
  163. pcmcia_socket[i].k_state=state;
  164. pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
  165. if (i == 0) {
  166. pcmcia_socket[i].virt_io = 
  167. (u32)ioremap((ioaddr_t)0xF00000000, 0x1000);
  168. pcmcia_socket[i].phys_attr = (memaddr_t)0xF40000000;
  169. pcmcia_socket[i].phys_mem = (memaddr_t)0xF80000000;
  170. }
  171. else  {
  172. pcmcia_socket[i].virt_io = 
  173. (u32)ioremap((ioaddr_t)0xF08000000, 0x1000);
  174. pcmcia_socket[i].phys_attr = (memaddr_t)0xF48000000;
  175. pcmcia_socket[i].phys_mem = (memaddr_t)0xF88000000;
  176. }
  177. }
  178. /* Only advertise as many sockets as we can detect: */
  179. if(register_ss_entry(socket_count, &au1000_pcmcia_operations)<0){
  180. printk(KERN_ERR "Unable to register socket service routinen");
  181. return -ENXIO;
  182. }
  183. /* Start the event poll timer.  
  184.  * It will reschedule by itself afterwards. 
  185.  */
  186. au1000_pcmcia_poll_event(0);
  187. DEBUG(1, "au1000: initialization completen");
  188. return 0;
  189. }  /* au1000_pcmcia_driver_init() */
  190. module_init(au1000_pcmcia_driver_init);
  191. static void __exit au1000_pcmcia_driver_shutdown(void)
  192. {
  193. int i;
  194. del_timer_sync(&poll_timer);
  195. unregister_ss_entry(&au1000_pcmcia_operations);
  196. pcmcia_low_level->shutdown();
  197. flush_scheduled_tasks();
  198. for(i=0; i < socket_count; i++) {
  199. if (pcmcia_socket[i].virt_io) 
  200. iounmap((void *)pcmcia_socket[i].virt_io);
  201. }
  202. DEBUG(1, "au1000: shutdown completen");
  203. }
  204. module_exit(au1000_pcmcia_driver_shutdown);
  205. static int au1000_pcmcia_init(unsigned int sock) { return 0; }
  206. static int au1000_pcmcia_suspend(unsigned int sock)
  207. {
  208. return 0;
  209. }
  210. static inline unsigned 
  211. au1000_pcmcia_events(struct pcmcia_state *state, 
  212. struct pcmcia_state *prev_state, 
  213. unsigned int mask, unsigned int flags)
  214. {
  215. unsigned int events=0;
  216. if(state->detect!=prev_state->detect){
  217. DEBUG(2, "%s(): card detect value %un", 
  218. __FUNCTION__, state->detect);
  219. events |= mask&SS_DETECT;
  220. }
  221. if(state->ready!=prev_state->ready){
  222. DEBUG(2, "%s(): card ready value %un", 
  223. __FUNCTION__, state->ready);
  224. events |= mask&((flags&SS_IOCARD)?0:SS_READY);
  225. }
  226. *prev_state=*state;
  227. return events;
  228. }  /* au1000_pcmcia_events() */
  229. /* 
  230.  * Au1000_pcmcia_task_handler()
  231.  * Processes socket events.
  232.  */
  233. static void au1000_pcmcia_task_handler(void *data) 
  234. {
  235. struct pcmcia_state state;
  236. int i, events, irq_status;
  237. for(i=0; i<socket_count; i++)  {
  238. if((irq_status = pcmcia_low_level->socket_state(i, &state))<0)
  239. printk(KERN_ERR "low-level PCMCIA errorn");
  240. events = au1000_pcmcia_events(&state, 
  241. &pcmcia_socket[i].k_state, 
  242. pcmcia_socket[i].cs_state.csc_mask, 
  243. pcmcia_socket[i].cs_state.flags);
  244. if(pcmcia_socket[i].handler!=NULL) {
  245. pcmcia_socket[i].handler(pcmcia_socket[i].handler_info,
  246. events);
  247. }
  248. }
  249. }  /* au1000_pcmcia_task_handler() */
  250. static struct tq_struct au1000_pcmcia_task = {
  251. routine: au1000_pcmcia_task_handler
  252. };
  253. static void au1000_pcmcia_poll_event(unsigned long dummy)
  254. {
  255. poll_timer.function = au1000_pcmcia_poll_event;
  256. poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD;
  257. add_timer(&poll_timer);
  258. schedule_task(&au1000_pcmcia_task);
  259. }
  260. /* 
  261.  * au1000_pcmcia_interrupt()
  262.  * The actual interrupt work is performed by au1000_pcmcia_task(), 
  263.  * because the Card Services event handling code performs scheduling 
  264.  * operations which cannot be executed from within an interrupt context.
  265.  */
  266. static void 
  267. au1000_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs)
  268. {
  269. schedule_task(&au1000_pcmcia_task);
  270. }
  271. static int 
  272. au1000_pcmcia_register_callback(unsigned int sock, 
  273. void (*handler)(void *, unsigned int), void *info)
  274. {
  275. if(handler==NULL){
  276. pcmcia_socket[sock].handler=NULL;
  277. MOD_DEC_USE_COUNT;
  278. } else {
  279. MOD_INC_USE_COUNT;
  280. pcmcia_socket[sock].handler=handler;
  281. pcmcia_socket[sock].handler_info=info;
  282. }
  283. return 0;
  284. }
  285. /* au1000_pcmcia_inquire_socket()
  286.  *
  287.  * From the sa1100 socket driver : 
  288.  *
  289.  * Implements the inquire_socket() operation for the in-kernel PCMCIA
  290.  * service (formerly SS_InquireSocket in Card Services).  We set 
  291.  * SS_CAP_STATIC_MAP, which disables the memory resource database check. 
  292.  * (Mapped memory is set up within the socket driver itself.)
  293.  *
  294.  * In conjunction with the STATIC_MAP capability is a new field,
  295.  * `io_offset', recommended by David Hinds. Rather than go through
  296.  * the SetIOMap interface (which is not quite suited for communicating
  297.  * window locations up from the socket driver), we just pass up 
  298.  * an offset which is applied to client-requested base I/O addresses
  299.  * in alloc_io_space().
  300.  *
  301.  * Returns: 0 on success, -1 if no pin has been configured for `sock'
  302.  */
  303. static int au1000_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap)
  304. {
  305. struct pcmcia_irq_info irq_info;
  306. if(sock > socket_count){
  307. printk(KERN_ERR "au1000: socket %u not configuredn", sock);
  308. return -1;
  309. }
  310. /* from the sa1100_generic driver: */
  311. /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
  312. *   force_low argument to validate_mem() in rsrc_mgr.c -- since in
  313. *   general, the mapped * addresses of the PCMCIA memory regions
  314. *   will not be within 0xffff, setting force_low would be
  315. *   undesirable.
  316. *
  317. * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
  318. *   resource database; we instead pass up physical address ranges
  319. *   and allow other parts of Card Services to deal with remapping.
  320. *
  321. * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
  322. *   not 32-bit CardBus devices.
  323. */
  324. cap->features=(SS_CAP_PAGE_REGS  | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
  325. irq_info.sock=sock;
  326. irq_info.irq=-1;
  327. if(pcmcia_low_level->get_irq_info(&irq_info)<0){
  328. printk(KERN_ERR "Error obtaining IRQ info socket %un", sock);
  329. return -1;
  330. }
  331. cap->irq_mask=0;
  332. cap->map_size=MAP_SIZE;
  333. cap->pci_irq=irq_info.irq;
  334. cap->io_offset=pcmcia_socket[sock].virt_io;
  335. return 0;
  336. }  /* au1000_pcmcia_inquire_socket() */
  337. static int 
  338. au1000_pcmcia_get_status(unsigned int sock, unsigned int *status)
  339. {
  340. struct pcmcia_state state;
  341. if((pcmcia_low_level->socket_state(sock, &state))<0){
  342. printk(KERN_ERR "Unable to get PCMCIA status from kernel.n");
  343. return -1;
  344. }
  345. pcmcia_socket[sock].k_state = state;
  346. *status = state.detect?SS_DETECT:0;
  347. *status |= state.ready?SS_READY:0;
  348. *status |= pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;
  349. if(pcmcia_socket[sock].cs_state.flags&SS_IOCARD)
  350. *status |= state.bvd1?SS_STSCHG:0;
  351. else {
  352. if(state.bvd1==0)
  353. *status |= SS_BATDEAD;
  354. else if(state.bvd2 == 0)
  355. *status |= SS_BATWARN;
  356. }
  357. *status|=state.vs_3v?SS_3VCARD:0;
  358. *status|=state.vs_Xv?SS_XVCARD:0;
  359. DEBUG(2, "tstatus: %s%s%s%s%s%s%s%sn",
  360. (*status&SS_DETECT)?"DETECT ":"",
  361. (*status&SS_READY)?"READY ":"", 
  362. (*status&SS_BATDEAD)?"BATDEAD ":"",
  363. (*status&SS_BATWARN)?"BATWARN ":"",
  364. (*status&SS_POWERON)?"POWERON ":"",
  365. (*status&SS_STSCHG)?"STSCHG ":"",
  366. (*status&SS_3VCARD)?"3VCARD ":"",
  367. (*status&SS_XVCARD)?"XVCARD ":"");
  368. return 0;
  369. }  /* au1000_pcmcia_get_status() */
  370. static int 
  371. au1000_pcmcia_get_socket(unsigned int sock, socket_state_t *state)
  372. {
  373. *state = pcmcia_socket[sock].cs_state;
  374. return 0;
  375. }
  376. static int 
  377. au1000_pcmcia_set_socket(unsigned int sock, socket_state_t *state)
  378. {
  379. struct pcmcia_configure configure;
  380. DEBUG(2, "tmask:  %s%s%s%s%s%sntflags: %s%s%s%s%s%sn"
  381. "tVcc %d  Vpp %d  irq %dn",
  382. (state->csc_mask==0)?"<NONE>":"",
  383. (state->csc_mask&SS_DETECT)?"DETECT ":"",
  384. (state->csc_mask&SS_READY)?"READY ":"",
  385. (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
  386. (state->csc_mask&SS_BATWARN)?"BATWARN ":"",
  387. (state->csc_mask&SS_STSCHG)?"STSCHG ":"",
  388. (state->flags==0)?"<NONE>":"",
  389. (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
  390. (state->flags&SS_IOCARD)?"IOCARD ":"",
  391. (state->flags&SS_RESET)?"RESET ":"",
  392. (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
  393. (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
  394. state->Vcc, state->Vpp, state->io_irq);
  395. configure.sock=sock;
  396. configure.vcc=state->Vcc;
  397. configure.vpp=state->Vpp;
  398. configure.output=(state->flags&SS_OUTPUT_ENA)?1:0;
  399. configure.speaker=(state->flags&SS_SPKR_ENA)?1:0;
  400. configure.reset=(state->flags&SS_RESET)?1:0;
  401. if(pcmcia_low_level->configure_socket(&configure)<0){
  402. printk(KERN_ERR "Unable to configure socket %un", sock);
  403. return -1;
  404. }
  405. pcmcia_socket[sock].cs_state = *state;
  406. return 0;
  407. }  /* au1000_pcmcia_set_socket() */
  408. static int 
  409. au1000_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map)
  410. {
  411. DEBUG(1, "au1000_pcmcia_get_io_map: sock %dn", sock);
  412. if(map->map>=MAX_IO_WIN){
  413. printk(KERN_ERR "%s(): map (%d) out of rangen", 
  414. __FUNCTION__, map->map);
  415. return -1;
  416. }
  417. *map=pcmcia_socket[sock].io_map[map->map];
  418. return 0;
  419. }
  420. int 
  421. au1000_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map)
  422. {
  423. unsigned int speed;
  424. unsigned long start;
  425. if(map->map>=MAX_IO_WIN){
  426. printk(KERN_ERR "%s(): map (%d) out of rangen", 
  427. __FUNCTION__, map->map);
  428. return -1;
  429. }
  430. if(map->flags&MAP_ACTIVE){
  431. speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED;
  432. pcmcia_socket[sock].speed_io=speed;
  433. }
  434. start=map->start;
  435. if(map->stop==1) {
  436. map->stop=PAGE_SIZE-1;
  437. }
  438. map->start=pcmcia_socket[sock].virt_io;
  439. map->stop=map->start+(map->stop-start);
  440. pcmcia_socket[sock].io_map[map->map]=*map;
  441. DEBUG(3, "set_io_map %d start %x stop %xn", 
  442. map->map, map->start, map->stop);
  443. return 0;
  444. }  /* au1000_pcmcia_set_io_map() */
  445. static int 
  446. au1000_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map)
  447. {
  448. if(map->map>=MAX_WIN) {
  449. printk(KERN_ERR "%s(): map (%d) out of rangen", 
  450. __FUNCTION__, map->map);
  451. return -1;
  452. }
  453. *map=pcmcia_socket[sock].mem_map[map->map];
  454. return 0;
  455. }
  456. static int 
  457. au1000_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map)
  458. {
  459. unsigned int speed;
  460. unsigned long start;
  461. u_long flags;
  462. if(map->map>=MAX_WIN){
  463. printk(KERN_ERR "%s(): map (%d) out of rangen", 
  464. __FUNCTION__, map->map);
  465. return -1;
  466. }
  467. if(map->flags&MAP_ACTIVE){
  468. speed=(map->speed>0)?map->speed:AU1000_PCMCIA_MEM_SPEED;
  469. /* TBD */
  470. if(map->flags&MAP_ATTRIB){
  471. pcmcia_socket[sock].speed_attr=speed;
  472. else {
  473. pcmcia_socket[sock].speed_mem=speed;
  474. }
  475. }
  476. save_flags(flags);
  477. cli();
  478. start=map->sys_start;
  479. if(map->sys_stop==0)
  480. map->sys_stop=MAP_SIZE-1;
  481. if (map->flags & MAP_ATTRIB) {
  482. map->sys_start = pcmcia_socket[sock].phys_attr + 
  483. map->card_start;
  484. }
  485. else {
  486. map->sys_start = pcmcia_socket[sock].phys_mem + 
  487. map->card_start;
  488. }
  489. map->sys_stop=map->sys_start+(map->sys_stop-start);
  490. pcmcia_socket[sock].mem_map[map->map]=*map;
  491. restore_flags(flags);
  492. DEBUG(3, "set_mem_map %d start %x stop %x card_start %xn", 
  493. map->map, map->sys_start, map->sys_stop, 
  494. map->card_start);
  495. return 0;
  496. }  /* au1000_pcmcia_set_mem_map() */
  497. #if defined(CONFIG_PROC_FS)
  498. static void 
  499. au1000_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base)
  500. {
  501. struct proc_dir_entry *entry;
  502. if((entry=create_proc_entry("status", 0, base))==NULL){
  503. printk(KERN_ERR "Unable to install "status" procfs entryn");
  504. return;
  505. }
  506. entry->read_proc=au1000_pcmcia_proc_status;
  507. entry->data=(void *)sock;
  508. }
  509. /* au1000_pcmcia_proc_status()
  510.  * Implements the /proc/bus/pccard/??/status file.
  511.  *
  512.  * Returns: the number of characters added to the buffer
  513.  */
  514. static int 
  515. au1000_pcmcia_proc_status(char *buf, char **start, off_t pos, 
  516. int count, int *eof, void *data)
  517. {
  518. char *p=buf;
  519. unsigned int sock=(unsigned int)data;
  520. p+=sprintf(p, "k_flags  : %s%s%s%s%s%s%sn", 
  521.      pcmcia_socket[sock].k_state.detect?"detect ":"",
  522.      pcmcia_socket[sock].k_state.ready?"ready ":"",
  523.      pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",
  524.      pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",
  525.      pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",
  526.      pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",
  527.      pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");
  528. p+=sprintf(p, "status   : %s%s%s%s%s%s%s%s%sn",
  529.      pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",
  530.      pcmcia_socket[sock].k_state.ready?"SS_READY ":"",
  531.      pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",
  532.      pcmcia_socket[sock].cs_state.flags&SS_IOCARD?
  533.      "SS_IOCARD ":"",
  534.      (pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&
  535.       pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",
  536.      ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
  537.       (pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",
  538.      ((pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
  539.       (pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",
  540.      pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",
  541.      pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");
  542. p+=sprintf(p, "mask     : %s%s%s%s%sn",
  543.      pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?
  544.      "SS_DETECT ":"",
  545.      pcmcia_socket[sock].cs_state.csc_mask&SS_READY?
  546.      "SS_READY ":"",
  547.      pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?
  548.      "SS_BATDEAD ":"",
  549.      pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?
  550.      "SS_BATWARN ":"",
  551.      pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?
  552.      "SS_STSCHG ":"");
  553. p+=sprintf(p, "cs_flags : %s%s%s%s%sn",
  554.      pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?
  555.      "SS_PWR_AUTO ":"",
  556.      pcmcia_socket[sock].cs_state.flags&SS_IOCARD?
  557.      "SS_IOCARD ":"",
  558.      pcmcia_socket[sock].cs_state.flags&SS_RESET?
  559.      "SS_RESET ":"",
  560.      pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?
  561.      "SS_SPKR_ENA ":"",
  562.      pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?
  563.      "SS_OUTPUT_ENA ":"");
  564. p+=sprintf(p, "Vcc      : %dn", pcmcia_socket[sock].cs_state.Vcc);
  565. p+=sprintf(p, "Vpp      : %dn", pcmcia_socket[sock].cs_state.Vpp);
  566. p+=sprintf(p, "irq      : %dn", pcmcia_socket[sock].cs_state.io_irq);
  567. p+=sprintf(p, "I/O      : %un", pcmcia_socket[sock].speed_io);
  568. p+=sprintf(p, "attribute: %un", pcmcia_socket[sock].speed_attr);
  569. p+=sprintf(p, "common   : %un", pcmcia_socket[sock].speed_mem);
  570. return p-buf;
  571. }
  572. #endif  /* defined(CONFIG_PROC_FS) */