static void lmc_ds3_watchdog (lmc_softc_t * const sc) { sc->lmc_miireg16 = lmc_mii_readreg (sc, 0, 16); if (sc->lmc_miireg16 & 0x0018) { printf("%s: AIS Received\n", sc->lmc_xname); lmc_led_on (sc, LMC_DS3_LED1 | LMC_DS3_LED2); } }
static void lmc_shutdown(void *arg) { lmc_softc_t * const sc = arg; LMC_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET); DELAY(10); sc->lmc_miireg16 = 0; /* deassert ready, and all others too */ lmc_led_on(sc, LMC_MII16_LED_ALL); }
static void lmc_t1_watchdog(lmc_softc_t * const sc) { int t1stat; /* read alarm 1 status (receive) */ t1stat = lmc_t1_read (sc, 0x47); /* blue alarm -- RAIS */ if (t1stat & 0x08) { if (sc->lmc_blue != 1) printf ("%s: AIS Received\n", sc->lmc_xname); lmc_led_on (sc, LMC_DS3_LED1 | LMC_DS3_LED2); sc->lmc_blue = 1; } else { if (sc->lmc_blue == 1) printf ("%s: AIS ok\n", sc->lmc_xname); lmc_led_off (sc, LMC_DS3_LED1); lmc_led_on (sc, LMC_DS3_LED2); sc->lmc_blue = 0; } /* Red alarm -- LOS | LOF */ if (t1stat & 0x04) { /* Only print the error once */ if (sc->lmc_red != 1) printf ("%s: Red Alarm\n", sc->lmc_xname); lmc_led_on (sc, LMC_DS3_LED2 | LMC_DS3_LED3); sc->lmc_red = 1; } else { if (sc->lmc_red == 1) printf ("%s: Red Alarm ok\n", sc->lmc_xname); lmc_led_off (sc, LMC_DS3_LED3); lmc_led_on (sc, LMC_DS3_LED2); sc->lmc_red = 0; } /* check for Receive Multiframe Yellow Alarm * Ignore Receive Yellow Alarm */ if (t1stat & 0x80) { if (sc->lmc_yel != 1) { printf ("%s: Receive Yellow Alarm\n", sc->lmc_xname); } lmc_led_on (sc, LMC_DS3_LED0 | LMC_DS3_LED2); sc->lmc_yel = 1; } else { if (sc->lmc_yel == 1) printf ("%s: Yellow Alarm ok\n", sc->lmc_xname); lmc_led_off (sc, LMC_DS3_LED0); lmc_led_on (sc, LMC_DS3_LED2); sc->lmc_yel = 0; } }
static void lmc_ssi_watchdog (lmc_softc_t * const sc) { u_int16_t mii17; struct ssicsr2 { unsigned short dtr:1, dsr:1, rts:1, cable:3, crc:1, led0:1, led1:1, led2:1, led3:1, fifo:1, ll:1, rl:1, tm:1, loop:1; }; struct ssicsr2 *ssicsr; mii17 = lmc_mii_readreg (sc, 0, 17); ssicsr = (struct ssicsr2 *) &mii17; if (ssicsr->cable == 7) { lmc_led_off (sc, LMC_MII16_LED2); } else { lmc_led_on (sc, LMC_MII16_LED2); } }
int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { lmc_softc_t *sc = dev_to_sc(dev); lmc_ctl_t ctl; int ret = -EOPNOTSUPP; u16 regVal; unsigned long flags; lmc_trace(dev, "lmc_ioctl in"); switch (cmd) { case LMCIOCGINFO: if (copy_to_user(ifr->ifr_data, &sc->ictl, sizeof(lmc_ctl_t))) ret = -EFAULT; else ret = 0; break; case LMCIOCSINFO: if (!capable(CAP_NET_ADMIN)) { ret = -EPERM; break; } if(dev->flags & IFF_UP){ ret = -EBUSY; break; } if (copy_from_user(&ctl, ifr->ifr_data, sizeof(lmc_ctl_t))) { ret = -EFAULT; break; } spin_lock_irqsave(&sc->lmc_lock, flags); sc->lmc_media->set_status (sc, &ctl); if(ctl.crc_length != sc->ictl.crc_length) { sc->lmc_media->set_crc_length(sc, ctl.crc_length); if (sc->ictl.crc_length == LMC_CTL_CRC_LENGTH_16) sc->TxDescriptControlInit |= LMC_TDES_ADD_CRC_DISABLE; else sc->TxDescriptControlInit &= ~LMC_TDES_ADD_CRC_DISABLE; } spin_unlock_irqrestore(&sc->lmc_lock, flags); ret = 0; break; case LMCIOCIFTYPE: { u16 old_type = sc->if_type; u16 new_type; if (!capable(CAP_NET_ADMIN)) { ret = -EPERM; break; } if (copy_from_user(&new_type, ifr->ifr_data, sizeof(u16))) { ret = -EFAULT; break; } if (new_type == old_type) { ret = 0 ; break; } spin_lock_irqsave(&sc->lmc_lock, flags); lmc_proto_close(sc); sc->if_type = new_type; lmc_proto_attach(sc); ret = lmc_proto_open(sc); spin_unlock_irqrestore(&sc->lmc_lock, flags); break; } case LMCIOCGETXINFO: spin_lock_irqsave(&sc->lmc_lock, flags); sc->lmc_xinfo.Magic0 = 0xBEEFCAFE; sc->lmc_xinfo.PciCardType = sc->lmc_cardtype; sc->lmc_xinfo.PciSlotNumber = 0; sc->lmc_xinfo.DriverMajorVersion = DRIVER_MAJOR_VERSION; sc->lmc_xinfo.DriverMinorVersion = DRIVER_MINOR_VERSION; sc->lmc_xinfo.DriverSubVersion = DRIVER_SUB_VERSION; sc->lmc_xinfo.XilinxRevisionNumber = lmc_mii_readreg (sc, 0, 3) & 0xf; sc->lmc_xinfo.MaxFrameSize = LMC_PKT_BUF_SZ; sc->lmc_xinfo.link_status = sc->lmc_media->get_link_status (sc); sc->lmc_xinfo.mii_reg16 = lmc_mii_readreg (sc, 0, 16); spin_unlock_irqrestore(&sc->lmc_lock, flags); sc->lmc_xinfo.Magic1 = 0xDEADBEEF; if (copy_to_user(ifr->ifr_data, &sc->lmc_xinfo, sizeof(struct lmc_xinfo))) ret = -EFAULT; else ret = 0; break; case LMCIOCGETLMCSTATS: spin_lock_irqsave(&sc->lmc_lock, flags); if (sc->lmc_cardtype == LMC_CARDTYPE_T1) { lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_LSB); sc->extra_stats.framingBitErrorCount += lmc_mii_readreg(sc, 0, 18) & 0xff; lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_MSB); sc->extra_stats.framingBitErrorCount += (lmc_mii_readreg(sc, 0, 18) & 0xff) << 8; lmc_mii_writereg(sc, 0, 17, T1FRAMER_LCV_LSB); sc->extra_stats.lineCodeViolationCount += lmc_mii_readreg(sc, 0, 18) & 0xff; lmc_mii_writereg(sc, 0, 17, T1FRAMER_LCV_MSB); sc->extra_stats.lineCodeViolationCount += (lmc_mii_readreg(sc, 0, 18) & 0xff) << 8; lmc_mii_writereg(sc, 0, 17, T1FRAMER_AERR); regVal = lmc_mii_readreg(sc, 0, 18) & 0xff; sc->extra_stats.lossOfFrameCount += (regVal & T1FRAMER_LOF_MASK) >> 4; sc->extra_stats.changeOfFrameAlignmentCount += (regVal & T1FRAMER_COFA_MASK) >> 2; sc->extra_stats.severelyErroredFrameCount += regVal & T1FRAMER_SEF_MASK; } spin_unlock_irqrestore(&sc->lmc_lock, flags); if (copy_to_user(ifr->ifr_data, &sc->lmc_device->stats, sizeof(sc->lmc_device->stats)) || copy_to_user(ifr->ifr_data + sizeof(sc->lmc_device->stats), &sc->extra_stats, sizeof(sc->extra_stats))) ret = -EFAULT; else ret = 0; break; case LMCIOCCLEARLMCSTATS: if (!capable(CAP_NET_ADMIN)) { ret = -EPERM; break; } spin_lock_irqsave(&sc->lmc_lock, flags); memset(&sc->lmc_device->stats, 0, sizeof(sc->lmc_device->stats)); memset(&sc->extra_stats, 0, sizeof(sc->extra_stats)); sc->extra_stats.check = STATCHECK; sc->extra_stats.version_size = (DRIVER_VERSION << 16) + sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats); sc->extra_stats.lmc_cardtype = sc->lmc_cardtype; spin_unlock_irqrestore(&sc->lmc_lock, flags); ret = 0; break; case LMCIOCSETCIRCUIT: if (!capable(CAP_NET_ADMIN)){ ret = -EPERM; break; } if(dev->flags & IFF_UP){ ret = -EBUSY; break; } if (copy_from_user(&ctl, ifr->ifr_data, sizeof(lmc_ctl_t))) { ret = -EFAULT; break; } spin_lock_irqsave(&sc->lmc_lock, flags); sc->lmc_media->set_circuit_type(sc, ctl.circuit_type); sc->ictl.circuit_type = ctl.circuit_type; spin_unlock_irqrestore(&sc->lmc_lock, flags); ret = 0; break; case LMCIOCRESET: if (!capable(CAP_NET_ADMIN)){ ret = -EPERM; break; } spin_lock_irqsave(&sc->lmc_lock, flags); printk (" REG16 before reset +%04x\n", lmc_mii_readreg (sc, 0, 16)); lmc_running_reset (dev); printk (" REG16 after reset +%04x\n", lmc_mii_readreg (sc, 0, 16)); LMC_EVENT_LOG(LMC_EVENT_FORCEDRESET, LMC_CSR_READ (sc, csr_status), lmc_mii_readreg (sc, 0, 16)); spin_unlock_irqrestore(&sc->lmc_lock, flags); ret = 0; break; #ifdef DEBUG case LMCIOCDUMPEVENTLOG: if (copy_to_user(ifr->ifr_data, &lmcEventLogIndex, sizeof(u32))) { ret = -EFAULT; break; } if (copy_to_user(ifr->ifr_data + sizeof(u32), lmcEventLogBuf, sizeof(lmcEventLogBuf))) ret = -EFAULT; else ret = 0; break; #endif case LMCIOCT1CONTROL: if (sc->lmc_cardtype != LMC_CARDTYPE_T1){ ret = -EOPNOTSUPP; break; } break; case LMCIOCXILINX: { struct lmc_xilinx_control xc; if (!capable(CAP_NET_ADMIN)){ ret = -EPERM; break; } netif_stop_queue(dev); if (copy_from_user(&xc, ifr->ifr_data, sizeof(struct lmc_xilinx_control))) { ret = -EFAULT; break; } switch(xc.command){ case lmc_xilinx_reset: { u16 mii; spin_lock_irqsave(&sc->lmc_lock, flags); mii = lmc_mii_readreg (sc, 0, 16); lmc_gpio_mkinput(sc, 0xff); lmc_gpio_mkoutput(sc, LMC_GEP_RESET); sc->lmc_gpio &= ~LMC_GEP_RESET; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); udelay(50); sc->lmc_gpio |= LMC_GEP_RESET; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); lmc_gpio_mkinput(sc, 0xff); sc->lmc_media->set_link_status (sc, 1); sc->lmc_media->set_status (sc, NULL); { int i; for(i = 0; i < 5; i++){ lmc_led_on(sc, LMC_DS3_LED0); mdelay(100); lmc_led_off(sc, LMC_DS3_LED0); lmc_led_on(sc, LMC_DS3_LED1); mdelay(100); lmc_led_off(sc, LMC_DS3_LED1); lmc_led_on(sc, LMC_DS3_LED3); mdelay(100); lmc_led_off(sc, LMC_DS3_LED3); lmc_led_on(sc, LMC_DS3_LED2); mdelay(100); lmc_led_off(sc, LMC_DS3_LED2); } } spin_unlock_irqrestore(&sc->lmc_lock, flags); ret = 0x0; } break; case lmc_xilinx_load_prom: { u16 mii; int timeout = 500000; spin_lock_irqsave(&sc->lmc_lock, flags); mii = lmc_mii_readreg (sc, 0, 16); lmc_gpio_mkinput(sc, 0xff); lmc_gpio_mkoutput(sc, LMC_GEP_DP | LMC_GEP_RESET); sc->lmc_gpio &= ~(LMC_GEP_RESET | LMC_GEP_DP); LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); udelay(50); sc->lmc_gpio |= LMC_GEP_DP | LMC_GEP_RESET; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 && (timeout-- > 0)) cpu_relax(); lmc_gpio_mkinput(sc, 0xff); spin_unlock_irqrestore(&sc->lmc_lock, flags); ret = 0x0; break; } case lmc_xilinx_load: { char *data; int pos; int timeout = 500000; if (!xc.data) { ret = -EINVAL; break; } data = kmalloc(xc.len, GFP_KERNEL); if (!data) { ret = -ENOMEM; break; } if(copy_from_user(data, xc.data, xc.len)) { kfree(data); ret = -ENOMEM; break; } printk("%s: Starting load of data Len: %d at 0x%p == 0x%p\n", dev->name, xc.len, xc.data, data); spin_lock_irqsave(&sc->lmc_lock, flags); lmc_gpio_mkinput(sc, 0xff); sc->lmc_gpio = 0x00; sc->lmc_gpio &= ~LMC_GEP_DP; sc->lmc_gpio &= ~LMC_GEP_RESET; sc->lmc_gpio |= LMC_GEP_MODE; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); lmc_gpio_mkoutput(sc, LMC_GEP_MODE | LMC_GEP_DP | LMC_GEP_RESET); udelay(50); lmc_gpio_mkinput(sc, LMC_GEP_DP | LMC_GEP_RESET); sc->lmc_gpio = 0x00; sc->lmc_gpio |= LMC_GEP_MODE; sc->lmc_gpio |= LMC_GEP_DATA; sc->lmc_gpio |= LMC_GEP_CLK; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); lmc_gpio_mkoutput(sc, LMC_GEP_DATA | LMC_GEP_CLK | LMC_GEP_MODE ); while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 && (timeout-- > 0)) cpu_relax(); printk(KERN_DEBUG "%s: Waited %d for the Xilinx to clear it's memory\n", dev->name, 500000-timeout); for(pos = 0; pos < xc.len; pos++){ switch(data[pos]){ case 0: sc->lmc_gpio &= ~LMC_GEP_DATA; break; case 1: sc->lmc_gpio |= LMC_GEP_DATA; break; default: printk(KERN_WARNING "%s Bad data in xilinx programming data at %d, got %d wanted 0 or 1\n", dev->name, pos, data[pos]); sc->lmc_gpio |= LMC_GEP_DATA; } sc->lmc_gpio &= ~LMC_GEP_CLK; sc->lmc_gpio |= LMC_GEP_MODE; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); udelay(1); sc->lmc_gpio |= LMC_GEP_CLK; sc->lmc_gpio |= LMC_GEP_MODE; LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio); udelay(1); } if((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0){ printk(KERN_WARNING "%s: Reprogramming FAILED. Needs to be reprogrammed. (corrupted data)\n", dev->name); } else if((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_DP) == 0){ printk(KERN_WARNING "%s: Reprogramming FAILED. Needs to be reprogrammed. (done)\n", dev->name); } else { printk(KERN_DEBUG "%s: Done reprogramming Xilinx, %d bits, good luck!\n", dev->name, pos); } lmc_gpio_mkinput(sc, 0xff); sc->lmc_miireg16 |= LMC_MII16_FIFO_RESET; lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16); sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET; lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16); spin_unlock_irqrestore(&sc->lmc_lock, flags); kfree(data); ret = 0; break; } default: ret = -EBADE; break; } netif_wake_queue(dev); sc->lmc_txfull = 0; } break; default: ret = lmc_proto_ioctl (sc, ifr, cmd); break; }
static int lmc_t1_get_link_status(lmc_softc_t * const sc){ u_int16_t link_status; lmc_mii_writereg(sc, 0, 17, T1FRAMER_ALARM1_STATUS ); link_status = lmc_mii_readreg(sc, 0, 18); /* * LMC 1200 LED definitions * led0 yellow = far-end adapter is in Red alarm condition * led1 blue = received an Alarm Indication signal (upstream failure) * led2 Green = power to adapter, Gate Array loaded & driver attached * led3 red = Loss of Signal (LOS) or out of frame (OOF) conditions * detected on T3 receive signal */ /* detect a change in Blue alarm indication signal */ if( (sc->t1_alarm1_status & T1F_RAIS) != (link_status & T1F_RAIS) ) { if( link_status & T1F_RAIS ) { /* turn on blue LED */ printf("%s: link status: RAIS turn ON Blue %x\n", sc->lmc_xname, link_status); /* DEBUG */ lmc_led_on(sc, LMC_DS3_LED1); } else { /* turn off blue LED */ printf("%s: link status: RAIS turn OFF Blue %x\n", sc->lmc_xname, link_status ); /* DEBUG */ lmc_led_off(sc, LMC_DS3_LED1); } } /* * T1F_RYEL wiggles quite a bit, * taking it out until I understand why -baz 6/22/99 */ /* Yellow alarm indication */ if( (sc->t1_alarm1_status & T1F_RMYEL) != (link_status & T1F_RMYEL) ) { if( (link_status & (T1F_RYEL | T1F_RMYEL)) == 0 ) { /* turn off yellow LED */ printf("%s: link status: RYEL turn OFF Yellow %x\n", sc->lmc_xname, link_status); /* DEBUG */ lmc_led_off(sc, LMC_DS3_LED0); } else { /* turn on yellow LED */ printf("%s: link status: RYEL turn ON Yellow %x\n", sc->lmc_xname, link_status); /* DEBUG */ lmc_led_on(sc, LMC_DS3_LED0); } } sc->t1_alarm1_status = link_status; lmc_mii_writereg(sc, 0, 17, T1FRAMER_ALARM2_STATUS ); sc->t1_alarm2_status = lmc_mii_readreg(sc, 0, 18); /* link status based upon T1 receive loss of frame or * loss of signal - RED alarm indication */ if ((link_status & (T1F_RLOF | T1F_RLOS)) == 0) return 1; else return 0; }
void lmc_dec_reset(lmc_softc_t * const sc) { #ifndef __linux__ lmc_ringinfo_t *ri; lmc_desc_t *di; #endif u_int32_t val; /* * disable all interrupts */ sc->lmc_intrmask = 0; LMC_CSR_WRITE(sc, csr_intr, sc->lmc_intrmask); /* * we are, obviously, down. */ #ifndef __linux__ sc->lmc_flags &= ~(LMC_IFUP | LMC_MODEMOK); DP(("lmc_dec_reset\n")); #endif /* * Reset the chip with a software reset command. * Wait 10 microseconds (actually 50 PCI cycles but at * 33MHz that comes to two microseconds but wait a * bit longer anyways) */ LMC_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET); DELAY(10); sc->lmc_cmdmode = LMC_CSR_READ(sc, csr_command); /* * We want: * no ethernet address in frames we write * disable padding (txdesc, padding disable) * ignore runt frames (rdes0 bit 15) * no receiver watchdog or transmitter jabber timer * (csr15 bit 0,14 == 1) * if using 16-bit CRC, turn off CRC (trans desc, crc disable) */ #ifndef TULIP_CMD_RECEIVEALL #define TULIP_CMD_RECEIVEALL 0x40000000L #endif sc->lmc_cmdmode |= ( TULIP_CMD_PROMISCUOUS | TULIP_CMD_FULLDUPLEX | TULIP_CMD_PASSBADPKT | TULIP_CMD_NOHEARTBEAT | TULIP_CMD_PORTSELECT | TULIP_CMD_RECEIVEALL | TULIP_CMD_MUSTBEONE ); sc->lmc_cmdmode &= ~( TULIP_CMD_OPERMODE | TULIP_CMD_THRESHOLDCTL | TULIP_CMD_STOREFWD | TULIP_CMD_TXTHRSHLDCTL ); LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode); /* * disable receiver watchdog and transmit jabber */ val = LMC_CSR_READ(sc, csr_sia_general); val |= (TULIP_WATCHDOG_TXDISABLE | TULIP_WATCHDOG_RXDISABLE); LMC_CSR_WRITE(sc, csr_sia_general, val); /* * turn off those LEDs... */ sc->lmc_miireg16 |= LMC_MII16_LED_ALL; lmc_led_on(sc, LMC_MII16_LED0); #ifndef __linux__ /* * reprogram the tx desc, rx desc, and PCI bus options */ LMC_CSR_WRITE(sc, csr_txlist, sc->lmc_txdescmap->dm_segs[0].ds_addr); LMC_CSR_WRITE(sc, csr_rxlist, sc->lmc_rxdescmap->dm_segs[0].ds_addr); LMC_CSR_WRITE(sc, csr_busmode, (1 << (LMC_BURSTSIZE(sc->lmc_unit) + 8)) |TULIP_BUSMODE_CACHE_ALIGN8 |TULIP_BUSMODE_READMULTIPLE); sc->lmc_txq.ifq_maxlen = LMC_TXDESCS; /* * Free all the mbufs that were on the transmit ring. */ for (;;) { bus_dmamap_t map; struct mbuf *m; IF_DEQUEUE(&sc->lmc_txq, m); if (m == NULL) break; map = LMC_GETCTX(m, bus_dmamap_t); bus_dmamap_unload(sc->lmc_dmatag, map); sc->lmc_txmaps[sc->lmc_txmaps_free++] = map; m_freem(m); } /* * reset descriptor state and reclaim all descriptors. */ ri = &sc->lmc_txinfo; ri->ri_nextin = ri->ri_nextout = ri->ri_first; ri->ri_free = ri->ri_max; for (di = ri->ri_first; di < ri->ri_last; di++) di->d_status = 0; bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_txdescmap, 0, sc->lmc_txdescmap->dm_mapsize, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); /* * We need to collect all the mbufs were on the * receive ring before we reinit it either to put * them back on or to know if we have to allocate * more. */ ri = &sc->lmc_rxinfo; ri->ri_nextin = ri->ri_nextout = ri->ri_first; ri->ri_free = ri->ri_max; for (di = ri->ri_first; di < ri->ri_last; di++) { u_int32_t ctl = di->d_ctl; di->d_status = 0; di->d_ctl = LMC_CTL(LMC_CTL_FLGS(ctl),0,0); di->d_addr1 = 0; di->d_addr2 = 0; } bus_dmamap_sync(sc->lmc_dmatag, sc->lmc_rxdescmap, 0, sc->lmc_rxdescmap->dm_mapsize, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); for (;;) { bus_dmamap_t map; struct mbuf *m; IF_DEQUEUE(&sc->lmc_rxq, m); if (m == NULL) break; map = LMC_GETCTX(m, bus_dmamap_t); bus_dmamap_unload(sc->lmc_dmatag, map); sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map; m_freem(m); } #endif }