?? isapnp_proc.c
字號:
for (i = next = 0; i < 2; i++) { tmp = isapnp_read_word(ISAPNP_CFG_IRQ + (i << 1)); if (!(tmp >> 8)) continue; if (!next) { isapnp_printf(buffer, "%sActive IRQ ", space); next = 1; } isapnp_printf(buffer, "%s%i", i > 0 ? "," : "", tmp >> 8); if (tmp & 0xff) isapnp_printf(buffer, " [0x%x]", tmp & 0xff); } if (next) isapnp_printf(buffer, "\n"); for (i = next = 0; i < 2; i++) { tmp = isapnp_read_byte(ISAPNP_CFG_DMA + i); if (tmp == 4) continue; if (!next) { isapnp_printf(buffer, "%sActive DMA ", space); next = 1; } isapnp_printf(buffer, "%s%i", i > 0 ? "," : "", tmp); } if (next) isapnp_printf(buffer, "\n"); for (i = next = 0; i < 4; i++) { tmp = isapnp_read_dword(ISAPNP_CFG_MEM + (i << 3)); if (!tmp) continue; if (!next) { isapnp_printf(buffer, "%sActive memory ", space); next = 1; } isapnp_printf(buffer, "%s0x%x", i > 0 ? "," : "", tmp); } if (next) isapnp_printf(buffer, "\n"); isapnp_cfg_end();}static void isapnp_print_device(isapnp_info_buffer_t *buffer, struct pnp_dev *dev){ int block, block1; char *space = " "; struct isapnp_resources *res, *resa; if (!dev) return; isapnp_printf(buffer, " Logical device %i '", dev->devfn); isapnp_print_devid(buffer, dev->vendor, dev->device); isapnp_printf(buffer, ":%s'", dev->name[0]?dev->name:"Unknown"); isapnp_printf(buffer, "\n");#if 0 isapnp_cfg_begin(dev->bus->number, dev->devfn); for (block = 0; block < 128; block++) if ((block % 16) == 15) isapnp_printf(buffer, "%02x\n", isapnp_read_byte(block)); else isapnp_printf(buffer, "%02x:", isapnp_read_byte(block)); isapnp_cfg_end();#endif if (dev->regs) isapnp_printf(buffer, "%sSupported registers 0x%x\n", space, dev->regs); isapnp_print_compatible(buffer, dev); isapnp_print_configuration(buffer, dev); for (res = (struct isapnp_resources *)dev->sysdata, block = 0; res; res = res->next, block++) { isapnp_printf(buffer, "%sResources %i\n", space, block); isapnp_print_resources(buffer, " ", res); for (resa = res->alt, block1 = 1; resa; resa = resa->alt, block1++) { isapnp_printf(buffer, "%s Alternate resources %i:%i\n", space, block, block1); isapnp_print_resources(buffer, " ", resa); } }}/* * Main read routine */ static void isapnp_info_read(isapnp_info_buffer_t *buffer){ struct pnp_bus *card; struct pnp_dev *dev; for (card = isapnp_cards; card; card = card->next) { isapnp_printf(buffer, "Card %i '", card->number); isapnp_print_devid(buffer, card->vendor, card->device); isapnp_printf(buffer, ":%s'", card->name[0]?card->name:"Unknown"); if (card->pnpver) isapnp_printf(buffer, " PnP version %x.%x", card->pnpver >> 4, card->pnpver & 0x0f); if (card->productver) isapnp_printf(buffer, " Product version %x.%x", card->productver >> 4, card->productver & 0x0f); isapnp_printf(buffer,"\n"); for (dev = card->devices; dev; dev = dev->sibling) isapnp_print_device(buffer, dev); }}/* * */static struct pnp_bus *isapnp_info_card;static struct pnp_dev *isapnp_info_device;static char *isapnp_get_str(char *dest, char *src, int len){ int c; while (*src == ' ' || *src == '\t') src++; if (*src == '"' || *src == '\'') { c = *src++; while (--len > 0 && *src && *src != c) { *dest++ = *src++; } if (*src == c) src++; } else { while (--len > 0 && *src && *src != ' ' && *src != '\t') { *dest++ = *src++; } } *dest = 0; while (*src == ' ' || *src == '\t') src++; return src;}static unsigned char isapnp_get_hex(unsigned char c){ if (c >= '0' || c <= '9') return c - '0'; if (c >= 'a' || c <= 'f') return (c - 'a') + 10; if (c >= 'A' || c <= 'F') return (c - 'A') + 10; return 0;}static unsigned int isapnp_parse_id(const char *id){ if (strlen(id) != 7) { printk("isapnp: wrong PnP ID\n"); return 0; } return (ISAPNP_VENDOR(id[0], id[1], id[2])<<16) | (isapnp_get_hex(id[3])<<4) | (isapnp_get_hex(id[4])<<0) | (isapnp_get_hex(id[5])<<12) | (isapnp_get_hex(id[6])<<8);}static int isapnp_set_card(char *line){ int idx, idx1; unsigned int id; char index[16], value[32]; isapnp_info_card = NULL; line = isapnp_get_str(index, line, sizeof(index)); isapnp_get_str(value, line, sizeof(value)); idx = idx1 = simple_strtoul(index, NULL, 0); id = isapnp_parse_id(value); isapnp_info_card = isapnp_find_card(id >> 16, id & 0xffff, NULL); while (isapnp_info_card && idx1-- > 0) isapnp_info_card = isapnp_find_card(id >> 16, id & 0xffff, isapnp_info_card); if (isapnp_info_card == NULL) { printk("isapnp: card '%s' order %i not found\n", value, idx); return 1; } if (isapnp_cfg_begin(isapnp_info_card->number, -1)<0) { printk("isapnp: configuration start sequence for device '%s' failed\n", value); isapnp_info_card = NULL; return 1; } return 0;}static int isapnp_select_csn(char *line){ int csn; char index[16], value[32]; isapnp_info_device = NULL; isapnp_get_str(index, line, sizeof(index)); csn = simple_strtoul(index, NULL, 0); for (isapnp_info_card = isapnp_cards; isapnp_info_card; isapnp_info_card = isapnp_info_card->next) if (isapnp_info_card->number == csn) break; if (isapnp_info_card == NULL) { printk("isapnp: cannot find CSN %i\n", csn); return 1; } if (isapnp_cfg_begin(isapnp_info_card->number, -1)<0) { printk("isapnp: configuration start sequence for device '%s' failed\n", value); isapnp_info_card = NULL; return 1; } return 0;}static int isapnp_set_device(char *line){ int idx, idx1; unsigned int id; char index[16], value[32]; line = isapnp_get_str(index, line, sizeof(index)); isapnp_get_str(value, line, sizeof(value)); idx = idx1 = simple_strtoul(index, NULL, 0); id = isapnp_parse_id(value); isapnp_info_device = isapnp_find_dev(isapnp_info_card, id >> 16, id & 0xffff, NULL); while (isapnp_info_device && idx-- > 0) isapnp_info_device = isapnp_find_dev(isapnp_info_card, id >> 16, id & 0xffff, isapnp_info_device); if (isapnp_info_device == NULL) { printk("isapnp: device '%s' order %i not found\n", value, idx); return 1; } isapnp_device(isapnp_info_device->devfn); return 0;}static int isapnp_autoconfigure(void){ if (isapnp_info_device == NULL) { printk("isapnp: device is not set\n"); return 0; } if (isapnp_info_device->active) isapnp_info_device->deactivate(isapnp_info_device); if (isapnp_info_device->prepare(isapnp_info_device) < 0) { printk("isapnp: cannot prepare device for the activation"); return 0; } if (isapnp_info_device->activate(isapnp_info_device) < 0) { printk("isapnp: cannot activate device"); return 0; } return 0;}static int isapnp_set_port(char *line){ int idx, port; char index[16], value[32]; line = isapnp_get_str(index, line, sizeof(index)); isapnp_get_str(value, line, sizeof(value)); idx = simple_strtoul(index, NULL, 0); port = simple_strtoul(value, NULL, 0); if (idx < 0 || idx > 7) { printk("isapnp: wrong port index %i\n", idx); return 1; } if (port < 0 || port > 0xffff) { printk("isapnp: wrong port value 0x%x\n", port); return 1; } isapnp_write_word(ISAPNP_CFG_PORT + (idx << 1), port); if (!isapnp_info_device->resource[idx].flags) return 0; if (isapnp_info_device->resource[idx].flags & IORESOURCE_AUTO) { isapnp_info_device->resource[idx].start = port; isapnp_info_device->resource[idx].end += port - 1; isapnp_info_device->resource[idx].flags &= ~IORESOURCE_AUTO; } else { isapnp_info_device->resource[idx].end -= isapnp_info_device->resource[idx].start; isapnp_info_device->resource[idx].start = port; isapnp_info_device->resource[idx].end += port; } return 0;}static void isapnp_set_irqresource(struct resource *res, int irq){ res->start = res->end = irq; res->flags = IORESOURCE_IRQ;} static int isapnp_set_irq(char *line){ int idx, irq; char index[16], value[32]; line = isapnp_get_str(index, line, sizeof(index)); isapnp_get_str(value, line, sizeof(value)); idx = simple_strtoul(index, NULL, 0); irq = simple_strtoul(value, NULL, 0); if (idx < 0 || idx > 1) { printk("isapnp: wrong IRQ index %i\n", idx); return 1; } if (irq == 2) irq = 9; if (irq < 0 || irq > 15) { printk("isapnp: wrong IRQ value %i\n", irq); return 1; } isapnp_write_byte(ISAPNP_CFG_IRQ + (idx << 1), irq); isapnp_set_irqresource(isapnp_info_device->irq_resource + idx, irq); return 0;} static void isapnp_set_dmaresource(struct resource *res, int dma){ res->start = res->end = dma; res->flags = IORESOURCE_DMA;} static int isapnp_set_dma(char *line){ int idx, dma; char index[16], value[32]; line = isapnp_get_str(index, line, sizeof(index)); isapnp_get_str(value, line, sizeof(value)); idx = simple_strtoul(index, NULL, 0); dma = simple_strtoul(value, NULL, 0); if (idx < 0 || idx > 1) { printk("isapnp: wrong DMA index %i\n", idx); return 1; } if (dma < 0 || dma > 7) { printk("isapnp: wrong DMA value %i\n", dma); return 1; } isapnp_write_byte(ISAPNP_CFG_DMA + idx, dma); isapnp_set_dmaresource(isapnp_info_device->dma_resource + idx, dma); return 0;} static int isapnp_set_mem(char *line){ int idx; unsigned int mem; char index[16], value[32]; line = isapnp_get_str(index, line, sizeof(index)); isapnp_get_str(value, line, sizeof(value)); idx = simple_strtoul(index, NULL, 0); mem = simple_strtoul(value, NULL, 0); if (idx < 0 || idx > 3) { printk("isapnp: wrong memory index %i\n", idx); return 1; } mem >>= 8; isapnp_write_word(ISAPNP_CFG_MEM + (idx<<2), mem & 0xffff); if (!isapnp_info_device->resource[idx + 8].flags) return 0; if (isapnp_info_device->resource[idx + 8].flags & IORESOURCE_AUTO) { isapnp_info_device->resource[idx + 8].start = mem & ~0x00ffff00; isapnp_info_device->resource[idx + 8].end += (mem & ~0x00ffff00) - 1; isapnp_info_device->resource[idx + 8].flags &= ~IORESOURCE_AUTO; } else { isapnp_info_device->resource[idx + 8].end -= isapnp_info_device->resource[idx + 8].start; isapnp_info_device->resource[idx + 8].start = mem & ~0x00ffff00; isapnp_info_device->resource[idx + 8].end += mem & ~0x00ffff00; } return 0;} static int isapnp_poke(char *line, int what){ int reg; unsigned int val; char index[16], value[32]; line = isapnp_get_str(index, line, sizeof(index)); isapnp_get_str(value, line, sizeof(value)); reg = simple_strtoul(index, NULL, 0); val = simple_strtoul(value, NULL, 0); if (reg < 0 || reg > 127) { printk("isapnp: wrong register %i\n", reg); return 1; } switch (what) { case 1: isapnp_write_word(reg, val); break; case 2: isapnp_write_dword(reg, val); break; default: isapnp_write_byte(reg, val); break; } return 0;} static int isapnp_decode_line(char *line){ char cmd[32]; line = isapnp_get_str(cmd, line, sizeof(cmd)); if (!strcmp(cmd, "card")) return isapnp_set_card(line); if (!strcmp(cmd, "csn")) return isapnp_select_csn(line); if (!isapnp_info_card) { printk("isapnp: card is not selected\n"); return 1; } if (!strncmp(cmd, "dev", 3)) return isapnp_set_device(line); if (!isapnp_info_device) { printk("isapnp: device is not selected\n"); return 1; } if (!strncmp(cmd, "auto", 4)) return isapnp_autoconfigure(); if (!strncmp(cmd, "act", 3)) { isapnp_activate(isapnp_info_device->devfn); isapnp_info_device->active = 1; return 0; } if (!strncmp(cmd, "deact", 5)) { isapnp_deactivate(isapnp_info_device->devfn); isapnp_info_device->active = 0; return 0; } if (!strcmp(cmd, "port")) return isapnp_set_port(line); if (!strcmp(cmd, "irq")) return isapnp_set_irq(line); if (!strcmp(cmd, "dma")) return isapnp_set_dma(line); if (!strncmp(cmd, "mem", 3)) return isapnp_set_mem(line); if (!strcmp(cmd, "poke")) return isapnp_poke(line, 0); if (!strcmp(cmd, "pokew")) return isapnp_poke(line, 1); if (!strcmp(cmd, "poked")) return isapnp_poke(line, 2); printk("isapnp: wrong command '%s'\n", cmd); return 1;}/* * Main write routine */static void isapnp_info_write(isapnp_info_buffer_t *buffer){ int c, idx, idx1 = 0; char line[128]; if (buffer->size <= 0) return; isapnp_info_card = NULL; isapnp_info_device = NULL; for (idx = 0; idx < buffer->size; idx++) { c = buffer->buffer[idx]; if (c == '\n') { line[idx1] = '\0'; if (line[0] != '#') { if (isapnp_decode_line(line)) goto __end; } idx1 = 0; continue; } if (idx1 >= sizeof(line)-1) { printk("isapnp: line too long, aborting\n"); return; } line[idx1++] = c; } __end: if (isapnp_info_card) isapnp_cfg_end();}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -