int rdopen(dev_t dev, int flag, int fmt, struct proc *p) { struct rd_softc *sc; u_int unit, part; int error; unit = DISKUNIT(dev); part = DISKPART(dev); sc = rdlookup(unit); if (sc == NULL) return (ENXIO); if ((error = disk_lock(&sc->sc_dk)) != 0) goto unref; if (sc->sc_dk.dk_openmask == 0) { /* Load the partition info if not already loaded. */ if ((error = rdgetdisklabel(dev, sc, sc->sc_dk.dk_label, 0)) != 0) goto unlock; } error = disk_openpart(&sc->sc_dk, part, fmt, 1); unlock: disk_unlock(&sc->sc_dk); unref: device_unref(&sc->sc_dev); return (error); }
int rdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) { struct rd_softc *sc; struct disklabel *lp; int error = 0; sc = rdlookup(DISKUNIT(dev)); if (sc == NULL) return (ENXIO); switch (cmd) { case DIOCRLDINFO: lp = malloc(sizeof(*lp), M_TEMP, M_WAITOK); rdgetdisklabel(dev, sc, lp, 0); bcopy(lp, sc->sc_dk.dk_label, sizeof(*lp)); free(lp, M_TEMP); goto done; case DIOCGPDINFO: rdgetdisklabel(dev, sc, (struct disklabel *)data, 1); goto done; case DIOCGDINFO: *(struct disklabel *)data = *(sc->sc_dk.dk_label); goto done; case DIOCGPART: ((struct partinfo *)data)->disklab = sc->sc_dk.dk_label; ((struct partinfo *)data)->part = &sc->sc_dk.dk_label->d_partitions[DISKPART(dev)]; goto done; case DIOCWDINFO: case DIOCSDINFO: if ((fflag & FWRITE) == 0) { error = EBADF; goto done; } if ((error = disk_lock(&sc->sc_dk)) != 0) goto done; error = setdisklabel(sc->sc_dk.dk_label, (struct disklabel *)data, sc->sc_dk.dk_openmask); if (error == 0) { if (cmd == DIOCWDINFO) error = writedisklabel(DISKLABELDEV(dev), rdstrategy, sc->sc_dk.dk_label); } disk_unlock(&sc->sc_dk); goto done; } done: device_unref(&sc->sc_dev); return (error); }
void rdstrategy(struct buf *bp) { struct rd_softc *sc; struct partition *p; size_t off, xfer; caddr_t addr; int s; sc = rdlookup(DISKUNIT(bp->b_dev)); if (sc == NULL) { bp->b_error = ENXIO; goto bad; } /* Validate the request. */ if (bounds_check_with_label(bp, sc->sc_dk.dk_label) == -1) goto done; /* Do the transfer. */ /* XXX: Worry about overflow when computing off? */ p = &sc->sc_dk.dk_label->d_partitions[DISKPART(bp->b_dev)]; off = DL_GETPOFFSET(p) * sc->sc_dk.dk_label->d_secsize + (u_int64_t)bp->b_blkno * DEV_BSIZE; if (off > rd_root_size) off = rd_root_size; xfer = bp->b_bcount; if (xfer > rd_root_size - off) xfer = rd_root_size - off; addr = rd_root_image + off; if (bp->b_flags & B_READ) memcpy(bp->b_data, addr, xfer); else memcpy(addr, bp->b_data, xfer); bp->b_resid = bp->b_bcount - xfer; goto done; bad: bp->b_flags |= B_ERROR; bp->b_resid = bp->b_bcount; done: s = splbio(); biodone(bp); splx(s); if (sc != NULL) device_unref(&sc->sc_dev); }
int rdclose(dev_t dev, int flag, int fmt, struct proc *p) { struct rd_softc *sc; u_int unit, part; unit = DISKUNIT(dev); part = DISKPART(dev); sc = rdlookup(unit); if (sc == NULL) return (ENXIO); disk_lock_nointr(&sc->sc_dk); disk_closepart(&sc->sc_dk, part, fmt); disk_unlock(&sc->sc_dk); device_unref(&sc->sc_dev); return (0); }
int main(int argc, char *argv[]) { static const u_int16_t tpcScaleReductionTable[5] = { 0, 3, 6, 9, MAX_RATE_POWER }; struct ath_hal_private ahp; struct ieee80211_channel achans[IEEE80211_CHAN_MAX]; int16_t atxpow[IEEE80211_CHAN_MAX]; struct ieee80211_channel bchans[IEEE80211_CHAN_MAX]; int16_t btxpow[IEEE80211_CHAN_MAX]; struct ieee80211_channel gchans[IEEE80211_CHAN_MAX]; int16_t gtxpow[IEEE80211_CHAN_MAX]; struct ieee80211_channel tchans[IEEE80211_CHAN_MAX]; int16_t ttxpow[IEEE80211_CHAN_MAX]; struct ieee80211_channel tgchans[IEEE80211_CHAN_MAX]; int16_t tgtxpow[IEEE80211_CHAN_MAX]; struct ieee80211_channel nchans[IEEE80211_CHAN_MAX]; int16_t ntxpow[IEEE80211_CHAN_MAX]; int i, na, nb, ng, nt, ntg, nn; HAL_BOOL showall = AH_FALSE; HAL_BOOL extendedChanMode = AH_TRUE; int modes = 0; int16_t tpcReduction, powerLimit; int showdfs = 0; int show4ms = 0; memset(&ahp, 0, sizeof(ahp)); ahp.ah_getChannelEdges = getChannelEdges; ahp.ah_getWirelessModes = getWirelessModes; ahp.ah_eepromRead = eepromRead; ahp.ah_getChipPowerLimits = getChipPowerLimits; ahp.ah_caps.halWirelessModes = HAL_MODE_ALL; ahp.ah_caps.halLow5GhzChan = 4920; ahp.ah_caps.halHigh5GhzChan = 6100; ahp.ah_caps.halLow2GhzChan = 2312; ahp.ah_caps.halHigh2GhzChan = 2732; ahp.ah_caps.halChanHalfRate = AH_TRUE; ahp.ah_caps.halChanQuarterRate = AH_TRUE; ahp.h.ah_getCapability = getCapability; ahp.ah_opmode = HAL_M_STA; tpcReduction = tpcScaleReductionTable[0]; powerLimit = MAX_RATE_POWER; while ((i = getopt(argc, argv, "acdeflm:pr4ABGhHNT")) != -1) switch (i) { case 'a': showall = AH_TRUE; break; case 'c': showchannels = AH_TRUE; break; case 'd': ath_hal_debug = HAL_DEBUG_ANY; break; case 'e': extendedChanMode = AH_FALSE; break; case 'f': showchannels = AH_FALSE; break; case 'l': cclist(); rdlist(); exit(0); case 'm': if (strncasecmp(optarg, "sta", 2) == 0) ahp.ah_opmode = HAL_M_STA; else if (strncasecmp(optarg, "ibss", 2) == 0) ahp.ah_opmode = HAL_M_IBSS; else if (strncasecmp(optarg, "adhoc", 2) == 0) ahp.ah_opmode = HAL_M_IBSS; else if (strncasecmp(optarg, "ap", 2) == 0) ahp.ah_opmode = HAL_M_HOSTAP; else if (strncasecmp(optarg, "hostap", 2) == 0) ahp.ah_opmode = HAL_M_HOSTAP; else if (strncasecmp(optarg, "monitor", 2) == 0) ahp.ah_opmode = HAL_M_MONITOR; else usage(argv[0]); break; case 'p': dopassive = 1; break; case 'A': modes |= HAL_MODE_11A; break; case 'B': modes |= HAL_MODE_11B; break; case 'G': modes |= HAL_MODE_11G; break; case 'h': modes |= HAL_MODE_HT20; break; case 'H': modes |= HAL_MODE_HT40; break; case 'N': modes |= HAL_MODE_HT; break; case 'T': modes |= HAL_MODE_TURBO | HAL_MODE_108G; break; case 'r': showdfs = 1; break; case '4': show4ms = 1; break; default: usage(argv[0]); } switch (argc - optind) { case 0: if (!cclookup("US", &rd, &cc)) { printf("%s: unknown country code\n", "US"); exit(-1); } break; case 1: /* cc/regdomain */ if (!cclookup(argv[optind], &rd, &cc)) { if (!rdlookup(argv[optind], &rd)) { const char* rdname; rd = strtoul(argv[optind], NULL, 0); rdname = getrdname(rd); if (rdname == NULL) { printf("%s: unknown country/regulatory " "domain code\n", argv[optind]); exit(-1); } } cc = CTRY_DEFAULT; } break; default: /* regdomain cc */ if (!rdlookup(argv[optind], &rd)) { const char* rdname; rd = strtoul(argv[optind], NULL, 0); rdname = getrdname(rd); if (rdname == NULL) { printf("%s: unknown country/regulatory " "domain code\n", argv[optind]); exit(-1); } } if (!cclookup(argv[optind+1], &rd, &cc)) cc = strtoul(argv[optind+1], NULL, 0); break; } if (cc != CTRY_DEFAULT) printf("\n%s (%s, 0x%x, %u) %s (0x%x, %u)\n", getccname(cc), getccisoname(cc), cc, cc, getrdname(rd), rd, rd); else printf("\n%s (0x%x, %u)\n", getrdname(rd), rd, rd); if (modes == 0) { /* NB: no HAL_MODE_HT */ modes = HAL_MODE_11A | HAL_MODE_11B | HAL_MODE_11G | HAL_MODE_TURBO | HAL_MODE_108G; } na = nb = ng = nt = ntg = nn = 0; if (modes & HAL_MODE_11G) { ahp.ah_currentRD = rd; if (ath_hal_getchannels(&ahp.h, gchans, IEEE80211_CHAN_MAX, &ng, HAL_MODE_11G, cc, rd, extendedChanMode) == HAL_OK) { calctxpower(&ahp.h, ng, gchans, tpcReduction, powerLimit, gtxpow); if (showdfs) isdfs |= anychan(gchans, ng, IEEE80211_CHAN_DFS); if (show4ms) is4ms |= anychan(gchans, ng, IEEE80211_CHAN_4MSXMIT); } } if (modes & HAL_MODE_11B) { ahp.ah_currentRD = rd; if (ath_hal_getchannels(&ahp.h, bchans, IEEE80211_CHAN_MAX, &nb, HAL_MODE_11B, cc, rd, extendedChanMode) == HAL_OK) { calctxpower(&ahp.h, nb, bchans, tpcReduction, powerLimit, btxpow); if (showdfs) isdfs |= anychan(bchans, nb, IEEE80211_CHAN_DFS); if (show4ms) is4ms |= anychan(bchans, nb, IEEE80211_CHAN_4MSXMIT); } } if (modes & HAL_MODE_11A) { ahp.ah_currentRD = rd; if (ath_hal_getchannels(&ahp.h, achans, IEEE80211_CHAN_MAX, &na, HAL_MODE_11A, cc, rd, extendedChanMode) == HAL_OK) { calctxpower(&ahp.h, na, achans, tpcReduction, powerLimit, atxpow); if (showdfs) isdfs |= anychan(achans, na, IEEE80211_CHAN_DFS); if (show4ms) is4ms |= anychan(achans, na, IEEE80211_CHAN_4MSXMIT); } } if (modes & HAL_MODE_TURBO) { ahp.ah_currentRD = rd; if (ath_hal_getchannels(&ahp.h, tchans, IEEE80211_CHAN_MAX, &nt, HAL_MODE_TURBO, cc, rd, extendedChanMode) == HAL_OK) { calctxpower(&ahp.h, nt, tchans, tpcReduction, powerLimit, ttxpow); if (showdfs) isdfs |= anychan(tchans, nt, IEEE80211_CHAN_DFS); if (show4ms) is4ms |= anychan(tchans, nt, IEEE80211_CHAN_4MSXMIT); } } if (modes & HAL_MODE_108G) { ahp.ah_currentRD = rd; if (ath_hal_getchannels(&ahp.h, tgchans, IEEE80211_CHAN_MAX, &ntg, HAL_MODE_108G, cc, rd, extendedChanMode) == HAL_OK) { calctxpower(&ahp.h, ntg, tgchans, tpcReduction, powerLimit, tgtxpow); if (showdfs) isdfs |= anychan(tgchans, ntg, IEEE80211_CHAN_DFS); if (show4ms) is4ms |= anychan(tgchans, ntg, IEEE80211_CHAN_4MSXMIT); } } if (modes & HAL_MODE_HT) { ahp.ah_currentRD = rd; if (ath_hal_getchannels(&ahp.h, nchans, IEEE80211_CHAN_MAX, &nn, modes & HAL_MODE_HT, cc, rd, extendedChanMode) == HAL_OK) { calctxpower(&ahp.h, nn, nchans, tpcReduction, powerLimit, ntxpow); if (showdfs) isdfs |= anychan(nchans, nn, IEEE80211_CHAN_DFS); if (show4ms) is4ms |= anychan(nchans, nn, IEEE80211_CHAN_4MSXMIT); } } if (!showall) { #define CHECKMODES(_modes, _m) ((_modes & (_m)) == (_m)) if (CHECKMODES(modes, HAL_MODE_11B|HAL_MODE_11G)) { /* b ^= g */ intersect(bchans, btxpow, &nb, gchans, gtxpow, ng); } if (CHECKMODES(modes, HAL_MODE_11A|HAL_MODE_TURBO)) { /* t ^= a */ intersect(tchans, ttxpow, &nt, achans, atxpow, na); } if (CHECKMODES(modes, HAL_MODE_11G|HAL_MODE_108G)) { /* tg ^= g */ intersect(tgchans, tgtxpow, &ntg, gchans, gtxpow, ng); } if (CHECKMODES(modes, HAL_MODE_11G|HAL_MODE_HT)) { /* g ^= n */ intersect(gchans, gtxpow, &ng, nchans, ntxpow, nn); } if (CHECKMODES(modes, HAL_MODE_11A|HAL_MODE_HT)) { /* a ^= n */ intersect(achans, atxpow, &na, nchans, ntxpow, nn); } #undef CHECKMODES } if (modes & HAL_MODE_11G) dumpchannels(&ahp.h, ng, gchans, gtxpow); if (modes & HAL_MODE_11B) dumpchannels(&ahp.h, nb, bchans, btxpow); if (modes & HAL_MODE_11A) dumpchannels(&ahp.h, na, achans, atxpow); if (modes & HAL_MODE_108G) dumpchannels(&ahp.h, ntg, tgchans, tgtxpow); if (modes & HAL_MODE_TURBO) dumpchannels(&ahp.h, nt, tchans, ttxpow); if (modes & HAL_MODE_HT) dumpchannels(&ahp.h, nn, nchans, ntxpow); printf("\n"); return (0); }