diff options
Diffstat (limited to 'drivers/scsi/pcmcia/sym53c500_cs.c')
-rw-r--r-- | drivers/scsi/pcmcia/sym53c500_cs.c | 124 |
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 | ||
204 | struct scsi_info_t { | 204 | struct 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 | ||
529 | static void | 529 | static void |
530 | SYM53C500_release(dev_link_t *link) | 530 | SYM53C500_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) \ |
714 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 708 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
715 | 709 | ||
716 | static void | 710 | static int |
717 | SYM53C500_config(dev_link_t *link) | 711 | SYM53C500_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 | } |
764 | next_entry: | 754 | next_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 | ||
848 | err_free_irq: | 838 | err_free_irq: |
849 | free_irq(irq_level, host); | 839 | free_irq(irq_level, host); |
@@ -852,74 +842,50 @@ err_free_scsi: | |||
852 | err_release: | 842 | err_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; | |
856 | out: | ||
857 | link->state &= ~DEV_CONFIG_PENDING; | ||
858 | return; | ||
859 | 846 | ||
860 | cs_failed: | 847 | cs_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 | ||
866 | static int sym53c500_suspend(struct pcmcia_device *dev) | 853 | static 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 | |||
877 | static 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 | ||
904 | static void | 874 | static void |
905 | SYM53C500_detach(struct pcmcia_device *p_dev) | 875 | SYM53C500_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 | ||
918 | static int | 885 | static int |
919 | SYM53C500_attach(struct pcmcia_device *p_dev) | 886 | SYM53C500_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 | ||
952 | MODULE_AUTHOR("Bob Tracy <rct@frus.com>"); | 911 | MODULE_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 | ||