aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pcmcia/sym53c500_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/pcmcia/sym53c500_cs.c')
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c124
1 files changed, 41 insertions, 83 deletions
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 3a4dd6f5b81f..9f59827707f0 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -202,7 +202,7 @@ static char *version =
202/* ================================================================== */ 202/* ================================================================== */
203 203
204struct scsi_info_t { 204struct scsi_info_t {
205 dev_link_t link; 205 struct pcmcia_device *p_dev;
206 dev_node_t node; 206 dev_node_t node;
207 struct Scsi_Host *host; 207 struct Scsi_Host *host;
208 unsigned short manf_id; 208 unsigned short manf_id;
@@ -527,7 +527,7 @@ idle_out:
527} 527}
528 528
529static void 529static void
530SYM53C500_release(dev_link_t *link) 530SYM53C500_release(struct pcmcia_device *link)
531{ 531{
532 struct scsi_info_t *info = link->priv; 532 struct scsi_info_t *info = link->priv;
533 struct Scsi_Host *shost = info->host; 533 struct Scsi_Host *shost = info->host;
@@ -550,13 +550,7 @@ SYM53C500_release(dev_link_t *link)
550 if (shost->io_port && shost->n_io_port) 550 if (shost->io_port && shost->n_io_port)
551 release_region(shost->io_port, shost->n_io_port); 551 release_region(shost->io_port, shost->n_io_port);
552 552
553 link->dev = NULL; 553 pcmcia_disable_device(link);
554
555 pcmcia_release_configuration(link->handle);
556 pcmcia_release_io(link->handle, &link->io);
557 pcmcia_release_irq(link->handle, &link->irq);
558
559 link->state &= ~DEV_CONFIG;
560 554
561 scsi_host_put(shost); 555 scsi_host_put(shost);
562} /* SYM53C500_release */ 556} /* SYM53C500_release */
@@ -713,10 +707,9 @@ static struct scsi_host_template sym53c500_driver_template = {
713#define CS_CHECK(fn, ret) \ 707#define CS_CHECK(fn, ret) \
714do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 708do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
715 709
716static void 710static int
717SYM53C500_config(dev_link_t *link) 711SYM53C500_config(struct pcmcia_device *link)
718{ 712{
719 client_handle_t handle = link->handle;
720 struct scsi_info_t *info = link->priv; 713 struct scsi_info_t *info = link->priv;
721 tuple_t tuple; 714 tuple_t tuple;
722 cisparse_t parse; 715 cisparse_t parse;
@@ -733,40 +726,37 @@ SYM53C500_config(dev_link_t *link)
733 tuple.TupleDataMax = 64; 726 tuple.TupleDataMax = 64;
734 tuple.TupleOffset = 0; 727 tuple.TupleOffset = 0;
735 tuple.DesiredTuple = CISTPL_CONFIG; 728 tuple.DesiredTuple = CISTPL_CONFIG;
736 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 729 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
737 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 730 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
738 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 731 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
739 link->conf.ConfigBase = parse.config.base; 732 link->conf.ConfigBase = parse.config.base;
740 733
741 tuple.DesiredTuple = CISTPL_MANFID; 734 tuple.DesiredTuple = CISTPL_MANFID;
742 if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && 735 if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) &&
743 (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) 736 (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS))
744 info->manf_id = le16_to_cpu(tuple.TupleData[0]); 737 info->manf_id = le16_to_cpu(tuple.TupleData[0]);
745 738
746 /* Configure card */
747 link->state |= DEV_CONFIG;
748
749 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 739 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
750 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 740 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
751 while (1) { 741 while (1) {
752 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 742 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
753 pcmcia_parse_tuple(handle, &tuple, &parse) != 0) 743 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
754 goto next_entry; 744 goto next_entry;
755 link->conf.ConfigIndex = parse.cftable_entry.index; 745 link->conf.ConfigIndex = parse.cftable_entry.index;
756 link->io.BasePort1 = parse.cftable_entry.io.win[0].base; 746 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
757 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; 747 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
758 748
759 if (link->io.BasePort1 != 0) { 749 if (link->io.BasePort1 != 0) {
760 i = pcmcia_request_io(handle, &link->io); 750 i = pcmcia_request_io(link, &link->io);
761 if (i == CS_SUCCESS) 751 if (i == CS_SUCCESS)
762 break; 752 break;
763 } 753 }
764next_entry: 754next_entry:
765 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); 755 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
766 } 756 }
767 757
768 CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); 758 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
769 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); 759 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
770 760
771 /* 761 /*
772 * That's the trouble with copying liberally from another driver. 762 * That's the trouble with copying liberally from another driver.
@@ -835,7 +825,7 @@ next_entry:
835 data->fast_pio = USE_FAST_PIO; 825 data->fast_pio = USE_FAST_PIO;
836 826
837 sprintf(info->node.dev_name, "scsi%d", host->host_no); 827 sprintf(info->node.dev_name, "scsi%d", host->host_no);
838 link->dev = &info->node; 828 link->dev_node = &info->node;
839 info->host = host; 829 info->host = host;
840 830
841 if (scsi_add_host(host, NULL)) 831 if (scsi_add_host(host, NULL))
@@ -843,7 +833,7 @@ next_entry:
843 833
844 scsi_scan_host(host); 834 scsi_scan_host(host);
845 835
846 goto out; /* SUCCESS */ 836 return 0;
847 837
848err_free_irq: 838err_free_irq:
849 free_irq(irq_level, host); 839 free_irq(irq_level, host);
@@ -852,74 +842,50 @@ err_free_scsi:
852err_release: 842err_release:
853 release_region(port_base, 0x10); 843 release_region(port_base, 0x10);
854 printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n"); 844 printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n");
855 845 return -ENODEV;
856out:
857 link->state &= ~DEV_CONFIG_PENDING;
858 return;
859 846
860cs_failed: 847cs_failed:
861 cs_error(link->handle, last_fn, last_ret); 848 cs_error(link, last_fn, last_ret);
862 SYM53C500_release(link); 849 SYM53C500_release(link);
863 return; 850 return -ENODEV;
864} /* SYM53C500_config */ 851} /* SYM53C500_config */
865 852
866static int sym53c500_suspend(struct pcmcia_device *dev) 853static int sym53c500_resume(struct pcmcia_device *link)
867{
868 dev_link_t *link = dev_to_instance(dev);
869
870 link->state |= DEV_SUSPEND;
871 if (link->state & DEV_CONFIG)
872 pcmcia_release_configuration(link->handle);
873
874 return 0;
875}
876
877static int sym53c500_resume(struct pcmcia_device *dev)
878{ 854{
879 dev_link_t *link = dev_to_instance(dev);
880 struct scsi_info_t *info = link->priv; 855 struct scsi_info_t *info = link->priv;
881 856
882 link->state &= ~DEV_SUSPEND; 857 /* See earlier comment about manufacturer IDs. */
883 if (link->state & DEV_CONFIG) { 858 if ((info->manf_id == MANFID_MACNICA) ||
884 pcmcia_request_configuration(link->handle, &link->conf); 859 (info->manf_id == MANFID_PIONEER) ||
885 860 (info->manf_id == 0x0098)) {
886 /* See earlier comment about manufacturer IDs. */ 861 outb(0x80, link->io.BasePort1 + 0xd);
887 if ((info->manf_id == MANFID_MACNICA) || 862 outb(0x24, link->io.BasePort1 + 0x9);
888 (info->manf_id == MANFID_PIONEER) || 863 outb(0x04, link->io.BasePort1 + 0xd);
889 (info->manf_id == 0x0098)) {
890 outb(0x80, link->io.BasePort1 + 0xd);
891 outb(0x24, link->io.BasePort1 + 0x9);
892 outb(0x04, link->io.BasePort1 + 0xd);
893 }
894 /*
895 * If things don't work after a "resume",
896 * this is a good place to start looking.
897 */
898 SYM53C500_int_host_reset(link->io.BasePort1);
899 } 864 }
865 /*
866 * If things don't work after a "resume",
867 * this is a good place to start looking.
868 */
869 SYM53C500_int_host_reset(link->io.BasePort1);
900 870
901 return 0; 871 return 0;
902} 872}
903 873
904static void 874static void
905SYM53C500_detach(struct pcmcia_device *p_dev) 875SYM53C500_detach(struct pcmcia_device *link)
906{ 876{
907 dev_link_t *link = dev_to_instance(p_dev);
908
909 DEBUG(0, "SYM53C500_detach(0x%p)\n", link); 877 DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
910 878
911 if (link->state & DEV_CONFIG) 879 SYM53C500_release(link);
912 SYM53C500_release(link);
913 880
914 kfree(link->priv); 881 kfree(link->priv);
915 link->priv = NULL; 882 link->priv = NULL;
916} /* SYM53C500_detach */ 883} /* SYM53C500_detach */
917 884
918static int 885static int
919SYM53C500_attach(struct pcmcia_device *p_dev) 886SYM53C500_probe(struct pcmcia_device *link)
920{ 887{
921 struct scsi_info_t *info; 888 struct scsi_info_t *info;
922 dev_link_t *link;
923 889
924 DEBUG(0, "SYM53C500_attach()\n"); 890 DEBUG(0, "SYM53C500_attach()\n");
925 891
@@ -928,7 +894,7 @@ SYM53C500_attach(struct pcmcia_device *p_dev)
928 if (!info) 894 if (!info)
929 return -ENOMEM; 895 return -ENOMEM;
930 memset(info, 0, sizeof(*info)); 896 memset(info, 0, sizeof(*info));
931 link = &info->link; 897 info->p_dev = link;
932 link->priv = info; 898 link->priv = info;
933 link->io.NumPorts1 = 16; 899 link->io.NumPorts1 = 16;
934 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 900 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -936,17 +902,10 @@ SYM53C500_attach(struct pcmcia_device *p_dev)
936 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 902 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
937 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 903 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
938 link->conf.Attributes = CONF_ENABLE_IRQ; 904 link->conf.Attributes = CONF_ENABLE_IRQ;
939 link->conf.Vcc = 50;
940 link->conf.IntType = INT_MEMORY_AND_IO; 905 link->conf.IntType = INT_MEMORY_AND_IO;
941 link->conf.Present = PRESENT_OPTION; 906 link->conf.Present = PRESENT_OPTION;
942 907
943 link->handle = p_dev; 908 return SYM53C500_config(link);
944 p_dev->instance = link;
945
946 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
947 SYM53C500_config(link);
948
949 return 0;
950} /* SYM53C500_attach */ 909} /* SYM53C500_attach */
951 910
952MODULE_AUTHOR("Bob Tracy <rct@frus.com>"); 911MODULE_AUTHOR("Bob Tracy <rct@frus.com>");
@@ -966,10 +925,9 @@ static struct pcmcia_driver sym53c500_cs_driver = {
966 .drv = { 925 .drv = {
967 .name = "sym53c500_cs", 926 .name = "sym53c500_cs",
968 }, 927 },
969 .probe = SYM53C500_attach, 928 .probe = SYM53C500_probe,
970 .remove = SYM53C500_detach, 929 .remove = SYM53C500_detach,
971 .id_table = sym53c500_ids, 930 .id_table = sym53c500_ids,
972 .suspend = sym53c500_suspend,
973 .resume = sym53c500_resume, 931 .resume = sym53c500_resume,
974}; 932};
975 933