diff options
Diffstat (limited to 'drivers/scsi/pcmcia/sym53c500_cs.c')
-rw-r--r-- | drivers/scsi/pcmcia/sym53c500_cs.c | 133 |
1 files changed, 46 insertions, 87 deletions
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 98b64b2aa8ee..3a4dd6f5b81f 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c | |||
@@ -228,15 +228,6 @@ enum Phase { | |||
228 | 228 | ||
229 | /* ================================================================== */ | 229 | /* ================================================================== */ |
230 | 230 | ||
231 | /* | ||
232 | * Global (within this module) variables other than | ||
233 | * sym53c500_driver_template (the scsi_host_template). | ||
234 | */ | ||
235 | static dev_link_t *dev_list; | ||
236 | static dev_info_t dev_info = "sym53c500_cs"; | ||
237 | |||
238 | /* ================================================================== */ | ||
239 | |||
240 | static void | 231 | static void |
241 | chip_init(int io_port) | 232 | chip_init(int io_port) |
242 | { | 233 | { |
@@ -872,96 +863,70 @@ cs_failed: | |||
872 | return; | 863 | return; |
873 | } /* SYM53C500_config */ | 864 | } /* SYM53C500_config */ |
874 | 865 | ||
875 | static int | 866 | static int sym53c500_suspend(struct pcmcia_device *dev) |
876 | SYM53C500_event(event_t event, int priority, event_callback_args_t *args) | ||
877 | { | 867 | { |
878 | dev_link_t *link = args->client_data; | 868 | dev_link_t *link = dev_to_instance(dev); |
879 | struct scsi_info_t *info = link->priv; | ||
880 | 869 | ||
881 | DEBUG(1, "SYM53C500_event(0x%06x)\n", event); | 870 | link->state |= DEV_SUSPEND; |
871 | if (link->state & DEV_CONFIG) | ||
872 | pcmcia_release_configuration(link->handle); | ||
882 | 873 | ||
883 | switch (event) { | 874 | return 0; |
884 | case CS_EVENT_CARD_REMOVAL: | 875 | } |
885 | link->state &= ~DEV_PRESENT; | 876 | |
886 | if (link->state & DEV_CONFIG) | 877 | static int sym53c500_resume(struct pcmcia_device *dev) |
887 | SYM53C500_release(link); | 878 | { |
888 | break; | 879 | dev_link_t *link = dev_to_instance(dev); |
889 | case CS_EVENT_CARD_INSERTION: | 880 | struct scsi_info_t *info = link->priv; |
890 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 881 | |
891 | SYM53C500_config(link); | 882 | link->state &= ~DEV_SUSPEND; |
892 | break; | 883 | if (link->state & DEV_CONFIG) { |
893 | case CS_EVENT_PM_SUSPEND: | 884 | pcmcia_request_configuration(link->handle, &link->conf); |
894 | link->state |= DEV_SUSPEND; | 885 | |
895 | /* Fall through... */ | 886 | /* See earlier comment about manufacturer IDs. */ |
896 | case CS_EVENT_RESET_PHYSICAL: | 887 | if ((info->manf_id == MANFID_MACNICA) || |
897 | if (link->state & DEV_CONFIG) | 888 | (info->manf_id == MANFID_PIONEER) || |
898 | pcmcia_release_configuration(link->handle); | 889 | (info->manf_id == 0x0098)) { |
899 | break; | 890 | outb(0x80, link->io.BasePort1 + 0xd); |
900 | case CS_EVENT_PM_RESUME: | 891 | outb(0x24, link->io.BasePort1 + 0x9); |
901 | link->state &= ~DEV_SUSPEND; | 892 | outb(0x04, link->io.BasePort1 + 0xd); |
902 | /* Fall through... */ | ||
903 | case CS_EVENT_CARD_RESET: | ||
904 | if (link->state & DEV_CONFIG) { | ||
905 | pcmcia_request_configuration(link->handle, &link->conf); | ||
906 | /* See earlier comment about manufacturer IDs. */ | ||
907 | if ((info->manf_id == MANFID_MACNICA) || | ||
908 | (info->manf_id == MANFID_PIONEER) || | ||
909 | (info->manf_id == 0x0098)) { | ||
910 | outb(0x80, link->io.BasePort1 + 0xd); | ||
911 | outb(0x24, link->io.BasePort1 + 0x9); | ||
912 | outb(0x04, link->io.BasePort1 + 0xd); | ||
913 | } | ||
914 | /* | ||
915 | * If things don't work after a "resume", | ||
916 | * this is a good place to start looking. | ||
917 | */ | ||
918 | SYM53C500_int_host_reset(link->io.BasePort1); | ||
919 | } | 893 | } |
920 | break; | 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); | ||
921 | } | 899 | } |
900 | |||
922 | return 0; | 901 | return 0; |
923 | } /* SYM53C500_event */ | 902 | } |
924 | 903 | ||
925 | static void | 904 | static void |
926 | SYM53C500_detach(dev_link_t *link) | 905 | SYM53C500_detach(struct pcmcia_device *p_dev) |
927 | { | 906 | { |
928 | dev_link_t **linkp; | 907 | dev_link_t *link = dev_to_instance(p_dev); |
929 | 908 | ||
930 | DEBUG(0, "SYM53C500_detach(0x%p)\n", link); | 909 | DEBUG(0, "SYM53C500_detach(0x%p)\n", link); |
931 | 910 | ||
932 | /* Locate device structure */ | ||
933 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
934 | if (*linkp == link) | ||
935 | break; | ||
936 | if (*linkp == NULL) | ||
937 | return; | ||
938 | |||
939 | if (link->state & DEV_CONFIG) | 911 | if (link->state & DEV_CONFIG) |
940 | SYM53C500_release(link); | 912 | SYM53C500_release(link); |
941 | 913 | ||
942 | if (link->handle) | ||
943 | pcmcia_deregister_client(link->handle); | ||
944 | |||
945 | /* Unlink device structure, free bits. */ | ||
946 | *linkp = link->next; | ||
947 | kfree(link->priv); | 914 | kfree(link->priv); |
948 | link->priv = NULL; | 915 | link->priv = NULL; |
949 | } /* SYM53C500_detach */ | 916 | } /* SYM53C500_detach */ |
950 | 917 | ||
951 | static dev_link_t * | 918 | static int |
952 | SYM53C500_attach(void) | 919 | SYM53C500_attach(struct pcmcia_device *p_dev) |
953 | { | 920 | { |
954 | struct scsi_info_t *info; | 921 | struct scsi_info_t *info; |
955 | client_reg_t client_reg; | ||
956 | dev_link_t *link; | 922 | dev_link_t *link; |
957 | int ret; | ||
958 | 923 | ||
959 | DEBUG(0, "SYM53C500_attach()\n"); | 924 | DEBUG(0, "SYM53C500_attach()\n"); |
960 | 925 | ||
961 | /* Create new SCSI device */ | 926 | /* Create new SCSI device */ |
962 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 927 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
963 | if (!info) | 928 | if (!info) |
964 | return NULL; | 929 | return -ENOMEM; |
965 | memset(info, 0, sizeof(*info)); | 930 | memset(info, 0, sizeof(*info)); |
966 | link = &info->link; | 931 | link = &info->link; |
967 | link->priv = info; | 932 | link->priv = info; |
@@ -975,20 +940,13 @@ SYM53C500_attach(void) | |||
975 | link->conf.IntType = INT_MEMORY_AND_IO; | 940 | link->conf.IntType = INT_MEMORY_AND_IO; |
976 | link->conf.Present = PRESENT_OPTION; | 941 | link->conf.Present = PRESENT_OPTION; |
977 | 942 | ||
978 | /* Register with Card Services */ | 943 | link->handle = p_dev; |
979 | link->next = dev_list; | 944 | p_dev->instance = link; |
980 | dev_list = link; | 945 | |
981 | client_reg.dev_info = &dev_info; | 946 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
982 | client_reg.Version = 0x0210; | 947 | SYM53C500_config(link); |
983 | client_reg.event_callback_args.client_data = link; | ||
984 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
985 | if (ret != 0) { | ||
986 | cs_error(link->handle, RegisterClient, ret); | ||
987 | SYM53C500_detach(link); | ||
988 | return NULL; | ||
989 | } | ||
990 | 948 | ||
991 | return link; | 949 | return 0; |
992 | } /* SYM53C500_attach */ | 950 | } /* SYM53C500_attach */ |
993 | 951 | ||
994 | MODULE_AUTHOR("Bob Tracy <rct@frus.com>"); | 952 | MODULE_AUTHOR("Bob Tracy <rct@frus.com>"); |
@@ -1008,10 +966,11 @@ static struct pcmcia_driver sym53c500_cs_driver = { | |||
1008 | .drv = { | 966 | .drv = { |
1009 | .name = "sym53c500_cs", | 967 | .name = "sym53c500_cs", |
1010 | }, | 968 | }, |
1011 | .attach = SYM53C500_attach, | 969 | .probe = SYM53C500_attach, |
1012 | .event = SYM53C500_event, | 970 | .remove = SYM53C500_detach, |
1013 | .detach = SYM53C500_detach, | ||
1014 | .id_table = sym53c500_ids, | 971 | .id_table = sym53c500_ids, |
972 | .suspend = sym53c500_suspend, | ||
973 | .resume = sym53c500_resume, | ||
1015 | }; | 974 | }; |
1016 | 975 | ||
1017 | static int __init | 976 | static int __init |