diff options
Diffstat (limited to 'drivers/scsi/pcmcia/nsp_cs.c')
-rw-r--r-- | drivers/scsi/pcmcia/nsp_cs.c | 136 |
1 files changed, 45 insertions, 91 deletions
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 9e3ab3fd5355..231f9c311c69 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -1593,11 +1593,11 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt) | |||
1593 | 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 |
1594 | card insertion event. | 1594 | card insertion event. |
1595 | ======================================================================*/ | 1595 | ======================================================================*/ |
1596 | static int nsp_cs_attach(struct pcmcia_device *p_dev) | 1596 | static int nsp_cs_probe(struct pcmcia_device *link) |
1597 | { | 1597 | { |
1598 | scsi_info_t *info; | 1598 | scsi_info_t *info; |
1599 | dev_link_t *link; | ||
1600 | nsp_hw_data *data = &nsp_data_base; | 1599 | nsp_hw_data *data = &nsp_data_base; |
1600 | int ret; | ||
1601 | 1601 | ||
1602 | nsp_dbg(NSP_DEBUG_INIT, "in"); | 1602 | nsp_dbg(NSP_DEBUG_INIT, "in"); |
1603 | 1603 | ||
@@ -1605,7 +1605,7 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev) | |||
1605 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 1605 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
1606 | if (info == NULL) { return -ENOMEM; } | 1606 | if (info == NULL) { return -ENOMEM; } |
1607 | memset(info, 0, sizeof(*info)); | 1607 | memset(info, 0, sizeof(*info)); |
1608 | link = &info->link; | 1608 | info->p_dev = link; |
1609 | link->priv = info; | 1609 | link->priv = info; |
1610 | data->ScsiInfo = info; | 1610 | data->ScsiInfo = info; |
1611 | 1611 | ||
@@ -1627,18 +1627,13 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev) | |||
1627 | 1627 | ||
1628 | /* General socket configuration */ | 1628 | /* General socket configuration */ |
1629 | link->conf.Attributes = CONF_ENABLE_IRQ; | 1629 | link->conf.Attributes = CONF_ENABLE_IRQ; |
1630 | link->conf.Vcc = 50; | ||
1631 | link->conf.IntType = INT_MEMORY_AND_IO; | 1630 | link->conf.IntType = INT_MEMORY_AND_IO; |
1632 | link->conf.Present = PRESENT_OPTION; | 1631 | link->conf.Present = PRESENT_OPTION; |
1633 | 1632 | ||
1634 | link->handle = p_dev; | 1633 | ret = nsp_cs_config(link); |
1635 | p_dev->instance = link; | ||
1636 | |||
1637 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
1638 | nsp_cs_config(link); | ||
1639 | 1634 | ||
1640 | nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); | 1635 | nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); |
1641 | return 0; | 1636 | return ret; |
1642 | } /* nsp_cs_attach */ | 1637 | } /* nsp_cs_attach */ |
1643 | 1638 | ||
1644 | 1639 | ||
@@ -1648,16 +1643,12 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev) | |||
1648 | structures are freed. Otherwise, the structures will be freed | 1643 | structures are freed. Otherwise, the structures will be freed |
1649 | when the device is released. | 1644 | when the device is released. |
1650 | ======================================================================*/ | 1645 | ======================================================================*/ |
1651 | static void nsp_cs_detach(struct pcmcia_device *p_dev) | 1646 | static void nsp_cs_detach(struct pcmcia_device *link) |
1652 | { | 1647 | { |
1653 | dev_link_t *link = dev_to_instance(p_dev); | ||
1654 | |||
1655 | nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); | 1648 | nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); |
1656 | 1649 | ||
1657 | if (link->state & DEV_CONFIG) { | 1650 | ((scsi_info_t *)link->priv)->stop = 1; |
1658 | ((scsi_info_t *)link->priv)->stop = 1; | 1651 | nsp_cs_release(link); |
1659 | nsp_cs_release(link); | ||
1660 | } | ||
1661 | 1652 | ||
1662 | kfree(link->priv); | 1653 | kfree(link->priv); |
1663 | link->priv = NULL; | 1654 | link->priv = NULL; |
@@ -1672,9 +1663,9 @@ static void nsp_cs_detach(struct pcmcia_device *p_dev) | |||
1672 | #define CS_CHECK(fn, ret) \ | 1663 | #define CS_CHECK(fn, ret) \ |
1673 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 1664 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
1674 | /*====================================================================*/ | 1665 | /*====================================================================*/ |
1675 | static void nsp_cs_config(dev_link_t *link) | 1666 | static int nsp_cs_config(struct pcmcia_device *link) |
1676 | { | 1667 | { |
1677 | client_handle_t handle = link->handle; | 1668 | int ret; |
1678 | scsi_info_t *info = link->priv; | 1669 | scsi_info_t *info = link->priv; |
1679 | tuple_t tuple; | 1670 | tuple_t tuple; |
1680 | cisparse_t parse; | 1671 | cisparse_t parse; |
@@ -1698,26 +1689,22 @@ static void nsp_cs_config(dev_link_t *link) | |||
1698 | tuple.TupleData = tuple_data; | 1689 | tuple.TupleData = tuple_data; |
1699 | tuple.TupleDataMax = sizeof(tuple_data); | 1690 | tuple.TupleDataMax = sizeof(tuple_data); |
1700 | tuple.TupleOffset = 0; | 1691 | tuple.TupleOffset = 0; |
1701 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | 1692 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
1702 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); | 1693 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); |
1703 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); | 1694 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); |
1704 | link->conf.ConfigBase = parse.config.base; | 1695 | link->conf.ConfigBase = parse.config.base; |
1705 | link->conf.Present = parse.config.rmask[0]; | 1696 | link->conf.Present = parse.config.rmask[0]; |
1706 | 1697 | ||
1707 | /* Configure card */ | ||
1708 | link->state |= DEV_CONFIG; | ||
1709 | |||
1710 | /* Look up the current Vcc */ | 1698 | /* Look up the current Vcc */ |
1711 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); | 1699 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); |
1712 | link->conf.Vcc = conf.Vcc; | ||
1713 | 1700 | ||
1714 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 1701 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
1715 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | 1702 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
1716 | while (1) { | 1703 | while (1) { |
1717 | cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); | 1704 | cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); |
1718 | 1705 | ||
1719 | if (pcmcia_get_tuple_data(handle, &tuple) != 0 || | 1706 | if (pcmcia_get_tuple_data(link, &tuple) != 0 || |
1720 | pcmcia_parse_tuple(handle, &tuple, &parse) != 0) | 1707 | pcmcia_parse_tuple(link, &tuple, &parse) != 0) |
1721 | goto next_entry; | 1708 | goto next_entry; |
1722 | 1709 | ||
1723 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } | 1710 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } |
@@ -1743,10 +1730,10 @@ static void nsp_cs_config(dev_link_t *link) | |||
1743 | } | 1730 | } |
1744 | 1731 | ||
1745 | if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) { | 1732 | if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) { |
1746 | link->conf.Vpp1 = link->conf.Vpp2 = | 1733 | link->conf.Vpp = |
1747 | cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; | 1734 | cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; |
1748 | } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { | 1735 | } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { |
1749 | link->conf.Vpp1 = link->conf.Vpp2 = | 1736 | link->conf.Vpp = |
1750 | dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; | 1737 | dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; |
1751 | } | 1738 | } |
1752 | 1739 | ||
@@ -1773,7 +1760,7 @@ static void nsp_cs_config(dev_link_t *link) | |||
1773 | link->io.NumPorts2 = io->win[1].len; | 1760 | link->io.NumPorts2 = io->win[1].len; |
1774 | } | 1761 | } |
1775 | /* This reserves IO space but doesn't actually enable it */ | 1762 | /* This reserves IO space but doesn't actually enable it */ |
1776 | if (pcmcia_request_io(link->handle, &link->io) != 0) | 1763 | if (pcmcia_request_io(link, &link->io) != 0) |
1777 | goto next_entry; | 1764 | goto next_entry; |
1778 | } | 1765 | } |
1779 | 1766 | ||
@@ -1788,7 +1775,7 @@ static void nsp_cs_config(dev_link_t *link) | |||
1788 | req.Size = 0x1000; | 1775 | req.Size = 0x1000; |
1789 | } | 1776 | } |
1790 | req.AccessSpeed = 0; | 1777 | req.AccessSpeed = 0; |
1791 | if (pcmcia_request_window(&link->handle, &req, &link->win) != 0) | 1778 | if (pcmcia_request_window(&link, &req, &link->win) != 0) |
1792 | goto next_entry; | 1779 | goto next_entry; |
1793 | map.Page = 0; map.CardOffset = mem->win[0].card_addr; | 1780 | map.Page = 0; map.CardOffset = mem->win[0].card_addr; |
1794 | if (pcmcia_map_mem_page(link->win, &map) != 0) | 1781 | if (pcmcia_map_mem_page(link->win, &map) != 0) |
@@ -1802,17 +1789,14 @@ static void nsp_cs_config(dev_link_t *link) | |||
1802 | 1789 | ||
1803 | next_entry: | 1790 | next_entry: |
1804 | nsp_dbg(NSP_DEBUG_INIT, "next"); | 1791 | nsp_dbg(NSP_DEBUG_INIT, "next"); |
1805 | 1792 | pcmcia_disable_device(link); | |
1806 | if (link->io.NumPorts1) { | 1793 | CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); |
1807 | pcmcia_release_io(link->handle, &link->io); | ||
1808 | } | ||
1809 | CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); | ||
1810 | } | 1794 | } |
1811 | 1795 | ||
1812 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | 1796 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { |
1813 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); | 1797 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); |
1814 | } | 1798 | } |
1815 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); | 1799 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); |
1816 | 1800 | ||
1817 | if (free_ports) { | 1801 | if (free_ports) { |
1818 | if (link->io.BasePort1) { | 1802 | if (link->io.BasePort1) { |
@@ -1854,16 +1838,19 @@ static void nsp_cs_config(dev_link_t *link) | |||
1854 | 1838 | ||
1855 | 1839 | ||
1856 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) | 1840 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) |
1857 | scsi_add_host (host, NULL); | 1841 | ret = scsi_add_host (host, NULL); |
1842 | if (ret) | ||
1843 | goto cs_failed; | ||
1844 | |||
1858 | scsi_scan_host(host); | 1845 | scsi_scan_host(host); |
1859 | 1846 | ||
1860 | snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no); | 1847 | snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no); |
1861 | link->dev = &info->node; | 1848 | link->dev_node = &info->node; |
1862 | info->host = host; | 1849 | info->host = host; |
1863 | 1850 | ||
1864 | #else | 1851 | #else |
1865 | nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO"); | 1852 | nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO"); |
1866 | tail = &link->dev; | 1853 | tail = &link->dev_node; |
1867 | info->ndev = 0; | 1854 | info->ndev = 0; |
1868 | 1855 | ||
1869 | nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); | 1856 | nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); |
@@ -1908,11 +1895,10 @@ static void nsp_cs_config(dev_link_t *link) | |||
1908 | #endif | 1895 | #endif |
1909 | 1896 | ||
1910 | /* Finally, report what we've done */ | 1897 | /* Finally, report what we've done */ |
1911 | printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d", | 1898 | printk(KERN_INFO "nsp_cs: index 0x%02x: ", |
1912 | link->conf.ConfigIndex, | 1899 | link->conf.ConfigIndex); |
1913 | link->conf.Vcc/10, link->conf.Vcc%10); | 1900 | if (link->conf.Vpp) { |
1914 | if (link->conf.Vpp1) { | 1901 | printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); |
1915 | printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); | ||
1916 | } | 1902 | } |
1917 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { | 1903 | if (link->conf.Attributes & CONF_ENABLE_IRQ) { |
1918 | printk(", irq %d", link->irq.AssignedIRQ); | 1904 | printk(", irq %d", link->irq.AssignedIRQ); |
@@ -1929,15 +1915,14 @@ static void nsp_cs_config(dev_link_t *link) | |||
1929 | req.Base+req.Size-1); | 1915 | req.Base+req.Size-1); |
1930 | printk("\n"); | 1916 | printk("\n"); |
1931 | 1917 | ||
1932 | link->state &= ~DEV_CONFIG_PENDING; | 1918 | return 0; |
1933 | return; | ||
1934 | 1919 | ||
1935 | cs_failed: | 1920 | cs_failed: |
1936 | nsp_dbg(NSP_DEBUG_INIT, "config fail"); | 1921 | nsp_dbg(NSP_DEBUG_INIT, "config fail"); |
1937 | cs_error(link->handle, last_fn, last_ret); | 1922 | cs_error(link, last_fn, last_ret); |
1938 | nsp_cs_release(link); | 1923 | nsp_cs_release(link); |
1939 | 1924 | ||
1940 | return; | 1925 | return -ENODEV; |
1941 | } /* nsp_cs_config */ | 1926 | } /* nsp_cs_config */ |
1942 | #undef CS_CHECK | 1927 | #undef CS_CHECK |
1943 | 1928 | ||
@@ -1947,7 +1932,7 @@ static void nsp_cs_config(dev_link_t *link) | |||
1947 | device, and release the PCMCIA configuration. If the device is | 1932 | device, and release the PCMCIA configuration. If the device is |
1948 | still open, this will be postponed until it is closed. | 1933 | still open, this will be postponed until it is closed. |
1949 | ======================================================================*/ | 1934 | ======================================================================*/ |
1950 | static void nsp_cs_release(dev_link_t *link) | 1935 | static void nsp_cs_release(struct pcmcia_device *link) |
1951 | { | 1936 | { |
1952 | scsi_info_t *info = link->priv; | 1937 | scsi_info_t *info = link->priv; |
1953 | nsp_hw_data *data = NULL; | 1938 | nsp_hw_data *data = NULL; |
@@ -1968,22 +1953,15 @@ static void nsp_cs_release(dev_link_t *link) | |||
1968 | #else | 1953 | #else |
1969 | scsi_unregister_host(&nsp_driver_template); | 1954 | scsi_unregister_host(&nsp_driver_template); |
1970 | #endif | 1955 | #endif |
1971 | link->dev = NULL; | 1956 | link->dev_node = NULL; |
1972 | 1957 | ||
1973 | if (link->win) { | 1958 | if (link->win) { |
1974 | if (data != NULL) { | 1959 | if (data != NULL) { |
1975 | iounmap((void *)(data->MmioAddress)); | 1960 | iounmap((void *)(data->MmioAddress)); |
1976 | } | 1961 | } |
1977 | pcmcia_release_window(link->win); | ||
1978 | } | ||
1979 | pcmcia_release_configuration(link->handle); | ||
1980 | if (link->io.NumPorts1) { | ||
1981 | pcmcia_release_io(link->handle, &link->io); | ||
1982 | } | 1962 | } |
1983 | if (link->irq.AssignedIRQ) { | 1963 | pcmcia_disable_device(link); |
1984 | pcmcia_release_irq(link->handle, &link->irq); | 1964 | |
1985 | } | ||
1986 | link->state &= ~DEV_CONFIG; | ||
1987 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) | 1965 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) |
1988 | if (info->host != NULL) { | 1966 | if (info->host != NULL) { |
1989 | scsi_host_put(info->host); | 1967 | scsi_host_put(info->host); |
@@ -1991,14 +1969,11 @@ static void nsp_cs_release(dev_link_t *link) | |||
1991 | #endif | 1969 | #endif |
1992 | } /* nsp_cs_release */ | 1970 | } /* nsp_cs_release */ |
1993 | 1971 | ||
1994 | static int nsp_cs_suspend(struct pcmcia_device *dev) | 1972 | static int nsp_cs_suspend(struct pcmcia_device *link) |
1995 | { | 1973 | { |
1996 | dev_link_t *link = dev_to_instance(dev); | ||
1997 | scsi_info_t *info = link->priv; | 1974 | scsi_info_t *info = link->priv; |
1998 | nsp_hw_data *data; | 1975 | nsp_hw_data *data; |
1999 | 1976 | ||
2000 | link->state |= DEV_SUSPEND; | ||
2001 | |||
2002 | nsp_dbg(NSP_DEBUG_INIT, "event: suspend"); | 1977 | nsp_dbg(NSP_DEBUG_INIT, "event: suspend"); |
2003 | 1978 | ||
2004 | if (info->host != NULL) { | 1979 | if (info->host != NULL) { |
@@ -2011,25 +1986,16 @@ static int nsp_cs_suspend(struct pcmcia_device *dev) | |||
2011 | 1986 | ||
2012 | info->stop = 1; | 1987 | info->stop = 1; |
2013 | 1988 | ||
2014 | if (link->state & DEV_CONFIG) | ||
2015 | pcmcia_release_configuration(link->handle); | ||
2016 | |||
2017 | return 0; | 1989 | return 0; |
2018 | } | 1990 | } |
2019 | 1991 | ||
2020 | static int nsp_cs_resume(struct pcmcia_device *dev) | 1992 | static int nsp_cs_resume(struct pcmcia_device *link) |
2021 | { | 1993 | { |
2022 | dev_link_t *link = dev_to_instance(dev); | ||
2023 | scsi_info_t *info = link->priv; | 1994 | scsi_info_t *info = link->priv; |
2024 | nsp_hw_data *data; | 1995 | nsp_hw_data *data; |
2025 | 1996 | ||
2026 | nsp_dbg(NSP_DEBUG_INIT, "event: resume"); | 1997 | nsp_dbg(NSP_DEBUG_INIT, "event: resume"); |
2027 | 1998 | ||
2028 | link->state &= ~DEV_SUSPEND; | ||
2029 | |||
2030 | if (link->state & DEV_CONFIG) | ||
2031 | pcmcia_request_configuration(link->handle, &link->conf); | ||
2032 | |||
2033 | info->stop = 0; | 1999 | info->stop = 0; |
2034 | 2000 | ||
2035 | if (info->host != NULL) { | 2001 | if (info->host != NULL) { |
@@ -2065,7 +2031,7 @@ static struct pcmcia_driver nsp_driver = { | |||
2065 | .drv = { | 2031 | .drv = { |
2066 | .name = "nsp_cs", | 2032 | .name = "nsp_cs", |
2067 | }, | 2033 | }, |
2068 | .probe = nsp_cs_attach, | 2034 | .probe = nsp_cs_probe, |
2069 | .remove = nsp_cs_detach, | 2035 | .remove = nsp_cs_detach, |
2070 | .id_table = nsp_cs_ids, | 2036 | .id_table = nsp_cs_ids, |
2071 | .suspend = nsp_cs_suspend, | 2037 | .suspend = nsp_cs_suspend, |
@@ -2098,19 +2064,7 @@ static int __init nsp_cs_init(void) | |||
2098 | static void __exit nsp_cs_exit(void) | 2064 | static void __exit nsp_cs_exit(void) |
2099 | { | 2065 | { |
2100 | nsp_msg(KERN_INFO, "unloading..."); | 2066 | nsp_msg(KERN_INFO, "unloading..."); |
2101 | |||
2102 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) | ||
2103 | pcmcia_unregister_driver(&nsp_driver); | 2067 | pcmcia_unregister_driver(&nsp_driver); |
2104 | #else | ||
2105 | unregister_pcmcia_driver(&dev_info); | ||
2106 | /* XXX: this really needs to move into generic code.. */ | ||
2107 | while (dev_list != NULL) { | ||
2108 | if (dev_list->state & DEV_CONFIG) { | ||
2109 | nsp_cs_release(dev_list); | ||
2110 | } | ||
2111 | nsp_cs_detach(dev_list); | ||
2112 | } | ||
2113 | #endif | ||
2114 | } | 2068 | } |
2115 | 2069 | ||
2116 | 2070 | ||