aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pcmcia/nsp_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/pcmcia/nsp_cs.c')
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c167
1 files changed, 48 insertions, 119 deletions
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 050ea13ff80b..9e3ab3fd5355 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -104,9 +104,6 @@ static struct scsi_host_template nsp_driver_template = {
104#endif 104#endif
105}; 105};
106 106
107static dev_link_t *dev_list = NULL;
108static dev_info_t dev_info = {"nsp_cs"};
109
110static nsp_hw_data nsp_data_base; /* attach <-> detect glue */ 107static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
111 108
112 109
@@ -1596,19 +1593,17 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1596 configure the card at this point -- we wait until we receive a 1593 configure the card at this point -- we wait until we receive a
1597 card insertion event. 1594 card insertion event.
1598======================================================================*/ 1595======================================================================*/
1599static dev_link_t *nsp_cs_attach(void) 1596static int nsp_cs_attach(struct pcmcia_device *p_dev)
1600{ 1597{
1601 scsi_info_t *info; 1598 scsi_info_t *info;
1602 client_reg_t client_reg;
1603 dev_link_t *link; 1599 dev_link_t *link;
1604 int ret;
1605 nsp_hw_data *data = &nsp_data_base; 1600 nsp_hw_data *data = &nsp_data_base;
1606 1601
1607 nsp_dbg(NSP_DEBUG_INIT, "in"); 1602 nsp_dbg(NSP_DEBUG_INIT, "in");
1608 1603
1609 /* Create new SCSI device */ 1604 /* Create new SCSI device */
1610 info = kmalloc(sizeof(*info), GFP_KERNEL); 1605 info = kmalloc(sizeof(*info), GFP_KERNEL);
1611 if (info == NULL) { return NULL; } 1606 if (info == NULL) { return -ENOMEM; }
1612 memset(info, 0, sizeof(*info)); 1607 memset(info, 0, sizeof(*info));
1613 link = &info->link; 1608 link = &info->link;
1614 link->priv = info; 1609 link->priv = info;
@@ -1636,23 +1631,14 @@ static dev_link_t *nsp_cs_attach(void)
1636 link->conf.IntType = INT_MEMORY_AND_IO; 1631 link->conf.IntType = INT_MEMORY_AND_IO;
1637 link->conf.Present = PRESENT_OPTION; 1632 link->conf.Present = PRESENT_OPTION;
1638 1633
1634 link->handle = p_dev;
1635 p_dev->instance = link;
1639 1636
1640 /* Register with Card Services */ 1637 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1641 link->next = dev_list; 1638 nsp_cs_config(link);
1642 dev_list = link;
1643 client_reg.dev_info = &dev_info;
1644 client_reg.Version = 0x0210;
1645 client_reg.event_callback_args.client_data = link;
1646 ret = pcmcia_register_client(&link->handle, &client_reg);
1647 if (ret != CS_SUCCESS) {
1648 cs_error(link->handle, RegisterClient, ret);
1649 nsp_cs_detach(link);
1650 return NULL;
1651 }
1652
1653 1639
1654 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); 1640 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1655 return link; 1641 return 0;
1656} /* nsp_cs_attach */ 1642} /* nsp_cs_attach */
1657 1643
1658 1644
@@ -1662,35 +1648,19 @@ static dev_link_t *nsp_cs_attach(void)
1662 structures are freed. Otherwise, the structures will be freed 1648 structures are freed. Otherwise, the structures will be freed
1663 when the device is released. 1649 when the device is released.
1664======================================================================*/ 1650======================================================================*/
1665static void nsp_cs_detach(dev_link_t *link) 1651static void nsp_cs_detach(struct pcmcia_device *p_dev)
1666{ 1652{
1667 dev_link_t **linkp; 1653 dev_link_t *link = dev_to_instance(p_dev);
1668 1654
1669 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); 1655 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1670 1656
1671 /* Locate device structure */ 1657 if (link->state & DEV_CONFIG) {
1672 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { 1658 ((scsi_info_t *)link->priv)->stop = 1;
1673 if (*linkp == link) {
1674 break;
1675 }
1676 }
1677 if (*linkp == NULL) {
1678 return;
1679 }
1680
1681 if (link->state & DEV_CONFIG)
1682 nsp_cs_release(link); 1659 nsp_cs_release(link);
1683
1684 /* Break the link with Card Services */
1685 if (link->handle) {
1686 pcmcia_deregister_client(link->handle);
1687 } 1660 }
1688 1661
1689 /* Unlink device structure, free bits */
1690 *linkp = link->next;
1691 kfree(link->priv); 1662 kfree(link->priv);
1692 link->priv = NULL; 1663 link->priv = NULL;
1693
1694} /* nsp_cs_detach */ 1664} /* nsp_cs_detach */
1695 1665
1696 1666
@@ -2021,99 +1991,58 @@ static void nsp_cs_release(dev_link_t *link)
2021#endif 1991#endif
2022} /* nsp_cs_release */ 1992} /* nsp_cs_release */
2023 1993
2024/*====================================================================== 1994static int nsp_cs_suspend(struct pcmcia_device *dev)
2025
2026 The card status event handler. Mostly, this schedules other
2027 stuff to run after an event is received. A CARD_REMOVAL event
2028 also sets some flags to discourage the net drivers from trying
2029 to talk to the card any more.
2030
2031 When a CARD_REMOVAL event is received, we immediately set a flag
2032 to block future accesses to this device. All the functions that
2033 actually access the device should check this flag to make sure
2034 the card is still present.
2035
2036======================================================================*/
2037static int nsp_cs_event(event_t event,
2038 int priority,
2039 event_callback_args_t *args)
2040{ 1995{
2041 dev_link_t *link = args->client_data; 1996 dev_link_t *link = dev_to_instance(dev);
2042 scsi_info_t *info = link->priv; 1997 scsi_info_t *info = link->priv;
2043 nsp_hw_data *data; 1998 nsp_hw_data *data;
2044 1999
2045 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event); 2000 link->state |= DEV_SUSPEND;
2046 2001
2047 switch (event) { 2002 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2048 case CS_EVENT_CARD_REMOVAL:
2049 nsp_dbg(NSP_DEBUG_INIT, "event: remove");
2050 link->state &= ~DEV_PRESENT;
2051 if (link->state & DEV_CONFIG) {
2052 ((scsi_info_t *)link->priv)->stop = 1;
2053 nsp_cs_release(link);
2054 }
2055 break;
2056 2003
2057 case CS_EVENT_CARD_INSERTION: 2004 if (info->host != NULL) {
2058 nsp_dbg(NSP_DEBUG_INIT, "event: insert"); 2005 nsp_msg(KERN_INFO, "clear SDTR status");
2059 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2060#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
2061 info->bus = args->bus;
2062#endif
2063 nsp_cs_config(link);
2064 break;
2065 2006
2066 case CS_EVENT_PM_SUSPEND: 2007 data = (nsp_hw_data *)info->host->hostdata;
2067 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2068 link->state |= DEV_SUSPEND;
2069 /* Fall through... */
2070 case CS_EVENT_RESET_PHYSICAL:
2071 /* Mark the device as stopped, to block IO until later */
2072 nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
2073 2008
2074 if (info->host != NULL) { 2009 nsphw_init_sync(data);
2075 nsp_msg(KERN_INFO, "clear SDTR status"); 2010 }
2076 2011
2077 data = (nsp_hw_data *)info->host->hostdata; 2012 info->stop = 1;
2078 2013
2079 nsphw_init_sync(data); 2014 if (link->state & DEV_CONFIG)
2080 } 2015 pcmcia_release_configuration(link->handle);
2081 2016
2082 info->stop = 1; 2017 return 0;
2083 if (link->state & DEV_CONFIG) { 2018}
2084 pcmcia_release_configuration(link->handle);
2085 }
2086 break;
2087 2019
2088 case CS_EVENT_PM_RESUME: 2020static int nsp_cs_resume(struct pcmcia_device *dev)
2089 nsp_dbg(NSP_DEBUG_INIT, "event: resume"); 2021{
2090 link->state &= ~DEV_SUSPEND; 2022 dev_link_t *link = dev_to_instance(dev);
2091 /* Fall through... */ 2023 scsi_info_t *info = link->priv;
2092 case CS_EVENT_CARD_RESET: 2024 nsp_hw_data *data;
2093 nsp_dbg(NSP_DEBUG_INIT, "event: reset");
2094 if (link->state & DEV_CONFIG) {
2095 pcmcia_request_configuration(link->handle, &link->conf);
2096 }
2097 info->stop = 0;
2098 2025
2099 if (info->host != NULL) { 2026 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2100 nsp_msg(KERN_INFO, "reset host and bus");
2101 2027
2102 data = (nsp_hw_data *)info->host->hostdata; 2028 link->state &= ~DEV_SUSPEND;
2103 2029
2104 nsphw_init (data); 2030 if (link->state & DEV_CONFIG)
2105 nsp_bus_reset(data); 2031 pcmcia_request_configuration(link->handle, &link->conf);
2106 }
2107 2032
2108 break; 2033 info->stop = 0;
2109 2034
2110 default: 2035 if (info->host != NULL) {
2111 nsp_dbg(NSP_DEBUG_INIT, "event: unknown"); 2036 nsp_msg(KERN_INFO, "reset host and bus");
2112 break; 2037
2038 data = (nsp_hw_data *)info->host->hostdata;
2039
2040 nsphw_init (data);
2041 nsp_bus_reset(data);
2113 } 2042 }
2114 nsp_dbg(NSP_DEBUG_INIT, "end"); 2043
2115 return 0; 2044 return 0;
2116} /* nsp_cs_event */ 2045}
2117 2046
2118/*======================================================================* 2047/*======================================================================*
2119 * module entry point 2048 * module entry point
@@ -2136,10 +2065,11 @@ static struct pcmcia_driver nsp_driver = {
2136 .drv = { 2065 .drv = {
2137 .name = "nsp_cs", 2066 .name = "nsp_cs",
2138 }, 2067 },
2139 .attach = nsp_cs_attach, 2068 .probe = nsp_cs_attach,
2140 .event = nsp_cs_event, 2069 .remove = nsp_cs_detach,
2141 .detach = nsp_cs_detach,
2142 .id_table = nsp_cs_ids, 2070 .id_table = nsp_cs_ids,
2071 .suspend = nsp_cs_suspend,
2072 .resume = nsp_cs_resume,
2143}; 2073};
2144#endif 2074#endif
2145 2075
@@ -2171,7 +2101,6 @@ static void __exit nsp_cs_exit(void)
2171 2101
2172#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) 2102#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2173 pcmcia_unregister_driver(&nsp_driver); 2103 pcmcia_unregister_driver(&nsp_driver);
2174 BUG_ON(dev_list != NULL);
2175#else 2104#else
2176 unregister_pcmcia_driver(&dev_info); 2105 unregister_pcmcia_driver(&dev_info);
2177 /* XXX: this really needs to move into generic code.. */ 2106 /* XXX: this really needs to move into generic code.. */