diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/an/if_an.c | 369 | ||||
-rw-r--r-- | sys/dev/an/if_an_pci.c | 5 | ||||
-rw-r--r-- | sys/dev/an/if_anreg.h | 1 |
3 files changed, 253 insertions, 122 deletions
diff --git a/sys/dev/an/if_an.c b/sys/dev/an/if_an.c index db88e0c..6a335f4 100644 --- a/sys/dev/an/if_an.c +++ b/sys/dev/an/if_an.c @@ -283,7 +283,7 @@ sysctl_an_cache_mode(SYSCTL_HANDLER_ARGS) break; } - error = sysctl_handle_string(oidp, an_conf_cache, + error = sysctl_handle_string(oidp, an_conf_cache, sizeof(an_conf_cache), req); if (strncmp(an_conf_cache,"dbm", 3) == 0) { @@ -303,6 +303,23 @@ SYSCTL_PROC(_hw_an, OID_AUTO, an_cache_mode, CTLTYPE_STRING | CTLFLAG_RW, 0, sizeof(an_conf_cache), sysctl_an_cache_mode, "A", ""); /* + * Setup the lock for PCI attachment since it skips the an_probe + * function. We need to setup the lock in an_probe since some + * operations need the lock. So we might as well create the + * lock in the probe. + */ +int +an_pci_probe(device_t dev) +{ + struct an_softc *sc = device_get_softc(dev); + + mtx_init(&sc->an_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, + MTX_DEF | MTX_RECURSE); + + return(0); +} + +/* * We probe for an Aironet 4500/4800 card by attempting to * read the default SSID list. On reset, the first entry in * the SSID list will contain the name "tsunami." If we don't @@ -342,19 +359,32 @@ an_probe(device_t dev) CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), 0); CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), 0xFFFF); + mtx_init(&sc->an_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, + MTX_DEF | MTX_RECURSE); + AN_LOCK(sc); an_reset(sc); - if (an_cmd(sc, AN_CMD_READCFG, 0)) - return(0); + if (an_cmd(sc, AN_CMD_READCFG, 0)) { + AN_UNLOCK(sc); + goto fail; + } - if (an_read_record(sc, (struct an_ltv_gen *)&ssid)) - return(0); + if (an_read_record(sc, (struct an_ltv_gen *)&ssid)) { + AN_UNLOCK(sc); + goto fail; + } /* See if the ssid matches what we expect ... but doesn't have to */ - if (strcmp(ssid.an_entry[0].an_ssid, AN_DEF_SSID)) - return(0); + if (strcmp(ssid.an_entry[0].an_ssid, AN_DEF_SSID)) { + AN_UNLOCK(sc); + goto fail; + } + AN_UNLOCK(sc); return(AN_IOSIZ); +fail: + mtx_destroy(&sc->an_mtx); + return(0); } /* @@ -548,6 +578,7 @@ an_init_mpi350_desc(struct an_softc *sc) struct an_card_tx_desc an_tx_desc; int i, desc; + AN_LOCK_ASSERT(sc); if(!sc->an_rid_buffer.an_dma_paddr) an_dma_malloc(sc, AN_RID_BUFFER_SIZE, &sc->an_rid_buffer, 0); @@ -569,7 +600,7 @@ an_init_mpi350_desc(struct an_softc *sc) cmd_struct.an_parm1 = AN_RX_DESC_OFFSET; cmd_struct.an_parm2 = AN_MAX_RX_DESC; if (an_cmd_struct(sc, &cmd_struct, &reply)) { - printf("an%d: failed to allocate RX descriptor\n", + printf("an%d: failed to allocate RX descriptor\n", sc->an_unit); return(EIO); } @@ -598,7 +629,7 @@ an_init_mpi350_desc(struct an_softc *sc) cmd_struct.an_parm1 = AN_TX_DESC_OFFSET; cmd_struct.an_parm2 = AN_MAX_TX_DESC; if (an_cmd_struct(sc, &cmd_struct, &reply)) { - printf("an%d: failed to allocate TX descriptor\n", + printf("an%d: failed to allocate TX descriptor\n", sc->an_unit); return(EIO); } @@ -628,7 +659,7 @@ an_init_mpi350_desc(struct an_softc *sc) cmd_struct.an_parm1 = AN_HOST_DESC_OFFSET; cmd_struct.an_parm2 = 1; if (an_cmd_struct(sc, &cmd_struct, &reply)) { - printf("an%d: failed to allocate host descriptor\n", + printf("an%d: failed to allocate host descriptor\n", sc->an_unit); return(EIO); } @@ -640,7 +671,7 @@ an_init_mpi350_desc(struct an_softc *sc) an_rid_desc.an_phys = sc->an_rid_buffer.an_dma_paddr; for (i = 0; i < sizeof(an_rid_desc) / 4; i++) - CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4, + CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4, ((u_int32_t *)(void *)&an_rid_desc)[i]); return(0); @@ -654,14 +685,12 @@ an_attach(struct an_softc *sc, int unit, int flags) int i, nrate, mword; u_int8_t r; - mtx_init(&sc->an_mtx, device_get_nameunit(sc->an_dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); ifp = sc->an_ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { printf("an%d: can not if_alloc()\n", sc->an_unit); goto fail; } - + sc->an_gone = 0; sc->an_associated = 0; sc->an_monitor = 0; @@ -669,6 +698,7 @@ an_attach(struct an_softc *sc, int unit, int flags) sc->an_flash_buffer = NULL; /* Reset the NIC. */ + AN_LOCK(sc); an_reset(sc); if (sc->mpi350) { error = an_init_mpi350_desc(sc); @@ -730,6 +760,7 @@ an_attach(struct an_softc *sc, int unit, int flags) printf("an%d: no RSSI <-> dBM map\n", sc->an_unit); } #endif + AN_UNLOCK(sc); ifp->if_softc = sc; sc->an_unit = unit; @@ -781,7 +812,7 @@ an_attach(struct an_softc *sc, int unit, int flags) ADD(mword, IFM_IEEE80211_ADHOC); } printf("\n"); - ifmedia_set(&sc->an_ifmedia, IFM_MAKEWORD(IFM_IEEE80211, + ifmedia_set(&sc->an_ifmedia, IFM_MAKEWORD(IFM_IEEE80211, IFM_AUTO, 0, 0)); #undef ADD @@ -793,7 +824,8 @@ an_attach(struct an_softc *sc, int unit, int flags) callout_init_mtx(&sc->an_stat_ch, &sc->an_mtx, 0); return(0); -fail:; +fail: + AN_UNLOCK(sc); mtx_destroy(&sc->an_mtx); if (ifp != NULL) if_free(ifp); @@ -890,7 +922,7 @@ an_rxeof(struct an_softc *sc) rx_frame.an_rx_payload_len); } else { fc1=rx_frame.an_frame_ctl >> 8; - ieee80211_header_len = + ieee80211_header_len = sizeof(struct ieee80211_frame); if ((fc1 & IEEE80211_FC1_DIR_TODS) && (fc1 & IEEE80211_FC1_DIR_FROMDS)) { @@ -937,7 +969,7 @@ an_rxeof(struct an_softc *sc) #ifdef ANCACHE /* Read NIC frame header */ - if (an_read_data(sc, id, 0, (caddr_t)&rx_frame, + if (an_read_data(sc, id, 0, (caddr_t)&rx_frame, sizeof(rx_frame))) { m_freem(m); ifp->if_ierrors++; @@ -945,7 +977,7 @@ an_rxeof(struct an_softc *sc) } #endif /* Read in the 802_3 frame header */ - if (an_read_data(sc, id, 0x34, + if (an_read_data(sc, id, 0x34, (caddr_t)&rx_frame_802_3, sizeof(rx_frame_802_3))) { m_freem(m); @@ -978,7 +1010,7 @@ an_rxeof(struct an_softc *sc) (char *)&eh->ether_shost, ETHER_ADDR_LEN); /* in mbuf header type is just before payload */ - error = an_read_data(sc, id, 0x44, + error = an_read_data(sc, id, 0x44, (caddr_t)&(eh->ether_type), rx_frame_802_3.an_rx_802_3_payload_len); @@ -991,7 +1023,7 @@ an_rxeof(struct an_softc *sc) /* Receive packet. */ #ifdef ANCACHE - an_cache_store(sc, eh, m, + an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength, rx_frame.an_rsvd0); #endif @@ -1003,9 +1035,9 @@ an_rxeof(struct an_softc *sc) } else { /* MPI-350 */ for (count = 0; count < AN_MAX_RX_DESC; count++){ for (i = 0; i < sizeof(an_rx_desc) / 4; i++) - ((u_int32_t *)(void *)&an_rx_desc)[i] - = CSR_MEM_AUX_READ_4(sc, - AN_RX_DESC_OFFSET + ((u_int32_t *)(void *)&an_rx_desc)[i] + = CSR_MEM_AUX_READ_4(sc, + AN_RX_DESC_OFFSET + (count * sizeof(an_rx_desc)) + (i * 4)); @@ -1026,14 +1058,14 @@ an_rxeof(struct an_softc *sc) m->m_pkthdr.rcvif = ifp; /* Read Ethernet encapsulated packet */ - /* + /* * No ANCACHE support since we just get back * an Ethernet packet no 802.11 info */ #if 0 #ifdef ANCACHE /* Read NIC frame header */ - bcopy(buf, (caddr_t)&rx_frame, + bcopy(buf, (caddr_t)&rx_frame, sizeof(rx_frame)); #endif #endif @@ -1050,18 +1082,18 @@ an_rxeof(struct an_softc *sc) m->m_pkthdr.len = m->m_len = an_rx_desc.an_len + 12; - + eh = mtod(m, struct ether_header *); - + bcopy(buf, (char *)eh, m->m_pkthdr.len); - + ifp->if_ipackets++; - + /* Receive packet. */ #if 0 #ifdef ANCACHE - an_cache_store(sc, eh, m, + an_cache_store(sc, eh, m, rx_frame.an_rx_signal_strength, rx_frame.an_rsvd0); #endif @@ -1073,16 +1105,16 @@ an_rxeof(struct an_softc *sc) an_rx_desc.an_valid = 1; an_rx_desc.an_len = AN_RX_BUFFER_SIZE; an_rx_desc.an_done = 0; - an_rx_desc.an_phys = + an_rx_desc.an_phys = sc->an_rx_buffer[count].an_dma_paddr; - + for (i = 0; i < sizeof(an_rx_desc) / 4; i++) - CSR_MEM_AUX_WRITE_4(sc, - AN_RX_DESC_OFFSET + CSR_MEM_AUX_WRITE_4(sc, + AN_RX_DESC_OFFSET + (count * sizeof(an_rx_desc)) + (i * 4), ((u_int32_t *)(void *)&an_rx_desc)[i]); - + } else { printf("an%d: Didn't get valid RX packet " "%x %x %d\n", @@ -1100,6 +1132,7 @@ an_txeof(struct an_softc *sc, int status) struct ifnet *ifp; int id, i; + AN_LOCK_ASSERT(sc); ifp = sc->an_ifp; ifp->if_timer = 0; @@ -1211,7 +1244,7 @@ an_intr(void *xsc) } if (status & AN_EV_LINKSTAT) { - if (CSR_READ_2(sc, AN_LINKSTAT(sc->mpi350)) + if (CSR_READ_2(sc, AN_LINKSTAT(sc->mpi350)) == AN_LINKSTAT_ASSOCIATED) sc->an_associated = 1; else @@ -1260,6 +1293,7 @@ an_cmd_struct(struct an_softc *sc, struct an_command *cmd, { int i; + AN_LOCK_ASSERT(sc); for (i = 0; i != AN_TIMEOUT; i++) { if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) { DELAY(1000); @@ -1289,7 +1323,7 @@ an_cmd_struct(struct an_softc *sc, struct an_command *cmd, reply->an_status = CSR_READ_2(sc, AN_STATUS(sc->mpi350)); if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) - CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), + CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CLR_STUCK_BUSY); /* Ack the command */ @@ -1306,6 +1340,7 @@ an_cmd(struct an_softc *sc, int cmd, int val) { int i, s = 0; + AN_LOCK_ASSERT(sc); CSR_WRITE_2(sc, AN_PARAM0(sc->mpi350), val); CSR_WRITE_2(sc, AN_PARAM1(sc->mpi350), 0); CSR_WRITE_2(sc, AN_PARAM2(sc->mpi350), 0); @@ -1352,6 +1387,7 @@ an_reset(struct an_softc *sc) if (sc->an_gone) return; + AN_LOCK_ASSERT(sc); an_cmd(sc, AN_CMD_ENABLE, 0); an_cmd(sc, AN_CMD_FW_RESTART, 0); an_cmd(sc, AN_CMD_NOOP2, 0); @@ -1378,6 +1414,7 @@ an_read_record(struct an_softc *sc, struct an_ltv_gen *ltv) u_int8_t *ptr2; int i, len; + AN_LOCK_ASSERT(sc); if (ltv->an_len < 4 || ltv->an_type == 0) return(EINVAL); @@ -1434,13 +1471,13 @@ an_read_record(struct an_softc *sc, struct an_ltv_gen *ltv) cmd.an_parm0 = ltv->an_type; for (i = 0; i < sizeof(an_rid_desc) / 4; i++) - CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4, + CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4, ((u_int32_t *)(void *)&an_rid_desc)[i]); if (an_cmd_struct(sc, &cmd, &reply) || reply.an_status & AN_CMD_QUAL_MASK) { - printf("an%d: failed to read RID %x %x %x %x %x, %d\n", - sc->an_unit, ltv->an_type, + printf("an%d: failed to read RID %x %x %x %x %x, %d\n", + sc->an_unit, ltv->an_type, reply.an_status, reply.an_resp0, reply.an_resp1, @@ -1464,7 +1501,7 @@ an_read_record(struct an_softc *sc, struct an_ltv_gen *ltv) ltv->an_len = len + 2; } bcopy(&an_ltv->an_type, - <v->an_val, + <v->an_val, len); } @@ -1487,6 +1524,7 @@ an_write_record(struct an_softc *sc, struct an_ltv_gen *ltv) u_int8_t *ptr2; int i, len; + AN_LOCK_ASSERT(sc); if (an_dump) an_dump_record(sc, ltv, "Write"); @@ -1514,11 +1552,11 @@ an_write_record(struct an_softc *sc, struct an_ltv_gen *ltv) if (an_cmd(sc, AN_CMD_ACCESS|AN_ACCESS_WRITE, ltv->an_type)) return(EIO); - } else { + } else { /* MPI-350 */ for (i = 0; i != AN_TIMEOUT; i++) { - if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) + if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) { DELAY(10); } else @@ -1542,14 +1580,14 @@ an_write_record(struct an_softc *sc, struct an_ltv_gen *ltv) cmd.an_parm0 = ltv->an_type; for (i = 0; i < sizeof(an_rid_desc) / 4; i++) - CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4, + CSR_MEM_AUX_WRITE_4(sc, AN_HOST_DESC_OFFSET + i * 4, ((u_int32_t *)(void *)&an_rid_desc)[i]); DELAY(100000); if ((i = an_cmd_struct(sc, &cmd, &reply))) { - printf("an%d: failed to write RID 1 %x %x %x %x %x, %d\n", - sc->an_unit, ltv->an_type, + printf("an%d: failed to write RID 1 %x %x %x %x %x, %d\n", + sc->an_unit, ltv->an_type, reply.an_status, reply.an_resp0, reply.an_resp1, @@ -1560,8 +1598,8 @@ an_write_record(struct an_softc *sc, struct an_ltv_gen *ltv) if (reply.an_status & AN_CMD_QUAL_MASK) { - printf("an%d: failed to write RID 2 %x %x %x %x %x, %d\n", - sc->an_unit, ltv->an_type, + printf("an%d: failed to write RID 2 %x %x %x %x %x, %d\n", + sc->an_unit, ltv->an_type, reply.an_status, reply.an_resp0, reply.an_resp1, @@ -1741,6 +1779,7 @@ an_setdef(struct an_softc *sc, struct an_req *areq) ifp = sc->an_ifp; + AN_LOCK_ASSERT(sc); switch (areq->an_type) { case AN_RID_GENCONFIG: cfg = (struct an_ltv_genconfig *)areq; @@ -1781,13 +1820,15 @@ an_setdef(struct an_softc *sc, struct an_req *areq) break; case AN_RID_WEP_TEMP: /* Cache the temp keys */ - bcopy(areq, - &sc->an_temp_keys[((struct an_ltv_key *)areq)->kindex], + bcopy(areq, + &sc->an_temp_keys[((struct an_ltv_key *)areq)->kindex], sizeof(struct an_ltv_key)); case AN_RID_WEP_PERM: case AN_RID_LEAPUSERNAME: case AN_RID_LEAPPASSWORD: + AN_UNLOCK(sc); an_init(sc); + AN_LOCK(sc); /* Disable the MAC. */ an_cmd(sc, AN_CMD_DISABLE, 0); @@ -1828,8 +1869,11 @@ an_setdef(struct an_softc *sc, struct an_req *areq) /* Reinitialize the card. */ - if (ifp->if_flags) + if (ifp->if_flags) { + AN_UNLOCK(sc); an_init(sc); + AN_LOCK(sc); + } return; } @@ -1841,13 +1885,17 @@ an_setdef(struct an_softc *sc, struct an_req *areq) static void an_promisc(struct an_softc *sc, int promisc) { + AN_LOCK_ASSERT(sc); if (sc->an_was_monitor) { an_reset(sc); if (sc->mpi350) - an_init_mpi350_desc(sc); + an_init_mpi350_desc(sc); } - if (sc->an_monitor || sc->an_was_monitor) + if (sc->an_monitor || sc->an_was_monitor) { + AN_UNLOCK(sc); an_init(sc); + AN_LOCK(sc); + } sc->an_was_monitor = sc->an_monitor; an_cmd(sc, AN_CMD_SET_MODE, promisc ? 0xffff : 0); @@ -1876,7 +1924,6 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) struct aironet_ioctl l_ioctl; sc = ifp->if_softc; - AN_LOCK(sc); ifr = (struct ifreq *)data; ireq = (struct ieee80211req *)data; @@ -1892,6 +1939,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) switch (command) { case SIOCSIFFLAGS: + AN_LOCK(sc); if (ifp->if_flags & IFF_UP) { if (ifp->if_drv_flags & IFF_DRV_RUNNING && ifp->if_flags & IFF_PROMISC && @@ -1901,12 +1949,19 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) !(ifp->if_flags & IFF_PROMISC) && sc->an_if_flags & IFF_PROMISC) { an_promisc(sc, 0); - } else + } else { + AN_UNLOCK(sc); an_init(sc); + AN_LOCK(sc); + } } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + AN_UNLOCK(sc); an_stop(sc); + AN_LOCK(sc); + } } + AN_UNLOCK(sc); sc->an_if_flags = ifp->if_flags; error = 0; break; @@ -1920,11 +1975,10 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) error = 0; break; case SIOCGAIRONET: - AN_UNLOCK(sc); error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); - AN_LOCK(sc); if (error != 0) break; + AN_LOCK(sc); #ifdef ANCACHE if (sc->areq.an_type == AN_RID_ZERO_CACHE) { error = priv_check(td, PRIV_DRIVER); @@ -1945,33 +1999,32 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } else #endif if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { + AN_UNLOCK(sc); error = EINVAL; break; } AN_UNLOCK(sc); error = copyout(&sc->areq, ifr->ifr_data, sizeof(sc->areq)); - AN_LOCK(sc); break; case SIOCSAIRONET: if ((error = priv_check(td, PRIV_DRIVER))) goto out; - AN_UNLOCK(sc); - error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); AN_LOCK(sc); + error = copyin(ifr->ifr_data, &sc->areq, sizeof(sc->areq)); if (error != 0) break; an_setdef(sc, &sc->areq); + AN_UNLOCK(sc); break; case SIOCGPRIVATE_0: /* used by Cisco client utility */ if ((error = priv_check(td, PRIV_DRIVER))) goto out; - AN_UNLOCK(sc); error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); - AN_LOCK(sc); if (error) goto out; mode = l_ioctl.command; + AN_LOCK(sc); if (mode >= AIROGCAP && mode <= AIROGSTATSD32) { error = readrids(ifp, &l_ioctl); } else if (mode >= AIROPCAP && mode <= AIROPLEAPUSR) { @@ -1981,26 +2034,21 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } else { error =-1; } + AN_UNLOCK(sc); if (!error) { /* copy out the updated command info */ - AN_UNLOCK(sc); error = copyout(&l_ioctl, ifr->ifr_data, sizeof(l_ioctl)); - AN_LOCK(sc); } break; case SIOCGPRIVATE_1: /* used by Cisco client utility */ if ((error = priv_check(td, PRIV_DRIVER))) goto out; - AN_UNLOCK(sc); error = copyin(ifr->ifr_data, &l_ioctl, sizeof(l_ioctl)); - AN_LOCK(sc); if (error) goto out; l_ioctl.command = 0; error = AIROMAGIC; - AN_UNLOCK(sc); (void) copyout(&error, l_ioctl.data, sizeof(error)); - AN_LOCK(sc); error = 0; break; case SIOCG80211: @@ -2008,11 +2056,13 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) /* was that a good idea DJA we are doing a short-cut */ switch (ireq->i_type) { case IEEE80211_IOC_SSID: + AN_LOCK(sc); if (ireq->i_val == -1) { sc->areq.an_type = AN_RID_STATUS; if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } len = status->an_ssidlen; @@ -2022,6 +2072,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } max = (sc->areq.an_len - 4) @@ -2034,6 +2085,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } if (ireq->i_val > max) { error = EINVAL; + AN_UNLOCK(sc); break; } else { len = ssids->an_entry[ireq->i_val].an_len; @@ -2041,30 +2093,34 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } } else { error = EINVAL; + AN_UNLOCK(sc); break; } if (len > IEEE80211_NWID_LEN) { error = EINVAL; + AN_UNLOCK(sc); break; } + AN_UNLOCK(sc); ireq->i_len = len; bzero(tmpstr, IEEE80211_NWID_LEN); bcopy(tmpptr, tmpstr, len); - AN_UNLOCK(sc); error = copyout(tmpstr, ireq->i_data, IEEE80211_NWID_LEN); - AN_LOCK(sc); break; case IEEE80211_IOC_NUMSSIDS: + AN_LOCK(sc); sc->areq.an_len = sizeof(sc->areq); sc->areq.an_type = AN_RID_SSIDLIST; if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { + AN_UNLOCK(sc); error = EINVAL; break; } max = (sc->areq.an_len - 4) / sizeof(struct an_ltv_ssid_entry); + AN_UNLOCK(sc); if ( max > MAX_SSIDS ) { printf("To many SSIDs only using " "%d of %d\n", @@ -2074,12 +2130,15 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) ireq->i_val = max; break; case IEEE80211_IOC_WEP: + AN_LOCK(sc); sc->areq.an_type = AN_RID_ACTUALCFG; if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } + AN_UNLOCK(sc); if (config->an_authtype & AN_AUTHTYPE_PRIVACY_IN_USE) { if (config->an_authtype & AN_AUTHTYPE_ALLOW_UNENCRYPTED) @@ -2103,6 +2162,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } len = 0; if (ireq->i_val < 5) { + AN_LOCK(sc); sc->areq.an_type = AN_RID_WEP_TEMP; for (i = 0; i < 5; i++) { if (an_read_record(sc, @@ -2117,8 +2177,10 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) /* Required to get next entry */ sc->areq.an_type = AN_RID_WEP_PERM; } - if (error != 0) + AN_UNLOCK(sc); + if (error != 0) { break; + } } /* We aren't allowed to read the value of the * key from the card so we just output zeros @@ -2127,9 +2189,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) */ bzero(tmpstr, len); ireq->i_len = len; - AN_UNLOCK(sc); error = copyout(tmpstr, ireq->i_data, len); - AN_LOCK(sc); break; case IEEE80211_IOC_NUMWEPKEYS: ireq->i_val = 9; /* include home key */ @@ -2139,6 +2199,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) * For some strange reason, you have to read all * keys before you can read the txkey. */ + AN_LOCK(sc); sc->areq.an_type = AN_RID_WEP_TEMP; for (i = 0; i < 5; i++) { if (an_read_record(sc, @@ -2146,19 +2207,23 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) error = EINVAL; break; } - if (key->kindex == 0xffff) + if (key->kindex == 0xffff) { break; + } /* Required to get next entry */ sc->areq.an_type = AN_RID_WEP_PERM; } - if (error != 0) + if (error != 0) { + AN_UNLOCK(sc); break; + } sc->areq.an_type = AN_RID_WEP_PERM; key->kindex = 0xffff; if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } ireq->i_val = key->mac[0]; @@ -2172,18 +2237,23 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } if (config->an_home_product & AN_HOME_NETWORK) ireq->i_val = 4; + AN_UNLOCK(sc); break; case IEEE80211_IOC_AUTHMODE: + AN_LOCK(sc); sc->areq.an_type = AN_RID_ACTUALCFG; if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } + AN_UNLOCK(sc); if ((config->an_authtype & AN_AUTHTYPE_MASK) == AN_AUTHTYPE_NONE) { ireq->i_val = IEEE80211_AUTH_NONE; @@ -2197,53 +2267,61 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) error = EINVAL; break; case IEEE80211_IOC_STATIONNAME: + AN_LOCK(sc); sc->areq.an_type = AN_RID_ACTUALCFG; if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } + AN_UNLOCK(sc); ireq->i_len = sizeof(config->an_nodename); tmpptr = config->an_nodename; bzero(tmpstr, IEEE80211_NWID_LEN); bcopy(tmpptr, tmpstr, ireq->i_len); - AN_UNLOCK(sc); error = copyout(tmpstr, ireq->i_data, IEEE80211_NWID_LEN); - AN_LOCK(sc); break; case IEEE80211_IOC_CHANNEL: + AN_LOCK(sc); sc->areq.an_type = AN_RID_STATUS; if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } + AN_UNLOCK(sc); ireq->i_val = status->an_cur_channel; break; - case IEEE80211_IOC_CURCHAN: - sc->areq.an_type = AN_RID_STATUS; - if (an_read_record(sc, - (struct an_ltv_gen *)&sc->areq)) { + case IEEE80211_IOC_CURCHAN: + AN_LOCK(sc); + sc->areq.an_type = AN_RID_STATUS; + if (an_read_record(sc, + (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } + AN_UNLOCK(sc); bzero(&ch, sizeof(ch)); ch.ic_freq = ieee80211_ieee2mhz(status->an_cur_channel, IEEE80211_CHAN_B); ch.ic_flags = IEEE80211_CHAN_B; ch.ic_ieee = status->an_cur_channel; - AN_UNLOCK(sc); error = copyout(&ch, ireq->i_data, sizeof(ch)); - AN_LOCK(sc); break; case IEEE80211_IOC_POWERSAVE: + AN_LOCK(sc); sc->areq.an_type = AN_RID_ACTUALCFG; if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } + AN_UNLOCK(sc); if (config->an_psave_mode == AN_PSAVE_NONE) { ireq->i_val = IEEE80211_POWERSAVE_OFF; } else if (config->an_psave_mode == AN_PSAVE_CAM) { @@ -2256,12 +2334,15 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) error = EINVAL; break; case IEEE80211_IOC_POWERSAVESLEEP: + AN_LOCK(sc); sc->areq.an_type = AN_RID_ACTUALCFG; if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } + AN_UNLOCK(sc); ireq->i_val = config->an_listen_interval; break; } @@ -2269,6 +2350,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCS80211: if ((error = priv_check(td, PRIV_NET80211_MANAGE))) goto out; + AN_LOCK(sc); sc->areq.an_len = sizeof(sc->areq); /* * We need a config structure for everything but the WEP @@ -2282,6 +2364,7 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } } @@ -2292,10 +2375,12 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if (an_read_record(sc, (struct an_ltv_gen *)&sc->areq)) { error = EINVAL; + AN_UNLOCK(sc); break; } if (ireq->i_len > IEEE80211_NWID_LEN) { error = EINVAL; + AN_UNLOCK(sc); break; } max = (sc->areq.an_len - 4) @@ -2308,15 +2393,18 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } if (ireq->i_val > max) { error = EINVAL; + AN_UNLOCK(sc); break; } else { - AN_UNLOCK(sc); error = copyin(ireq->i_data, - ssids->an_entry[ireq->i_val].an_ssid, + ssids->an_entry[ireq->i_val].an_ssid, ireq->i_len); - AN_LOCK(sc); - ssids->an_entry[ireq->i_val].an_len + ssids->an_entry[ireq->i_val].an_len = ireq->i_len; + sc->areq.an_len = sizeof(sc->areq); + sc->areq.an_type = AN_RID_SSIDLIST; + an_setdef(sc, &sc->areq); + AN_UNLOCK(sc); break; } break; @@ -2342,18 +2430,22 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) error = EINVAL; break; } + if (error != EINVAL) + an_setdef(sc, &sc->areq); + AN_UNLOCK(sc); break; case IEEE80211_IOC_WEPKEY: if (ireq->i_val < 0 || ireq->i_val > 8 || ireq->i_len > 13) { error = EINVAL; + AN_UNLOCK(sc); break; } - AN_UNLOCK(sc); error = copyin(ireq->i_data, tmpstr, 13); - AN_LOCK(sc); - if (error != 0) + if (error != 0) { + AN_UNLOCK(sc); break; + } /* * Map the 9th key into the home mode * since that is how it is stored on @@ -2371,10 +2463,13 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } key->klen = ireq->i_len; bcopy(tmpstr, key->key, key->klen); + an_setdef(sc, &sc->areq); + AN_UNLOCK(sc); break; case IEEE80211_IOC_WEPTXKEY: if (ireq->i_val < 0 || ireq->i_val > 4) { error = EINVAL; + AN_UNLOCK(sc); break; } @@ -2386,10 +2481,12 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) sc->areq.an_len = sizeof(struct an_ltv_genconfig); sc->areq.an_type = AN_RID_ACTUALCFG; if (an_read_record(sc, - (struct an_ltv_gen *)&sc->areq)) { - error = EINVAL; + (struct an_ltv_gen *)&sc->areq)) { + error = EINVAL; + AN_UNLOCK(sc); break; } + AN_UNLOCK(sc); if (ireq->i_val == 4) { config->an_home_product |= AN_HOME_NETWORK; ireq->i_val = 0; @@ -2404,10 +2501,13 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) an_init(sc); bzero(&sc->areq, sizeof(struct an_ltv_key)); + AN_LOCK(sc); sc->areq.an_len = sizeof(struct an_ltv_key); sc->areq.an_type = AN_RID_WEP_PERM; key->kindex = 0xffff; key->mac[0] = ireq->i_val; + an_setdef(sc, &sc->areq); + AN_UNLOCK(sc); break; case IEEE80211_IOC_AUTHMODE: switch (ireq->i_val) { @@ -2426,17 +2526,22 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) default: error = EINVAL; } + if (error != EINVAL) { + an_setdef(sc, &sc->areq); + } + AN_UNLOCK(sc); break; case IEEE80211_IOC_STATIONNAME: if (ireq->i_len > 16) { error = EINVAL; + AN_UNLOCK(sc); break; } bzero(config->an_nodename, 16); - AN_UNLOCK(sc); error = copyin(ireq->i_data, config->an_nodename, ireq->i_len); - AN_LOCK(sc); + an_setdef(sc, &sc->areq); + AN_UNLOCK(sc); break; case IEEE80211_IOC_CHANNEL: /* @@ -2446,9 +2551,12 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) */ if (ireq->i_val < 0 || ireq->i_val >14) { error = EINVAL; + AN_UNLOCK(sc); break; } config->an_ds_channel = ireq->i_val; + an_setdef(sc, &sc->areq); + AN_UNLOCK(sc); break; case IEEE80211_IOC_POWERSAVE: switch (ireq->i_val) { @@ -2468,23 +2576,29 @@ an_ioctl(struct ifnet *ifp, u_long command, caddr_t data) error = EINVAL; break; } + an_setdef(sc, &sc->areq); + AN_UNLOCK(sc); break; case IEEE80211_IOC_POWERSAVESLEEP: config->an_listen_interval = ireq->i_val; + an_setdef(sc, &sc->areq); + AN_UNLOCK(sc); break; } - if (!error) + /* + if (!error) { + AN_LOCK(sc); an_setdef(sc, &sc->areq); + AN_UNLOCK(sc); + } + */ break; default: - AN_UNLOCK(sc); error = ether_ioctl(ifp, command, data); - AN_LOCK(sc); break; } out: - AN_UNLOCK(sc); return(error != 0); } @@ -2537,7 +2651,7 @@ an_init(void *xsc) if (an_init_tx_ring(sc)) { an_reset(sc); if (sc->mpi350) - an_init_mpi350_desc(sc); + an_init_mpi350_desc(sc); if (an_init_tx_ring(sc)) { printf("an%d: tx buffer allocation " "failed\n", sc->an_unit); @@ -2660,6 +2774,7 @@ an_start(struct ifnet *ifp) idx = sc->an_rdata.an_tx_prod; + AN_LOCK(sc); if (!sc->mpi350) { bzero((char *)&tx_frame_802_3, sizeof(tx_frame_802_3)); @@ -2672,15 +2787,15 @@ an_start(struct ifnet *ifp) eh = mtod(m0, struct ether_header *); bcopy((char *)&eh->ether_dhost, - (char *)&tx_frame_802_3.an_tx_dst_addr, + (char *)&tx_frame_802_3.an_tx_dst_addr, ETHER_ADDR_LEN); bcopy((char *)&eh->ether_shost, - (char *)&tx_frame_802_3.an_tx_src_addr, + (char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN); /* minus src/dest mac & type */ tx_frame_802_3.an_tx_802_3_payload_len = - m0->m_pkthdr.len - 12; + m0->m_pkthdr.len - 12; m_copydata(m0, sizeof(struct ether_header) - 2 , tx_frame_802_3.an_tx_802_3_payload_len, @@ -2735,15 +2850,15 @@ an_start(struct ifnet *ifp) /* DJA optimize this to limit bcopy */ bcopy((char *)&eh->ether_dhost, - (char *)&tx_frame_802_3.an_tx_dst_addr, + (char *)&tx_frame_802_3.an_tx_dst_addr, ETHER_ADDR_LEN); bcopy((char *)&eh->ether_shost, - (char *)&tx_frame_802_3.an_tx_src_addr, + (char *)&tx_frame_802_3.an_tx_src_addr, ETHER_ADDR_LEN); /* minus src/dest mac & type */ tx_frame_802_3.an_tx_802_3_payload_len = - m0->m_pkthdr.len - 12; + m0->m_pkthdr.len - 12; m_copydata(m0, sizeof(struct ether_header) - 2 , tx_frame_802_3.an_tx_802_3_payload_len, @@ -2769,11 +2884,11 @@ an_start(struct ifnet *ifp) an_tx_desc.an_valid = 1; an_tx_desc.an_len = 0x44 + tx_frame_802_3.an_tx_802_3_payload_len; - an_tx_desc.an_phys + an_tx_desc.an_phys = sc->an_tx_buffer[idx].an_dma_paddr; for (i = 0; i < sizeof(an_tx_desc) / 4 ; i++) { CSR_MEM_AUX_WRITE_4(sc, AN_TX_DESC_OFFSET - /* zero for now */ + /* zero for now */ + (0 * sizeof(an_tx_desc)) + (i * 4), ((u_int32_t *)(void *)&an_tx_desc)[i]); @@ -2800,6 +2915,7 @@ an_start(struct ifnet *ifp) /* Re-enable interrupts. */ CSR_WRITE_2(sc, AN_INT_EN(sc->mpi350), AN_INTRS(sc->mpi350)); } + AN_UNLOCK(sc); if (m0 != NULL) ifp->if_drv_flags |= IFF_DRV_OACTIVE; @@ -2862,11 +2978,11 @@ an_watchdog(struct ifnet *ifp) an_reset(sc); if (sc->mpi350) - an_init_mpi350_desc(sc); + an_init_mpi350_desc(sc); + AN_UNLOCK(sc); an_init(sc); ifp->if_oerrors++; - AN_UNLOCK(sc); return; } @@ -2897,13 +3013,13 @@ an_resume(device_t dev) sc->an_gone = 0; an_reset(sc); if (sc->mpi350) - an_init_mpi350_desc(sc); + an_init_mpi350_desc(sc); an_init(sc); /* Recovery temporary keys */ for (i = 0; i < 4; i++) { sc->areq.an_type = AN_RID_WEP_TEMP; - sc->areq.an_len = sizeof(struct an_ltv_key); + sc->areq.an_len = sizeof(struct an_ltv_key); bcopy(&sc->an_temp_keys[i], &sc->areq, sizeof(struct an_ltv_key)); an_setdef(sc, &sc->areq); @@ -3091,9 +3207,9 @@ an_cache_store(struct an_softc *sc, struct ether_header *eh, struct mbuf *m, switch (an_cache_mode) { case DBM: if (sc->an_have_rssimap) { - sc->an_sigcache[cache_slot].signal = + sc->an_sigcache[cache_slot].signal = - sc->an_rssimap.an_entries[rx_rssi].an_rss_dbm; - sc->an_sigcache[cache_slot].quality = + sc->an_sigcache[cache_slot].quality = - sc->an_rssimap.an_entries[rx_quality].an_rss_dbm; } else { sc->an_sigcache[cache_slot].signal = rx_rssi - 100; @@ -3102,9 +3218,9 @@ an_cache_store(struct an_softc *sc, struct ether_header *eh, struct mbuf *m, break; case PERCENT: if (sc->an_have_rssimap) { - sc->an_sigcache[cache_slot].signal = + sc->an_sigcache[cache_slot].signal = sc->an_rssimap.an_entries[rx_rssi].an_rss_pct; - sc->an_sigcache[cache_slot].quality = + sc->an_sigcache[cache_slot].quality = sc->an_rssimap.an_entries[rx_quality].an_rss_pct; } else { if (rx_rssi > 100) @@ -3140,6 +3256,7 @@ an_media_change(struct ifnet *ifp) if (sc->an_tx_rate < 0) sc->an_tx_rate = 0; + AN_LOCK(sc); if (orate != sc->an_tx_rate) { /* Read the current configuration */ sc->an_config.an_type = AN_RID_GENCONFIG; @@ -3160,8 +3277,9 @@ an_media_change(struct ifnet *ifp) sc->an_config.an_opmode &= ~AN_OPMODE_INFRASTRUCTURE_STATION; else sc->an_config.an_opmode |= AN_OPMODE_INFRASTRUCTURE_STATION; + AN_UNLOCK(sc); - if (otype != sc->an_config.an_opmode || + if (otype != sc->an_config.an_opmode || orate != sc->an_tx_rate) an_init(sc); @@ -3176,6 +3294,7 @@ an_media_status(struct ifnet *ifp, struct ifmediareq *imr) imr->ifm_active = IFM_IEEE80211; + AN_LOCK(sc); status.an_len = sizeof(status); status.an_type = AN_RID_STATUS; if (an_read_record(sc, (struct an_ltv_gen *)&status)) { @@ -3183,6 +3302,7 @@ an_media_status(struct ifnet *ifp, struct ifmediareq *imr) imr->ifm_active = sc->an_ifmedia.ifm_cur->ifm_media; imr->ifm_status = IFM_AVALID|IFM_ACTIVE; } + AN_UNLOCK(sc); if (sc->an_tx_rate == 0) { imr->ifm_active = IFM_IEEE80211|IFM_AUTO; @@ -3287,6 +3407,7 @@ writerids(struct ifnet *ifp, struct aironet_ioctl *l_ioctl) int rid, command, error; sc = ifp->if_softc; + AN_LOCK_ASSERT(sc); rid = 0; command = l_ioctl->command; @@ -3396,7 +3517,7 @@ unstickbusy(struct ifnet *ifp) struct an_softc *sc = ifp->if_softc; if (CSR_READ_2(sc, AN_COMMAND(sc->mpi350)) & AN_CMD_BUSY) { - CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), + CSR_WRITE_2(sc, AN_EVENT_ACK(sc->mpi350), AN_EV_CLR_STUCK_BUSY); return 1; } @@ -3440,11 +3561,13 @@ cmdreset(struct ifnet *ifp) an_stop(sc); + AN_LOCK(sc); an_cmd(sc, AN_CMD_DISABLE, 0); if (!(status = WaitBusy(ifp, AN_TIMEOUT))) { printf("an%d: Waitbusy hang b4 RESET =%d\n", sc->an_unit, status); + AN_UNLOCK(sc); return -EBUSY; } CSR_WRITE_2(sc, AN_COMMAND(sc->mpi350), AN_CMD_FW_RESTART); @@ -3455,8 +3578,10 @@ cmdreset(struct ifnet *ifp) if (!(status = WaitBusy(ifp, 100))) { printf("an%d: Waitbusy hang AFTER RESET =%d\n", sc->an_unit, status); + AN_UNLOCK(sc); return -EBUSY; } + AN_UNLOCK(sc); return 0; } @@ -3605,7 +3730,7 @@ flashputbuf(struct ifnet *ifp) } } else { for (nwords = 0; nwords != FLASH_SIZE / 4; nwords++) { - CSR_MEM_AUX_WRITE_4(sc, 0x8000, + CSR_MEM_AUX_WRITE_4(sc, 0x8000, ((u_int32_t *)bufp)[nwords] & 0xffff); } } @@ -3627,7 +3752,9 @@ flashrestart(struct ifnet *ifp) FLASH_DELAY(sc, 1024); /* Added 12/7/00 */ + AN_UNLOCK(sc); an_init(sc); + AN_LOCK(sc); FLASH_DELAY(sc, 1024); /* Added 12/7/00 */ return status; @@ -3645,7 +3772,7 @@ flashcard(struct ifnet *ifp, struct aironet_ioctl *l_ioctl) sc = ifp->if_softc; if (sc->mpi350) { - printf("an%d: flashing not supported on MPI 350 yet\n", + printf("an%d: flashing not supported on MPI 350 yet\n", sc->an_unit); return(-1); } diff --git a/sys/dev/an/if_an_pci.c b/sys/dev/an/if_an_pci.c index a284c8a..d13b147 100644 --- a/sys/dev/an/if_an_pci.c +++ b/sys/dev/an/if_an_pci.c @@ -118,13 +118,16 @@ static int an_probe_pci(device_t dev) { struct an_type *t; + struct an_softc *sc = device_get_softc(dev); + bzero(sc, sizeof(struct an_softc)); t = an_devs; while (t->an_name != NULL) { if (pci_get_vendor(dev) == t->an_vid && pci_get_device(dev) == t->an_did) { device_set_desc(dev, t->an_name); + an_pci_probe(dev); return(BUS_PROBE_DEFAULT); } t++; @@ -133,6 +136,7 @@ an_probe_pci(device_t dev) if (pci_get_vendor(dev) == AIRONET_VENDORID && pci_get_device(dev) == AIRONET_DEVICEID_MPI350) { device_set_desc(dev, "Cisco Aironet MPI350"); + an_pci_probe(dev); return(BUS_PROBE_DEFAULT); } @@ -150,7 +154,6 @@ an_attach_pci(dev) sc = device_get_softc(dev); unit = device_get_unit(dev); flags = device_get_flags(dev); - bzero(sc, sizeof(struct an_softc)); if (pci_get_vendor(dev) == AIRONET_VENDORID && pci_get_device(dev) == AIRONET_DEVICEID_MPI350) { diff --git a/sys/dev/an/if_anreg.h b/sys/dev/an/if_anreg.h index 0a96ee3..fb2d6a7 100644 --- a/sys/dev/an/if_anreg.h +++ b/sys/dev/an/if_anreg.h @@ -509,6 +509,7 @@ int an_alloc_port (device_t, int, int); int an_alloc_memory (device_t, int, int); int an_alloc_aux_memory (device_t, int, int); int an_alloc_irq (device_t, int, int); +int an_pci_probe (device_t); int an_probe (device_t); void an_shutdown (device_t); void an_resume (device_t); |