diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-12 19:45:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-12 19:45:40 -0400 |
commit | 0cdf6990e992902ae59cbc625d28cb41390f378e (patch) | |
tree | 0c01cf792be5f36ea34064036005f424ab95a571 /drivers/infiniband/hw/ipath/ipath_driver.c | |
parent | de081fa517fed81b0369f2e90ca87c30182879c8 (diff) | |
parent | cec7c893d8654723028f09d33341e42673558057 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband: (76 commits)
IB: Update MAINTAINERS with Hal's new email address
IB/mlx4: Implement query SRQ
IB/mlx4: Implement query QP
IB/cm: Send no match if a SIDR REQ does not match a listen
IB/cm: Fix handling of duplicate SIDR REQs
IB/cm: cm_msgs.h should include ib_cm.h
IB/cm: Include HCA ACK delay in local ACK timeout
IB/cm: Use spin_lock_irq() instead of spin_lock_irqsave() when possible
IB/sa: Make sure SA queries use default P_Key
IPoIB: Recycle loopback skbs instead of freeing and reallocating
IB/mthca: Replace memset(<addr>, 0, PAGE_SIZE) with clear_page(<addr>)
IPoIB/cm: Fix warning if IPV6 is not enabled
IB/core: Take sizeof the correct pointer when calling kmalloc()
IB/ehca: Improve latency by unlocking after triggering the hardware
IB/ehca: Notify consumers of LID/PKEY/SM changes after nondisruptive events
IB/ehca: Return QP pointer in poll_cq()
IB/ehca: Change idr spinlocks into rwlocks
IB/ehca: Refactor sync between completions and destroy_cq using atomic_t
IB/ehca: Lock renaming, static initializers
IB/ehca: Report RDMA atomic attributes in query_qp()
...
Diffstat (limited to 'drivers/infiniband/hw/ipath/ipath_driver.c')
-rw-r--r-- | drivers/infiniband/hw/ipath/ipath_driver.c | 187 |
1 files changed, 155 insertions, 32 deletions
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 834e86f6c04..9361f5ab8bd 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 QLogic, Inc. All rights reserved. | 2 | * Copyright (c) 2006, 2007 QLogic Corporation. All rights reserved. |
3 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | 3 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This software is available to you under a choice of one of two | 5 | * This software is available to you under a choice of one of two |
@@ -104,6 +104,9 @@ static int __devinit ipath_init_one(struct pci_dev *, | |||
104 | #define PCI_DEVICE_ID_INFINIPATH_HT 0xd | 104 | #define PCI_DEVICE_ID_INFINIPATH_HT 0xd |
105 | #define PCI_DEVICE_ID_INFINIPATH_PE800 0x10 | 105 | #define PCI_DEVICE_ID_INFINIPATH_PE800 0x10 |
106 | 106 | ||
107 | /* Number of seconds before our card status check... */ | ||
108 | #define STATUS_TIMEOUT 60 | ||
109 | |||
107 | static const struct pci_device_id ipath_pci_tbl[] = { | 110 | static const struct pci_device_id ipath_pci_tbl[] = { |
108 | { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) }, | 111 | { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_HT) }, |
109 | { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) }, | 112 | { PCI_DEVICE(PCI_VENDOR_ID_PATHSCALE, PCI_DEVICE_ID_INFINIPATH_PE800) }, |
@@ -119,6 +122,18 @@ static struct pci_driver ipath_driver = { | |||
119 | .id_table = ipath_pci_tbl, | 122 | .id_table = ipath_pci_tbl, |
120 | }; | 123 | }; |
121 | 124 | ||
125 | static void ipath_check_status(struct work_struct *work) | ||
126 | { | ||
127 | struct ipath_devdata *dd = container_of(work, struct ipath_devdata, | ||
128 | status_work.work); | ||
129 | |||
130 | /* | ||
131 | * If we don't have any interrupts, let the user know and | ||
132 | * don't bother checking again. | ||
133 | */ | ||
134 | if (dd->ipath_int_counter == 0) | ||
135 | dev_err(&dd->pcidev->dev, "No interrupts detected.\n"); | ||
136 | } | ||
122 | 137 | ||
123 | static inline void read_bars(struct ipath_devdata *dd, struct pci_dev *dev, | 138 | static inline void read_bars(struct ipath_devdata *dd, struct pci_dev *dev, |
124 | u32 *bar0, u32 *bar1) | 139 | u32 *bar0, u32 *bar1) |
@@ -187,6 +202,8 @@ static struct ipath_devdata *ipath_alloc_devdata(struct pci_dev *pdev) | |||
187 | dd->pcidev = pdev; | 202 | dd->pcidev = pdev; |
188 | pci_set_drvdata(pdev, dd); | 203 | pci_set_drvdata(pdev, dd); |
189 | 204 | ||
205 | INIT_DELAYED_WORK(&dd->status_work, ipath_check_status); | ||
206 | |||
190 | list_add(&dd->ipath_list, &ipath_dev_list); | 207 | list_add(&dd->ipath_list, &ipath_dev_list); |
191 | 208 | ||
192 | bail_unlock: | 209 | bail_unlock: |
@@ -504,6 +521,9 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, | |||
504 | ipath_diag_add(dd); | 521 | ipath_diag_add(dd); |
505 | ipath_register_ib_device(dd); | 522 | ipath_register_ib_device(dd); |
506 | 523 | ||
524 | /* Check that card status in STATUS_TIMEOUT seconds. */ | ||
525 | schedule_delayed_work(&dd->status_work, HZ * STATUS_TIMEOUT); | ||
526 | |||
507 | goto bail; | 527 | goto bail; |
508 | 528 | ||
509 | bail_irqsetup: | 529 | bail_irqsetup: |
@@ -631,6 +651,9 @@ static void __devexit ipath_remove_one(struct pci_dev *pdev) | |||
631 | */ | 651 | */ |
632 | ipath_shutdown_device(dd); | 652 | ipath_shutdown_device(dd); |
633 | 653 | ||
654 | cancel_delayed_work(&dd->status_work); | ||
655 | flush_scheduled_work(); | ||
656 | |||
634 | if (dd->verbs_dev) | 657 | if (dd->verbs_dev) |
635 | ipath_unregister_ib_device(dd->verbs_dev); | 658 | ipath_unregister_ib_device(dd->verbs_dev); |
636 | 659 | ||
@@ -699,9 +722,9 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first, | |||
699 | u64 sendctrl, sendorig; | 722 | u64 sendctrl, sendorig; |
700 | 723 | ||
701 | ipath_cdbg(PKT, "disarm %u PIObufs first=%u\n", cnt, first); | 724 | ipath_cdbg(PKT, "disarm %u PIObufs first=%u\n", cnt, first); |
702 | sendorig = dd->ipath_sendctrl | INFINIPATH_S_DISARM; | 725 | sendorig = dd->ipath_sendctrl; |
703 | for (i = first; i < last; i++) { | 726 | for (i = first; i < last; i++) { |
704 | sendctrl = sendorig | | 727 | sendctrl = sendorig | INFINIPATH_S_DISARM | |
705 | (i << INFINIPATH_S_DISARMPIOBUF_SHIFT); | 728 | (i << INFINIPATH_S_DISARMPIOBUF_SHIFT); |
706 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 729 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
707 | sendctrl); | 730 | sendctrl); |
@@ -712,12 +735,12 @@ void ipath_disarm_piobufs(struct ipath_devdata *dd, unsigned first, | |||
712 | * while we were looping; no critical bits that would require | 735 | * while we were looping; no critical bits that would require |
713 | * locking. | 736 | * locking. |
714 | * | 737 | * |
715 | * Write a 0, and then the original value, reading scratch in | 738 | * disable PIOAVAILUPD, then re-enable, reading scratch in |
716 | * between. This seems to avoid a chip timing race that causes | 739 | * between. This seems to avoid a chip timing race that causes |
717 | * pioavail updates to memory to stop. | 740 | * pioavail updates to memory to stop. |
718 | */ | 741 | */ |
719 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 742 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
720 | 0); | 743 | sendorig & ~IPATH_S_PIOBUFAVAILUPD); |
721 | sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | 744 | sendorig = ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); |
722 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 745 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, |
723 | dd->ipath_sendctrl); | 746 | dd->ipath_sendctrl); |
@@ -1014,14 +1037,10 @@ void ipath_kreceive(struct ipath_devdata *dd) | |||
1014 | goto bail; | 1037 | goto bail; |
1015 | } | 1038 | } |
1016 | 1039 | ||
1017 | /* There is already a thread processing this queue. */ | ||
1018 | if (test_and_set_bit(0, &dd->ipath_rcv_pending)) | ||
1019 | goto bail; | ||
1020 | |||
1021 | l = dd->ipath_port0head; | 1040 | l = dd->ipath_port0head; |
1022 | hdrqtail = (u32) le64_to_cpu(*dd->ipath_hdrqtailptr); | 1041 | hdrqtail = (u32) le64_to_cpu(*dd->ipath_hdrqtailptr); |
1023 | if (l == hdrqtail) | 1042 | if (l == hdrqtail) |
1024 | goto done; | 1043 | goto bail; |
1025 | 1044 | ||
1026 | reloop: | 1045 | reloop: |
1027 | for (i = 0; l != hdrqtail; i++) { | 1046 | for (i = 0; l != hdrqtail; i++) { |
@@ -1156,10 +1175,6 @@ reloop: | |||
1156 | ipath_stats.sps_avgpkts_call = | 1175 | ipath_stats.sps_avgpkts_call = |
1157 | ipath_stats.sps_port0pkts / ++totcalls; | 1176 | ipath_stats.sps_port0pkts / ++totcalls; |
1158 | 1177 | ||
1159 | done: | ||
1160 | clear_bit(0, &dd->ipath_rcv_pending); | ||
1161 | smp_mb__after_clear_bit(); | ||
1162 | |||
1163 | bail:; | 1178 | bail:; |
1164 | } | 1179 | } |
1165 | 1180 | ||
@@ -1589,6 +1604,35 @@ int ipath_waitfor_mdio_cmdready(struct ipath_devdata *dd) | |||
1589 | return ret; | 1604 | return ret; |
1590 | } | 1605 | } |
1591 | 1606 | ||
1607 | |||
1608 | /* | ||
1609 | * Flush all sends that might be in the ready to send state, as well as any | ||
1610 | * that are in the process of being sent. Used whenever we need to be | ||
1611 | * sure the send side is idle. Cleans up all buffer state by canceling | ||
1612 | * all pio buffers, and issuing an abort, which cleans up anything in the | ||
1613 | * launch fifo. The cancel is superfluous on some chip versions, but | ||
1614 | * it's safer to always do it. | ||
1615 | * PIOAvail bits are updated by the chip as if normal send had happened. | ||
1616 | */ | ||
1617 | void ipath_cancel_sends(struct ipath_devdata *dd) | ||
1618 | { | ||
1619 | ipath_dbg("Cancelling all in-progress send buffers\n"); | ||
1620 | dd->ipath_lastcancel = jiffies+HZ/2; /* skip armlaunch errs a bit */ | ||
1621 | /* | ||
1622 | * the abort bit is auto-clearing. We read scratch to be sure | ||
1623 | * that cancels and the abort have taken effect in the chip. | ||
1624 | */ | ||
1625 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
1626 | INFINIPATH_S_ABORT); | ||
1627 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
1628 | ipath_disarm_piobufs(dd, 0, | ||
1629 | (unsigned)(dd->ipath_piobcnt2k + dd->ipath_piobcnt4k)); | ||
1630 | |||
1631 | /* and again, be sure all have hit the chip */ | ||
1632 | ipath_read_kreg64(dd, dd->ipath_kregs->kr_scratch); | ||
1633 | } | ||
1634 | |||
1635 | |||
1592 | static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) | 1636 | static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) |
1593 | { | 1637 | { |
1594 | static const char *what[4] = { | 1638 | static const char *what[4] = { |
@@ -1610,14 +1654,8 @@ static void ipath_set_ib_lstate(struct ipath_devdata *dd, int which) | |||
1610 | INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]); | 1654 | INFINIPATH_IBCS_LINKTRAININGSTATE_MASK]); |
1611 | /* flush all queued sends when going to DOWN or INIT, to be sure that | 1655 | /* flush all queued sends when going to DOWN or INIT, to be sure that |
1612 | * they don't block MAD packets */ | 1656 | * they don't block MAD packets */ |
1613 | if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) { | 1657 | if (!linkcmd || linkcmd == INFINIPATH_IBCC_LINKCMD_INIT) |
1614 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | 1658 | ipath_cancel_sends(dd); |
1615 | INFINIPATH_S_ABORT); | ||
1616 | ipath_disarm_piobufs(dd, dd->ipath_lastport_piobuf, | ||
1617 | (unsigned)(dd->ipath_piobcnt2k + | ||
1618 | dd->ipath_piobcnt4k) - | ||
1619 | dd->ipath_lastport_piobuf); | ||
1620 | } | ||
1621 | 1659 | ||
1622 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, | 1660 | ipath_write_kreg(dd, dd->ipath_kregs->kr_ibcctrl, |
1623 | dd->ipath_ibcctrl | which); | 1661 | dd->ipath_ibcctrl | which); |
@@ -1839,6 +1877,87 @@ void ipath_write_kreg_port(const struct ipath_devdata *dd, ipath_kreg regno, | |||
1839 | ipath_write_kreg(dd, where, value); | 1877 | ipath_write_kreg(dd, where, value); |
1840 | } | 1878 | } |
1841 | 1879 | ||
1880 | /* | ||
1881 | * Following deal with the "obviously simple" task of overriding the state | ||
1882 | * of the LEDS, which normally indicate link physical and logical status. | ||
1883 | * The complications arise in dealing with different hardware mappings | ||
1884 | * and the board-dependent routine being called from interrupts. | ||
1885 | * and then there's the requirement to _flash_ them. | ||
1886 | */ | ||
1887 | #define LED_OVER_FREQ_SHIFT 8 | ||
1888 | #define LED_OVER_FREQ_MASK (0xFF<<LED_OVER_FREQ_SHIFT) | ||
1889 | /* Below is "non-zero" to force override, but both actual LEDs are off */ | ||
1890 | #define LED_OVER_BOTH_OFF (8) | ||
1891 | |||
1892 | void ipath_run_led_override(unsigned long opaque) | ||
1893 | { | ||
1894 | struct ipath_devdata *dd = (struct ipath_devdata *)opaque; | ||
1895 | int timeoff; | ||
1896 | int pidx; | ||
1897 | u64 lstate, ltstate, val; | ||
1898 | |||
1899 | if (!(dd->ipath_flags & IPATH_INITTED)) | ||
1900 | return; | ||
1901 | |||
1902 | pidx = dd->ipath_led_override_phase++ & 1; | ||
1903 | dd->ipath_led_override = dd->ipath_led_override_vals[pidx]; | ||
1904 | timeoff = dd->ipath_led_override_timeoff; | ||
1905 | |||
1906 | /* | ||
1907 | * below potentially restores the LED values per current status, | ||
1908 | * should also possibly setup the traffic-blink register, | ||
1909 | * but leave that to per-chip functions. | ||
1910 | */ | ||
1911 | val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_ibcstatus); | ||
1912 | ltstate = (val >> INFINIPATH_IBCS_LINKTRAININGSTATE_SHIFT) & | ||
1913 | INFINIPATH_IBCS_LINKTRAININGSTATE_MASK; | ||
1914 | lstate = (val >> INFINIPATH_IBCS_LINKSTATE_SHIFT) & | ||
1915 | INFINIPATH_IBCS_LINKSTATE_MASK; | ||
1916 | |||
1917 | dd->ipath_f_setextled(dd, lstate, ltstate); | ||
1918 | mod_timer(&dd->ipath_led_override_timer, jiffies + timeoff); | ||
1919 | } | ||
1920 | |||
1921 | void ipath_set_led_override(struct ipath_devdata *dd, unsigned int val) | ||
1922 | { | ||
1923 | int timeoff, freq; | ||
1924 | |||
1925 | if (!(dd->ipath_flags & IPATH_INITTED)) | ||
1926 | return; | ||
1927 | |||
1928 | /* First check if we are blinking. If not, use 1HZ polling */ | ||
1929 | timeoff = HZ; | ||
1930 | freq = (val & LED_OVER_FREQ_MASK) >> LED_OVER_FREQ_SHIFT; | ||
1931 | |||
1932 | if (freq) { | ||
1933 | /* For blink, set each phase from one nybble of val */ | ||
1934 | dd->ipath_led_override_vals[0] = val & 0xF; | ||
1935 | dd->ipath_led_override_vals[1] = (val >> 4) & 0xF; | ||
1936 | timeoff = (HZ << 4)/freq; | ||
1937 | } else { | ||
1938 | /* Non-blink set both phases the same. */ | ||
1939 | dd->ipath_led_override_vals[0] = val & 0xF; | ||
1940 | dd->ipath_led_override_vals[1] = val & 0xF; | ||
1941 | } | ||
1942 | dd->ipath_led_override_timeoff = timeoff; | ||
1943 | |||
1944 | /* | ||
1945 | * If the timer has not already been started, do so. Use a "quick" | ||
1946 | * timeout so the function will be called soon, to look at our request. | ||
1947 | */ | ||
1948 | if (atomic_inc_return(&dd->ipath_led_override_timer_active) == 1) { | ||
1949 | /* Need to start timer */ | ||
1950 | init_timer(&dd->ipath_led_override_timer); | ||
1951 | dd->ipath_led_override_timer.function = | ||
1952 | ipath_run_led_override; | ||
1953 | dd->ipath_led_override_timer.data = (unsigned long) dd; | ||
1954 | dd->ipath_led_override_timer.expires = jiffies + 1; | ||
1955 | add_timer(&dd->ipath_led_override_timer); | ||
1956 | } else { | ||
1957 | atomic_dec(&dd->ipath_led_override_timer_active); | ||
1958 | } | ||
1959 | } | ||
1960 | |||
1842 | /** | 1961 | /** |
1843 | * ipath_shutdown_device - shut down a device | 1962 | * ipath_shutdown_device - shut down a device |
1844 | * @dd: the infinipath device | 1963 | * @dd: the infinipath device |
@@ -1879,17 +1998,9 @@ void ipath_shutdown_device(struct ipath_devdata *dd) | |||
1879 | */ | 1998 | */ |
1880 | udelay(5); | 1999 | udelay(5); |
1881 | 2000 | ||
1882 | /* | ||
1883 | * abort any armed or launched PIO buffers that didn't go. (self | ||
1884 | * clearing). Will cause any packet currently being transmitted to | ||
1885 | * go out with an EBP, and may also cause a short packet error on | ||
1886 | * the receiver. | ||
1887 | */ | ||
1888 | ipath_write_kreg(dd, dd->ipath_kregs->kr_sendctrl, | ||
1889 | INFINIPATH_S_ABORT); | ||
1890 | |||
1891 | ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE << | 2001 | ipath_set_ib_lstate(dd, INFINIPATH_IBCC_LINKINITCMD_DISABLE << |
1892 | INFINIPATH_IBCC_LINKINITCMD_SHIFT); | 2002 | INFINIPATH_IBCC_LINKINITCMD_SHIFT); |
2003 | ipath_cancel_sends(dd); | ||
1893 | 2004 | ||
1894 | /* disable IBC */ | 2005 | /* disable IBC */ |
1895 | dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; | 2006 | dd->ipath_control &= ~INFINIPATH_C_LINKENABLE; |
@@ -1902,7 +2013,6 @@ void ipath_shutdown_device(struct ipath_devdata *dd) | |||
1902 | * Turn the LEDs off explictly for the same reason. | 2013 | * Turn the LEDs off explictly for the same reason. |
1903 | */ | 2014 | */ |
1904 | dd->ipath_f_quiet_serdes(dd); | 2015 | dd->ipath_f_quiet_serdes(dd); |
1905 | dd->ipath_f_setextled(dd, 0, 0); | ||
1906 | 2016 | ||
1907 | if (dd->ipath_stats_timer_active) { | 2017 | if (dd->ipath_stats_timer_active) { |
1908 | del_timer_sync(&dd->ipath_stats_timer); | 2018 | del_timer_sync(&dd->ipath_stats_timer); |
@@ -1918,6 +2028,9 @@ void ipath_shutdown_device(struct ipath_devdata *dd) | |||
1918 | ~0ULL & ~INFINIPATH_HWE_MEMBISTFAILED); | 2028 | ~0ULL & ~INFINIPATH_HWE_MEMBISTFAILED); |
1919 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, -1LL); | 2029 | ipath_write_kreg(dd, dd->ipath_kregs->kr_errorclear, -1LL); |
1920 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL); | 2030 | ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, -1LL); |
2031 | |||
2032 | ipath_cdbg(VERBOSE, "Flush time and errors to EEPROM\n"); | ||
2033 | ipath_update_eeprom_log(dd); | ||
1921 | } | 2034 | } |
1922 | 2035 | ||
1923 | /** | 2036 | /** |
@@ -2078,6 +2191,16 @@ int ipath_reset_device(int unit) | |||
2078 | goto bail; | 2191 | goto bail; |
2079 | } | 2192 | } |
2080 | 2193 | ||
2194 | if (atomic_read(&dd->ipath_led_override_timer_active)) { | ||
2195 | /* Need to stop LED timer, _then_ shut off LEDs */ | ||
2196 | del_timer_sync(&dd->ipath_led_override_timer); | ||
2197 | atomic_set(&dd->ipath_led_override_timer_active, 0); | ||
2198 | } | ||
2199 | |||
2200 | /* Shut off LEDs after we are sure timer is not running */ | ||
2201 | dd->ipath_led_override = LED_OVER_BOTH_OFF; | ||
2202 | dd->ipath_f_setextled(dd, 0, 0); | ||
2203 | |||
2081 | dev_info(&dd->pcidev->dev, "Reset on unit %u requested\n", unit); | 2204 | dev_info(&dd->pcidev->dev, "Reset on unit %u requested\n", unit); |
2082 | 2205 | ||
2083 | if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT)) { | 2206 | if (!dd->ipath_kregbase || !(dd->ipath_flags & IPATH_PRESENT)) { |