aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/maps/pcmciamtd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/maps/pcmciamtd.c')
-rw-r--r--drivers/mtd/maps/pcmciamtd.c117
1 files changed, 49 insertions, 68 deletions
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c
index f988c817e196..d27f4129afd3 100644
--- a/drivers/mtd/maps/pcmciamtd.c
+++ b/drivers/mtd/maps/pcmciamtd.c
@@ -54,7 +54,7 @@ static const int debug = 0;
54#define MAX_PCMCIA_ADDR 0x4000000 54#define MAX_PCMCIA_ADDR 0x4000000
55 55
56struct pcmciamtd_dev { 56struct pcmciamtd_dev {
57 dev_link_t link; /* PCMCIA link */ 57 struct pcmcia_device *p_dev;
58 dev_node_t node; /* device node */ 58 dev_node_t node; /* device node */
59 caddr_t win_base; /* ioremapped address of PCMCIA window */ 59 caddr_t win_base; /* ioremapped address of PCMCIA window */
60 unsigned int win_size; /* size of window */ 60 unsigned int win_size; /* size of window */
@@ -111,8 +111,8 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
111 memreq_t mrq; 111 memreq_t mrq;
112 int ret; 112 int ret;
113 113
114 if(!(dev->link.state & DEV_PRESENT)) { 114 if (!pcmcia_dev_present(dev->p_dev)) {
115 DEBUG(1, "device removed state = 0x%4.4X", dev->link.state); 115 DEBUG(1, "device removed");
116 return 0; 116 return 0;
117 } 117 }
118 118
@@ -122,7 +122,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
122 dev->offset, mrq.CardOffset); 122 dev->offset, mrq.CardOffset);
123 mrq.Page = 0; 123 mrq.Page = 0;
124 if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) { 124 if( (ret = pcmcia_map_mem_page(win, &mrq)) != CS_SUCCESS) {
125 cs_error(dev->link.handle, MapMemPage, ret); 125 cs_error(dev->p_dev, MapMemPage, ret);
126 return NULL; 126 return NULL;
127 } 127 }
128 dev->offset = mrq.CardOffset; 128 dev->offset = mrq.CardOffset;
@@ -238,7 +238,7 @@ static void pcmcia_copy_to_remap(struct map_info *map, unsigned long to, const v
238 238
239/* read/write{8,16} copy_{from,to} routines with direct access */ 239/* read/write{8,16} copy_{from,to} routines with direct access */
240 240
241#define DEV_REMOVED(x) (!(*(u_int *)x->map_priv_1 & DEV_PRESENT)) 241#define DEV_REMOVED(x) (!(pcmcia_dev_present(((struct pcmciamtd_dev *)map->map_priv_1)->p_dev)))
242 242
243static map_word pcmcia_read8(struct map_info *map, unsigned long ofs) 243static map_word pcmcia_read8(struct map_info *map, unsigned long ofs)
244{ 244{
@@ -319,7 +319,7 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f
319static void pcmciamtd_set_vpp(struct map_info *map, int on) 319static void pcmciamtd_set_vpp(struct map_info *map, int on)
320{ 320{
321 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1; 321 struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
322 dev_link_t *link = &dev->link; 322 struct pcmcia_device *link = dev->p_dev;
323 modconf_t mod; 323 modconf_t mod;
324 int ret; 324 int ret;
325 325
@@ -328,9 +328,9 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
328 mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0; 328 mod.Vpp1 = mod.Vpp2 = on ? dev->vpp : 0;
329 329
330 DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp); 330 DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
331 ret = pcmcia_modify_configuration(link->handle, &mod); 331 ret = pcmcia_modify_configuration(link, &mod);
332 if(ret != CS_SUCCESS) { 332 if(ret != CS_SUCCESS) {
333 cs_error(link->handle, ModifyConfiguration, ret); 333 cs_error(link, ModifyConfiguration, ret);
334 } 334 }
335} 335}
336 336
@@ -340,7 +340,7 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
340 * still open, this will be postponed until it is closed. 340 * still open, this will be postponed until it is closed.
341 */ 341 */
342 342
343static void pcmciamtd_release(dev_link_t *link) 343static void pcmciamtd_release(struct pcmcia_device *link)
344{ 344{
345 struct pcmciamtd_dev *dev = link->priv; 345 struct pcmciamtd_dev *dev = link->priv;
346 346
@@ -353,12 +353,11 @@ static void pcmciamtd_release(dev_link_t *link)
353 } 353 }
354 pcmcia_release_window(link->win); 354 pcmcia_release_window(link->win);
355 } 355 }
356 pcmcia_release_configuration(link->handle); 356 pcmcia_disable_device(link);
357 link->state &= ~DEV_CONFIG;
358} 357}
359 358
360 359
361static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_name) 360static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
362{ 361{
363 int rc; 362 int rc;
364 tuple_t tuple; 363 tuple_t tuple;
@@ -371,16 +370,16 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
371 tuple.TupleOffset = 0; 370 tuple.TupleOffset = 0;
372 tuple.DesiredTuple = RETURN_FIRST_TUPLE; 371 tuple.DesiredTuple = RETURN_FIRST_TUPLE;
373 372
374 rc = pcmcia_get_first_tuple(link->handle, &tuple); 373 rc = pcmcia_get_first_tuple(link, &tuple);
375 while(rc == CS_SUCCESS) { 374 while(rc == CS_SUCCESS) {
376 rc = pcmcia_get_tuple_data(link->handle, &tuple); 375 rc = pcmcia_get_tuple_data(link, &tuple);
377 if(rc != CS_SUCCESS) { 376 if(rc != CS_SUCCESS) {
378 cs_error(link->handle, GetTupleData, rc); 377 cs_error(link, GetTupleData, rc);
379 break; 378 break;
380 } 379 }
381 rc = pcmcia_parse_tuple(link->handle, &tuple, &parse); 380 rc = pcmcia_parse_tuple(link, &tuple, &parse);
382 if(rc != CS_SUCCESS) { 381 if(rc != CS_SUCCESS) {
383 cs_error(link->handle, ParseTuple, rc); 382 cs_error(link, ParseTuple, rc);
384 break; 383 break;
385 } 384 }
386 385
@@ -451,7 +450,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
451 DEBUG(2, "Unknown tuple code %d", tuple.TupleCode); 450 DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
452 } 451 }
453 452
454 rc = pcmcia_get_next_tuple(link->handle, &tuple); 453 rc = pcmcia_get_next_tuple(link, &tuple);
455 } 454 }
456 if(!dev->pcmcia_map.size) 455 if(!dev->pcmcia_map.size)
457 dev->pcmcia_map.size = MAX_PCMCIA_ADDR; 456 dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
@@ -488,7 +487,7 @@ static void card_settings(struct pcmciamtd_dev *dev, dev_link_t *link, int *new_
488#define CS_CHECK(fn, ret) \ 487#define CS_CHECK(fn, ret) \
489do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 488do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
490 489
491static void pcmciamtd_config(dev_link_t *link) 490static int pcmciamtd_config(struct pcmcia_device *link)
492{ 491{
493 struct pcmciamtd_dev *dev = link->priv; 492 struct pcmciamtd_dev *dev = link->priv;
494 struct mtd_info *mtd = NULL; 493 struct mtd_info *mtd = NULL;
@@ -504,13 +503,10 @@ static void pcmciamtd_config(dev_link_t *link)
504 503
505 DEBUG(3, "link=0x%p", link); 504 DEBUG(3, "link=0x%p", link);
506 505
507 /* Configure card */
508 link->state |= DEV_CONFIG;
509
510 DEBUG(2, "Validating CIS"); 506 DEBUG(2, "Validating CIS");
511 ret = pcmcia_validate_cis(link->handle, &cisinfo); 507 ret = pcmcia_validate_cis(link, &cisinfo);
512 if(ret != CS_SUCCESS) { 508 if(ret != CS_SUCCESS) {
513 cs_error(link->handle, GetTupleData, ret); 509 cs_error(link, GetTupleData, ret);
514 } else { 510 } else {
515 DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains); 511 DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains);
516 } 512 }
@@ -538,7 +534,7 @@ static void pcmciamtd_config(dev_link_t *link)
538 req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16; 534 req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16;
539 req.Base = 0; 535 req.Base = 0;
540 req.AccessSpeed = mem_speed; 536 req.AccessSpeed = mem_speed;
541 link->win = (window_handle_t)link->handle; 537 link->win = (window_handle_t)link;
542 req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR; 538 req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR;
543 dev->win_size = 0; 539 dev->win_size = 0;
544 540
@@ -546,7 +542,7 @@ static void pcmciamtd_config(dev_link_t *link)
546 int ret; 542 int ret;
547 DEBUG(2, "requesting window with size = %dKiB memspeed = %d", 543 DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
548 req.Size >> 10, req.AccessSpeed); 544 req.Size >> 10, req.AccessSpeed);
549 ret = pcmcia_request_window(&link->handle, &req, &link->win); 545 ret = pcmcia_request_window(&link, &req, &link->win);
550 DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size); 546 DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
551 if(ret) { 547 if(ret) {
552 req.Size >>= 1; 548 req.Size >>= 1;
@@ -562,19 +558,19 @@ static void pcmciamtd_config(dev_link_t *link)
562 if(!dev->win_size) { 558 if(!dev->win_size) {
563 err("Cant allocate memory window"); 559 err("Cant allocate memory window");
564 pcmciamtd_release(link); 560 pcmciamtd_release(link);
565 return; 561 return -ENODEV;
566 } 562 }
567 DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10); 563 DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
568 564
569 /* Get write protect status */ 565 /* Get write protect status */
570 CS_CHECK(GetStatus, pcmcia_get_status(link->handle, &status)); 566 CS_CHECK(GetStatus, pcmcia_get_status(link, &status));
571 DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx", 567 DEBUG(2, "status value: 0x%x window handle = 0x%8.8lx",
572 status.CardState, (unsigned long)link->win); 568 status.CardState, (unsigned long)link->win);
573 dev->win_base = ioremap(req.Base, req.Size); 569 dev->win_base = ioremap(req.Base, req.Size);
574 if(!dev->win_base) { 570 if(!dev->win_base) {
575 err("ioremap(%lu, %u) failed", req.Base, req.Size); 571 err("ioremap(%lu, %u) failed", req.Base, req.Size);
576 pcmciamtd_release(link); 572 pcmciamtd_release(link);
577 return; 573 return -ENODEV;
578 } 574 }
579 DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x", 575 DEBUG(1, "mapped window dev = %p req.base = 0x%lx base = %p size = 0x%x",
580 dev, req.Base, dev->win_base, req.Size); 576 dev, req.Base, dev->win_base, req.Size);
@@ -584,17 +580,14 @@ static void pcmciamtd_config(dev_link_t *link)
584 dev->pcmcia_map.map_priv_2 = (unsigned long)link->win; 580 dev->pcmcia_map.map_priv_2 = (unsigned long)link->win;
585 581
586 DEBUG(2, "Getting configuration"); 582 DEBUG(2, "Getting configuration");
587 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link->handle, &t)); 583 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &t));
588 DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2); 584 DEBUG(2, "Vcc = %d Vpp1 = %d Vpp2 = %d", t.Vcc, t.Vpp1, t.Vpp2);
589 dev->vpp = (vpp) ? vpp : t.Vpp1; 585 dev->vpp = (vpp) ? vpp : t.Vpp1;
590 link->conf.Attributes = 0; 586 link->conf.Attributes = 0;
591 link->conf.Vcc = t.Vcc;
592 if(setvpp == 2) { 587 if(setvpp == 2) {
593 link->conf.Vpp1 = dev->vpp; 588 link->conf.Vpp = dev->vpp;
594 link->conf.Vpp2 = dev->vpp;
595 } else { 589 } else {
596 link->conf.Vpp1 = 0; 590 link->conf.Vpp = 0;
597 link->conf.Vpp2 = 0;
598 } 591 }
599 592
600 link->conf.IntType = INT_MEMORY; 593 link->conf.IntType = INT_MEMORY;
@@ -606,9 +599,10 @@ static void pcmciamtd_config(dev_link_t *link)
606 link->conf.ConfigIndex = 0; 599 link->conf.ConfigIndex = 0;
607 link->conf.Present = t.Present; 600 link->conf.Present = t.Present;
608 DEBUG(2, "Setting Configuration"); 601 DEBUG(2, "Setting Configuration");
609 ret = pcmcia_request_configuration(link->handle, &link->conf); 602 ret = pcmcia_request_configuration(link, &link->conf);
610 if(ret != CS_SUCCESS) { 603 if(ret != CS_SUCCESS) {
611 cs_error(link->handle, RequestConfiguration, ret); 604 cs_error(link, RequestConfiguration, ret);
605 return -ENODEV;
612 } 606 }
613 607
614 if(mem_type == 1) { 608 if(mem_type == 1) {
@@ -616,7 +610,7 @@ static void pcmciamtd_config(dev_link_t *link)
616 } else if(mem_type == 2) { 610 } else if(mem_type == 2) {
617 mtd = do_map_probe("map_rom", &dev->pcmcia_map); 611 mtd = do_map_probe("map_rom", &dev->pcmcia_map);
618 } else { 612 } else {
619 for(i = 0; i < sizeof(probes) / sizeof(char *); i++) { 613 for(i = 0; i < ARRAY_SIZE(probes); i++) {
620 DEBUG(1, "Trying %s", probes[i]); 614 DEBUG(1, "Trying %s", probes[i]);
621 mtd = do_map_probe(probes[i], &dev->pcmcia_map); 615 mtd = do_map_probe(probes[i], &dev->pcmcia_map);
622 if(mtd) 616 if(mtd)
@@ -629,7 +623,7 @@ static void pcmciamtd_config(dev_link_t *link)
629 if(!mtd) { 623 if(!mtd) {
630 DEBUG(1, "Cant find an MTD"); 624 DEBUG(1, "Cant find an MTD");
631 pcmciamtd_release(link); 625 pcmciamtd_release(link);
632 return; 626 return -ENODEV;
633 } 627 }
634 628
635 dev->mtd_info = mtd; 629 dev->mtd_info = mtd;
@@ -654,7 +648,6 @@ static void pcmciamtd_config(dev_link_t *link)
654 use the faster non-remapping read/write functions */ 648 use the faster non-remapping read/write functions */
655 if(mtd->size <= dev->win_size) { 649 if(mtd->size <= dev->win_size) {
656 DEBUG(1, "Using non remapping memory functions"); 650 DEBUG(1, "Using non remapping memory functions");
657 dev->pcmcia_map.map_priv_1 = (unsigned long)&(dev->link.state);
658 dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base; 651 dev->pcmcia_map.map_priv_2 = (unsigned long)dev->win_base;
659 if (dev->pcmcia_map.bankwidth == 1) { 652 if (dev->pcmcia_map.bankwidth == 1) {
660 dev->pcmcia_map.read = pcmcia_read8; 653 dev->pcmcia_map.read = pcmcia_read8;
@@ -672,19 +665,18 @@ static void pcmciamtd_config(dev_link_t *link)
672 dev->mtd_info = NULL; 665 dev->mtd_info = NULL;
673 err("Couldnt register MTD device"); 666 err("Couldnt register MTD device");
674 pcmciamtd_release(link); 667 pcmciamtd_release(link);
675 return; 668 return -ENODEV;
676 } 669 }
677 snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index); 670 snprintf(dev->node.dev_name, sizeof(dev->node.dev_name), "mtd%d", mtd->index);
678 info("mtd%d: %s", mtd->index, mtd->name); 671 info("mtd%d: %s", mtd->index, mtd->name);
679 link->state &= ~DEV_CONFIG_PENDING; 672 link->dev_node = &dev->node;
680 link->dev = &dev->node; 673 return 0;
681 return;
682 674
683 cs_failed: 675 cs_failed:
684 cs_error(link->handle, last_fn, last_ret); 676 cs_error(link, last_fn, last_ret);
685 err("CS Error, exiting"); 677 err("CS Error, exiting");
686 pcmciamtd_release(link); 678 pcmciamtd_release(link);
687 return; 679 return -ENODEV;
688} 680}
689 681
690 682
@@ -713,21 +705,18 @@ static int pcmciamtd_resume(struct pcmcia_device *dev)
713 * when the device is released. 705 * when the device is released.
714 */ 706 */
715 707
716static void pcmciamtd_detach(struct pcmcia_device *p_dev) 708static void pcmciamtd_detach(struct pcmcia_device *link)
717{ 709{
718 dev_link_t *link = dev_to_instance(p_dev); 710 struct pcmciamtd_dev *dev = link->priv;
719 711
720 DEBUG(3, "link=0x%p", link); 712 DEBUG(3, "link=0x%p", link);
721 713
722 if(link->state & DEV_CONFIG) { 714 if(dev->mtd_info) {
723 struct pcmciamtd_dev *dev = link->priv; 715 del_mtd_device(dev->mtd_info);
724 if(dev->mtd_info) { 716 info("mtd%d: Removed", dev->mtd_info->index);
725 del_mtd_device(dev->mtd_info);
726 info("mtd%d: Removed", dev->mtd_info->index);
727 }
728
729 pcmciamtd_release(link);
730 } 717 }
718
719 pcmciamtd_release(link);
731} 720}
732 721
733 722
@@ -736,10 +725,9 @@ static void pcmciamtd_detach(struct pcmcia_device *p_dev)
736 * with Card Services. 725 * with Card Services.
737 */ 726 */
738 727
739static int pcmciamtd_attach(struct pcmcia_device *p_dev) 728static int pcmciamtd_probe(struct pcmcia_device *link)
740{ 729{
741 struct pcmciamtd_dev *dev; 730 struct pcmciamtd_dev *dev;
742 dev_link_t *link;
743 731
744 /* Create new memory card device */ 732 /* Create new memory card device */
745 dev = kmalloc(sizeof(*dev), GFP_KERNEL); 733 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
@@ -747,20 +735,13 @@ static int pcmciamtd_attach(struct pcmcia_device *p_dev)
747 DEBUG(1, "dev=0x%p", dev); 735 DEBUG(1, "dev=0x%p", dev);
748 736
749 memset(dev, 0, sizeof(*dev)); 737 memset(dev, 0, sizeof(*dev));
750 link = &dev->link; 738 dev->p_dev = link;
751 link->priv = dev; 739 link->priv = dev;
752 740
753 link->conf.Attributes = 0; 741 link->conf.Attributes = 0;
754 link->conf.IntType = INT_MEMORY; 742 link->conf.IntType = INT_MEMORY;
755 743
756 link->next = NULL; 744 return pcmciamtd_config(link);
757 link->handle = p_dev;
758 p_dev->instance = link;
759
760 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
761 pcmciamtd_config(link);
762
763 return 0;
764} 745}
765 746
766static struct pcmcia_device_id pcmciamtd_ids[] = { 747static struct pcmcia_device_id pcmciamtd_ids[] = {
@@ -794,7 +775,7 @@ static struct pcmcia_driver pcmciamtd_driver = {
794 .drv = { 775 .drv = {
795 .name = "pcmciamtd" 776 .name = "pcmciamtd"
796 }, 777 },
797 .probe = pcmciamtd_attach, 778 .probe = pcmciamtd_probe,
798 .remove = pcmciamtd_detach, 779 .remove = pcmciamtd_detach,
799 .owner = THIS_MODULE, 780 .owner = THIS_MODULE,
800 .id_table = pcmciamtd_ids, 781 .id_table = pcmciamtd_ids,