📄 isapnp_proc.c
字号:
}static void isapnp_print_mem32(isapnp_info_buffer_t *buffer, char *space, struct isapnp_mem32 *mem32){ int first = 1, i; isapnp_printf(buffer, "%s32-bit memory ", space); for (i = 0; i < 17; i++) { if (first) { first = 0; } else { isapnp_printf(buffer, ":"); } isapnp_printf(buffer, "%02x", mem32->data[i]); }}static void isapnp_print_resources(isapnp_info_buffer_t *buffer, char *space, struct isapnp_resources *res){ char *s; struct isapnp_port *port; struct isapnp_irq *irq; struct isapnp_dma *dma; struct isapnp_mem *mem; struct isapnp_mem32 *mem32; switch (res->priority) { case ISAPNP_RES_PRIORITY_PREFERRED: s = "preferred"; break; case ISAPNP_RES_PRIORITY_ACCEPTABLE: s = "acceptable"; break; case ISAPNP_RES_PRIORITY_FUNCTIONAL: s = "functional"; break; default: s = "invalid"; } isapnp_printf(buffer, "%sPriority %s\n", space, s); for (port = res->port; port; port = port->next) isapnp_print_port(buffer, space, port); for (irq = res->irq; irq; irq = irq->next) isapnp_print_irq(buffer, space, irq); for (dma = res->dma; dma; dma = dma->next) isapnp_print_dma(buffer, space, dma); for (mem = res->mem; mem; mem = mem->next) isapnp_print_mem(buffer, space, mem); for (mem32 = res->mem32; mem32; mem32 = mem32->next) isapnp_print_mem32(buffer, space, mem32);}static void isapnp_print_configuration(isapnp_info_buffer_t *buffer, struct pci_dev *dev){ int i, tmp, next; char *space = " "; isapnp_cfg_begin(dev->bus->number, dev->devfn); isapnp_printf(buffer, "%sDevice is %sactive\n", space, isapnp_read_byte(ISAPNP_CFG_ACTIVATE)?"":"not "); for (i = next = 0; i < 8; i++) { tmp = isapnp_read_word(ISAPNP_CFG_PORT + (i << 1)); if (!tmp) continue; if (!next) { isapnp_printf(buffer, "%sActive port ", space); next = 1; } isapnp_printf(buffer, "%s0x%x", i > 0 ? "," : "", tmp); } if (next) isapnp_printf(buffer, "\n"); 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 pci_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 pci_bus *card; isapnp_for_each_card(card) { struct list_head *dev_list; 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_list = card->devices.next; dev_list != &card->devices; dev_list = dev_list->next) isapnp_print_device(buffer, pci_dev_b(dev_list)); }}/* * */static struct pci_bus *isapnp_info_card;static struct pci_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; struct list_head *list; char index[16], value[32]; isapnp_info_device = NULL; isapnp_get_str(index, line, sizeof(index)); csn = simple_strtoul(index, NULL, 0); for (list = isapnp_cards.next; list != &isapnp_cards; list = list->next) { isapnp_info_card = pci_bus_b(list); if (isapnp_info_card->number == csn) break; } if (list == &isapnp_cards) { 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 + -