aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/pcmcia/cm4040_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/pcmcia/cm4040_cs.c')
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c133
1 files changed, 44 insertions, 89 deletions
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 466e33bab029..29efa64580a8 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -41,7 +41,7 @@
41 41
42 42
43#ifdef PCMCIA_DEBUG 43#ifdef PCMCIA_DEBUG
44#define reader_to_dev(x) (&handle_to_dev(x->link.handle)) 44#define reader_to_dev(x) (&handle_to_dev(x->p_dev->handle))
45static int pc_debug = PCMCIA_DEBUG; 45static int pc_debug = PCMCIA_DEBUG;
46module_param(pc_debug, int, 0600); 46module_param(pc_debug, int, 0600);
47#define DEBUGP(n, rdr, x, args...) do { \ 47#define DEBUGP(n, rdr, x, args...) do { \
@@ -65,7 +65,7 @@ static char *version =
65/* how often to poll for fifo status change */ 65/* how often to poll for fifo status change */
66#define POLL_PERIOD msecs_to_jiffies(10) 66#define POLL_PERIOD msecs_to_jiffies(10)
67 67
68static void reader_release(dev_link_t *link); 68static void reader_release(struct pcmcia_device *link);
69 69
70static int major; 70static int major;
71static struct class *cmx_class; 71static struct class *cmx_class;
@@ -74,7 +74,7 @@ static struct class *cmx_class;
74#define BS_WRITABLE 0x02 74#define BS_WRITABLE 0x02
75 75
76struct reader_dev { 76struct reader_dev {
77 dev_link_t link; 77 struct pcmcia_device *p_dev;
78 dev_node_t node; 78 dev_node_t node;
79 wait_queue_head_t devq; 79 wait_queue_head_t devq;
80 wait_queue_head_t poll_wait; 80 wait_queue_head_t poll_wait;
@@ -87,7 +87,7 @@ struct reader_dev {
87 struct timer_list poll_timer; 87 struct timer_list poll_timer;
88}; 88};
89 89
90static dev_link_t *dev_table[CM_MAX_DEV]; 90static struct pcmcia_device *dev_table[CM_MAX_DEV];
91 91
92#ifndef PCMCIA_DEBUG 92#ifndef PCMCIA_DEBUG
93#define xoutb outb 93#define xoutb outb
@@ -116,7 +116,7 @@ static inline unsigned char xinb(unsigned short port)
116static void cm4040_do_poll(unsigned long dummy) 116static void cm4040_do_poll(unsigned long dummy)
117{ 117{
118 struct reader_dev *dev = (struct reader_dev *) dummy; 118 struct reader_dev *dev = (struct reader_dev *) dummy;
119 unsigned int obs = xinb(dev->link.io.BasePort1 119 unsigned int obs = xinb(dev->p_dev->io.BasePort1
120 + REG_OFFSET_BUFFER_STATUS); 120 + REG_OFFSET_BUFFER_STATUS);
121 121
122 if ((obs & BSR_BULK_IN_FULL)) { 122 if ((obs & BSR_BULK_IN_FULL)) {
@@ -147,7 +147,7 @@ static void cm4040_stop_poll(struct reader_dev *dev)
147static int wait_for_bulk_out_ready(struct reader_dev *dev) 147static int wait_for_bulk_out_ready(struct reader_dev *dev)
148{ 148{
149 int i, rc; 149 int i, rc;
150 int iobase = dev->link.io.BasePort1; 150 int iobase = dev->p_dev->io.BasePort1;
151 151
152 for (i = 0; i < POLL_LOOP_COUNT; i++) { 152 for (i = 0; i < POLL_LOOP_COUNT; i++) {
153 if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) 153 if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
@@ -177,7 +177,7 @@ static int wait_for_bulk_out_ready(struct reader_dev *dev)
177/* Write to Sync Control Register */ 177/* Write to Sync Control Register */
178static int write_sync_reg(unsigned char val, struct reader_dev *dev) 178static int write_sync_reg(unsigned char val, struct reader_dev *dev)
179{ 179{
180 int iobase = dev->link.io.BasePort1; 180 int iobase = dev->p_dev->io.BasePort1;
181 int rc; 181 int rc;
182 182
183 rc = wait_for_bulk_out_ready(dev); 183 rc = wait_for_bulk_out_ready(dev);
@@ -195,7 +195,7 @@ static int write_sync_reg(unsigned char val, struct reader_dev *dev)
195static int wait_for_bulk_in_ready(struct reader_dev *dev) 195static int wait_for_bulk_in_ready(struct reader_dev *dev)
196{ 196{
197 int i, rc; 197 int i, rc;
198 int iobase = dev->link.io.BasePort1; 198 int iobase = dev->p_dev->io.BasePort1;
199 199
200 for (i = 0; i < POLL_LOOP_COUNT; i++) { 200 for (i = 0; i < POLL_LOOP_COUNT; i++) {
201 if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS) 201 if ((xinb(iobase + REG_OFFSET_BUFFER_STATUS)
@@ -225,7 +225,7 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
225 size_t count, loff_t *ppos) 225 size_t count, loff_t *ppos)
226{ 226{
227 struct reader_dev *dev = filp->private_data; 227 struct reader_dev *dev = filp->private_data;
228 int iobase = dev->link.io.BasePort1; 228 int iobase = dev->p_dev->io.BasePort1;
229 size_t bytes_to_read; 229 size_t bytes_to_read;
230 unsigned long i; 230 unsigned long i;
231 size_t min_bytes_to_read; 231 size_t min_bytes_to_read;
@@ -246,7 +246,7 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
246 return -EAGAIN; 246 return -EAGAIN;
247 } 247 }
248 248
249 if ((dev->link.state & DEV_PRESENT)==0) 249 if (!pcmcia_dev_present(dev->p_dev))
250 return -ENODEV; 250 return -ENODEV;
251 251
252 for (i = 0; i < 5; i++) { 252 for (i = 0; i < 5; i++) {
@@ -328,7 +328,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf,
328 size_t count, loff_t *ppos) 328 size_t count, loff_t *ppos)
329{ 329{
330 struct reader_dev *dev = filp->private_data; 330 struct reader_dev *dev = filp->private_data;
331 int iobase = dev->link.io.BasePort1; 331 int iobase = dev->p_dev->io.BasePort1;
332 ssize_t rc; 332 ssize_t rc;
333 int i; 333 int i;
334 unsigned int bytes_to_write; 334 unsigned int bytes_to_write;
@@ -351,7 +351,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf,
351 return -EAGAIN; 351 return -EAGAIN;
352 } 352 }
353 353
354 if ((dev->link.state & DEV_PRESENT) == 0) 354 if (!pcmcia_dev_present(dev->p_dev))
355 return -ENODEV; 355 return -ENODEV;
356 356
357 bytes_to_write = count; 357 bytes_to_write = count;
@@ -445,14 +445,14 @@ static unsigned int cm4040_poll(struct file *filp, poll_table *wait)
445static int cm4040_open(struct inode *inode, struct file *filp) 445static int cm4040_open(struct inode *inode, struct file *filp)
446{ 446{
447 struct reader_dev *dev; 447 struct reader_dev *dev;
448 dev_link_t *link; 448 struct pcmcia_device *link;
449 int minor = iminor(inode); 449 int minor = iminor(inode);
450 450
451 if (minor >= CM_MAX_DEV) 451 if (minor >= CM_MAX_DEV)
452 return -ENODEV; 452 return -ENODEV;
453 453
454 link = dev_table[minor]; 454 link = dev_table[minor];
455 if (link == NULL || !(DEV_OK(link))) 455 if (link == NULL || !pcmcia_dev_present(link))
456 return -ENODEV; 456 return -ENODEV;
457 457
458 if (link->open) 458 if (link->open)
@@ -478,7 +478,7 @@ static int cm4040_open(struct inode *inode, struct file *filp)
478static int cm4040_close(struct inode *inode, struct file *filp) 478static int cm4040_close(struct inode *inode, struct file *filp)
479{ 479{
480 struct reader_dev *dev = filp->private_data; 480 struct reader_dev *dev = filp->private_data;
481 dev_link_t *link; 481 struct pcmcia_device *link;
482 int minor = iminor(inode); 482 int minor = iminor(inode);
483 483
484 DEBUGP(2, dev, "-> cm4040_close(maj/min=%d.%d)\n", imajor(inode), 484 DEBUGP(2, dev, "-> cm4040_close(maj/min=%d.%d)\n", imajor(inode),
@@ -500,7 +500,7 @@ static int cm4040_close(struct inode *inode, struct file *filp)
500 return 0; 500 return 0;
501} 501}
502 502
503static void cm4040_reader_release(dev_link_t *link) 503static void cm4040_reader_release(struct pcmcia_device *link)
504{ 504{
505 struct reader_dev *dev = link->priv; 505 struct reader_dev *dev = link->priv;
506 506
@@ -514,60 +514,49 @@ static void cm4040_reader_release(dev_link_t *link)
514 return; 514 return;
515} 515}
516 516
517static void reader_config(dev_link_t *link, int devno) 517static int reader_config(struct pcmcia_device *link, int devno)
518{ 518{
519 client_handle_t handle;
520 struct reader_dev *dev; 519 struct reader_dev *dev;
521 tuple_t tuple; 520 tuple_t tuple;
522 cisparse_t parse; 521 cisparse_t parse;
523 config_info_t conf;
524 u_char buf[64]; 522 u_char buf[64];
525 int fail_fn, fail_rc; 523 int fail_fn, fail_rc;
526 int rc; 524 int rc;
527 525
528 handle = link->handle;
529
530 tuple.DesiredTuple = CISTPL_CONFIG; 526 tuple.DesiredTuple = CISTPL_CONFIG;
531 tuple.Attributes = 0; 527 tuple.Attributes = 0;
532 tuple.TupleData = buf; 528 tuple.TupleData = buf;
533 tuple.TupleDataMax = sizeof(buf); 529 tuple.TupleDataMax = sizeof(buf);
534 tuple.TupleOffset = 0; 530 tuple.TupleOffset = 0;
535 531
536 if ((fail_rc = pcmcia_get_first_tuple(handle, &tuple)) != CS_SUCCESS) { 532 if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) {
537 fail_fn = GetFirstTuple; 533 fail_fn = GetFirstTuple;
538 goto cs_failed; 534 goto cs_failed;
539 } 535 }
540 if ((fail_rc = pcmcia_get_tuple_data(handle, &tuple)) != CS_SUCCESS) { 536 if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) {
541 fail_fn = GetTupleData; 537 fail_fn = GetTupleData;
542 goto cs_failed; 538 goto cs_failed;
543 } 539 }
544 if ((fail_rc = pcmcia_parse_tuple(handle, &tuple, &parse)) 540 if ((fail_rc = pcmcia_parse_tuple(link, &tuple, &parse))
545 != CS_SUCCESS) { 541 != CS_SUCCESS) {
546 fail_fn = ParseTuple; 542 fail_fn = ParseTuple;
547 goto cs_failed; 543 goto cs_failed;
548 } 544 }
549 if ((fail_rc = pcmcia_get_configuration_info(handle, &conf))
550 != CS_SUCCESS) {
551 fail_fn = GetConfigurationInfo;
552 goto cs_failed;
553 }
554 545
555 link->state |= DEV_CONFIG;
556 link->conf.ConfigBase = parse.config.base; 546 link->conf.ConfigBase = parse.config.base;
557 link->conf.Present = parse.config.rmask[0]; 547 link->conf.Present = parse.config.rmask[0];
558 link->conf.Vcc = conf.Vcc;
559 548
560 link->io.BasePort2 = 0; 549 link->io.BasePort2 = 0;
561 link->io.NumPorts2 = 0; 550 link->io.NumPorts2 = 0;
562 link->io.Attributes2 = 0; 551 link->io.Attributes2 = 0;
563 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 552 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
564 for (rc = pcmcia_get_first_tuple(handle, &tuple); 553 for (rc = pcmcia_get_first_tuple(link, &tuple);
565 rc == CS_SUCCESS; 554 rc == CS_SUCCESS;
566 rc = pcmcia_get_next_tuple(handle, &tuple)) { 555 rc = pcmcia_get_next_tuple(link, &tuple)) {
567 rc = pcmcia_get_tuple_data(handle, &tuple); 556 rc = pcmcia_get_tuple_data(link, &tuple);
568 if (rc != CS_SUCCESS) 557 if (rc != CS_SUCCESS)
569 continue; 558 continue;
570 rc = pcmcia_parse_tuple(handle, &tuple, &parse); 559 rc = pcmcia_parse_tuple(link, &tuple, &parse);
571 if (rc != CS_SUCCESS) 560 if (rc != CS_SUCCESS)
572 continue; 561 continue;
573 562
@@ -585,13 +574,13 @@ static void reader_config(dev_link_t *link, int devno)
585 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 574 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
586 link->io.IOAddrLines = parse.cftable_entry.io.flags 575 link->io.IOAddrLines = parse.cftable_entry.io.flags
587 & CISTPL_IO_LINES_MASK; 576 & CISTPL_IO_LINES_MASK;
588 rc = pcmcia_request_io(handle, &link->io); 577 rc = pcmcia_request_io(link, &link->io);
589 578
590 dev_printk(KERN_INFO, &handle_to_dev(handle), "foo"); 579 dev_printk(KERN_INFO, &handle_to_dev(link), "foo");
591 if (rc == CS_SUCCESS) 580 if (rc == CS_SUCCESS)
592 break; 581 break;
593 else 582 else
594 dev_printk(KERN_INFO, &handle_to_dev(handle), 583 dev_printk(KERN_INFO, &handle_to_dev(link),
595 "pcmcia_request_io failed 0x%x\n", rc); 584 "pcmcia_request_io failed 0x%x\n", rc);
596 } 585 }
597 if (rc != CS_SUCCESS) 586 if (rc != CS_SUCCESS)
@@ -599,10 +588,10 @@ static void reader_config(dev_link_t *link, int devno)
599 588
600 link->conf.IntType = 00000002; 589 link->conf.IntType = 00000002;
601 590
602 if ((fail_rc = pcmcia_request_configuration(handle,&link->conf)) 591 if ((fail_rc = pcmcia_request_configuration(link,&link->conf))
603 !=CS_SUCCESS) { 592 !=CS_SUCCESS) {
604 fail_fn = RequestConfiguration; 593 fail_fn = RequestConfiguration;
605 dev_printk(KERN_INFO, &handle_to_dev(handle), 594 dev_printk(KERN_INFO, &handle_to_dev(link),
606 "pcmcia_request_configuration failed 0x%x\n", 595 "pcmcia_request_configuration failed 0x%x\n",
607 fail_rc); 596 fail_rc);
608 goto cs_release; 597 goto cs_release;
@@ -612,57 +601,31 @@ static void reader_config(dev_link_t *link, int devno)
612 sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno); 601 sprintf(dev->node.dev_name, DEVICE_NAME "%d", devno);
613 dev->node.major = major; 602 dev->node.major = major;
614 dev->node.minor = devno; 603 dev->node.minor = devno;
615 dev->node.next = NULL; 604 dev->node.next = &dev->node;
616 link->dev = &dev->node;
617 link->state &= ~DEV_CONFIG_PENDING;
618 605
619 DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno, 606 DEBUGP(2, dev, "device " DEVICE_NAME "%d at 0x%.4x-0x%.4x\n", devno,
620 link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1); 607 link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1);
621 DEBUGP(2, dev, "<- reader_config (succ)\n"); 608 DEBUGP(2, dev, "<- reader_config (succ)\n");
622 609
623 return; 610 return 0;
624 611
625cs_failed: 612cs_failed:
626 cs_error(handle, fail_fn, fail_rc); 613 cs_error(link, fail_fn, fail_rc);
627cs_release: 614cs_release:
628 reader_release(link); 615 reader_release(link);
629 link->state &= ~DEV_CONFIG_PENDING; 616 return -ENODEV;
630}
631
632static int reader_suspend(struct pcmcia_device *p_dev)
633{
634 dev_link_t *link = dev_to_instance(p_dev);
635
636 link->state |= DEV_SUSPEND;
637 if (link->state & DEV_CONFIG)
638 pcmcia_release_configuration(link->handle);
639
640 return 0;
641} 617}
642 618
643static int reader_resume(struct pcmcia_device *p_dev) 619static void reader_release(struct pcmcia_device *link)
644{
645 dev_link_t *link = dev_to_instance(p_dev);
646
647 link->state &= ~DEV_SUSPEND;
648 if (link->state & DEV_CONFIG)
649 pcmcia_request_configuration(link->handle, &link->conf);
650
651 return 0;
652}
653
654static void reader_release(dev_link_t *link)
655{ 620{
656 cm4040_reader_release(link->priv); 621 cm4040_reader_release(link->priv);
657 pcmcia_release_configuration(link->handle); 622 pcmcia_disable_device(link);
658 pcmcia_release_io(link->handle, &link->io);
659} 623}
660 624
661static int reader_attach(struct pcmcia_device *p_dev) 625static int reader_probe(struct pcmcia_device *link)
662{ 626{
663 struct reader_dev *dev; 627 struct reader_dev *dev;
664 dev_link_t *link; 628 int i, ret;
665 int i;
666 629
667 for (i = 0; i < CM_MAX_DEV; i++) { 630 for (i = 0; i < CM_MAX_DEV; i++) {
668 if (dev_table[i] == NULL) 631 if (dev_table[i] == NULL)
@@ -679,8 +642,8 @@ static int reader_attach(struct pcmcia_device *p_dev)
679 dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT; 642 dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;
680 dev->buffer_status = 0; 643 dev->buffer_status = 0;
681 644
682 link = &dev->link;
683 link->priv = dev; 645 link->priv = dev;
646 dev->p_dev = link;
684 647
685 link->conf.IntType = INT_MEMORY_AND_IO; 648 link->conf.IntType = INT_MEMORY_AND_IO;
686 dev_table[i] = link; 649 dev_table[i] = link;
@@ -692,11 +655,9 @@ static int reader_attach(struct pcmcia_device *p_dev)
692 init_timer(&dev->poll_timer); 655 init_timer(&dev->poll_timer);
693 dev->poll_timer.function = &cm4040_do_poll; 656 dev->poll_timer.function = &cm4040_do_poll;
694 657
695 link->handle = p_dev; 658 ret = reader_config(link, i);
696 p_dev->instance = link; 659 if (ret)
697 660 return ret;
698 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
699 reader_config(link, i);
700 661
701 class_device_create(cmx_class, NULL, MKDEV(major, i), NULL, 662 class_device_create(cmx_class, NULL, MKDEV(major, i), NULL,
702 "cmx%d", i); 663 "cmx%d", i);
@@ -704,9 +665,8 @@ static int reader_attach(struct pcmcia_device *p_dev)
704 return 0; 665 return 0;
705} 666}
706 667
707static void reader_detach(struct pcmcia_device *p_dev) 668static void reader_detach(struct pcmcia_device *link)
708{ 669{
709 dev_link_t *link = dev_to_instance(p_dev);
710 struct reader_dev *dev = link->priv; 670 struct reader_dev *dev = link->priv;
711 int devno; 671 int devno;
712 672
@@ -718,10 +678,7 @@ static void reader_detach(struct pcmcia_device *p_dev)
718 if (devno == CM_MAX_DEV) 678 if (devno == CM_MAX_DEV)
719 return; 679 return;
720 680
721 link->state &= ~DEV_PRESENT; 681 reader_release(link);
722
723 if (link->state & DEV_CONFIG)
724 reader_release(link);
725 682
726 dev_table[devno] = NULL; 683 dev_table[devno] = NULL;
727 kfree(dev); 684 kfree(dev);
@@ -753,10 +710,8 @@ static struct pcmcia_driver reader_driver = {
753 .drv = { 710 .drv = {
754 .name = "cm4040_cs", 711 .name = "cm4040_cs",
755 }, 712 },
756 .probe = reader_attach, 713 .probe = reader_probe,
757 .remove = reader_detach, 714 .remove = reader_detach,
758 .suspend = reader_suspend,
759 .resume = reader_resume,
760 .id_table = cm4040_ids, 715 .id_table = cm4040_ids,
761}; 716};
762 717