8250_pci.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,238 行 · 第 1/4 页
C
2,238 行
.flags = FL_BASE0, .num_ports = 1, .base_baud = 921600, .uart_offset = 8, }, [pbn_b0_2_921600] = { .flags = FL_BASE0, .num_ports = 2, .base_baud = 921600, .uart_offset = 8, }, [pbn_b0_4_921600] = { .flags = FL_BASE0, .num_ports = 4, .base_baud = 921600, .uart_offset = 8, }, [pbn_b0_bt_1_115200] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 1, .base_baud = 115200, .uart_offset = 8, }, [pbn_b0_bt_2_115200] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 2, .base_baud = 115200, .uart_offset = 8, }, [pbn_b0_bt_8_115200] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 8, .base_baud = 115200, .uart_offset = 8, }, [pbn_b0_bt_1_460800] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 1, .base_baud = 460800, .uart_offset = 8, }, [pbn_b0_bt_2_460800] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 2, .base_baud = 460800, .uart_offset = 8, }, [pbn_b0_bt_4_460800] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 4, .base_baud = 460800, .uart_offset = 8, }, [pbn_b0_bt_1_921600] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 1, .base_baud = 921600, .uart_offset = 8, }, [pbn_b0_bt_2_921600] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 2, .base_baud = 921600, .uart_offset = 8, }, [pbn_b0_bt_4_921600] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 4, .base_baud = 921600, .uart_offset = 8, }, [pbn_b0_bt_8_921600] = { .flags = FL_BASE0|FL_BASE_BARS, .num_ports = 8, .base_baud = 921600, .uart_offset = 8, }, [pbn_b1_1_115200] = { .flags = FL_BASE1, .num_ports = 1, .base_baud = 115200, .uart_offset = 8, }, [pbn_b1_2_115200] = { .flags = FL_BASE1, .num_ports = 2, .base_baud = 115200, .uart_offset = 8, }, [pbn_b1_4_115200] = { .flags = FL_BASE1, .num_ports = 4, .base_baud = 115200, .uart_offset = 8, }, [pbn_b1_8_115200] = { .flags = FL_BASE1, .num_ports = 8, .base_baud = 115200, .uart_offset = 8, }, [pbn_b1_1_921600] = { .flags = FL_BASE1, .num_ports = 1, .base_baud = 921600, .uart_offset = 8, }, [pbn_b1_2_921600] = { .flags = FL_BASE1, .num_ports = 2, .base_baud = 921600, .uart_offset = 8, }, [pbn_b1_4_921600] = { .flags = FL_BASE1, .num_ports = 4, .base_baud = 921600, .uart_offset = 8, }, [pbn_b1_8_921600] = { .flags = FL_BASE1, .num_ports = 8, .base_baud = 921600, .uart_offset = 8, }, [pbn_b1_bt_2_921600] = { .flags = FL_BASE1|FL_BASE_BARS, .num_ports = 2, .base_baud = 921600, .uart_offset = 8, }, [pbn_b1_2_1382400] = { .flags = FL_BASE1, .num_ports = 2, .base_baud = 1382400, .uart_offset = 8, }, [pbn_b1_4_1382400] = { .flags = FL_BASE1, .num_ports = 4, .base_baud = 1382400, .uart_offset = 8, }, [pbn_b1_8_1382400] = { .flags = FL_BASE1, .num_ports = 8, .base_baud = 1382400, .uart_offset = 8, }, [pbn_b2_1_115200] = { .flags = FL_BASE2, .num_ports = 1, .base_baud = 115200, .uart_offset = 8, }, [pbn_b2_8_115200] = { .flags = FL_BASE2, .num_ports = 8, .base_baud = 115200, .uart_offset = 8, }, [pbn_b2_1_460800] = { .flags = FL_BASE2, .num_ports = 1, .base_baud = 460800, .uart_offset = 8, }, [pbn_b2_4_460800] = { .flags = FL_BASE2, .num_ports = 4, .base_baud = 460800, .uart_offset = 8, }, [pbn_b2_8_460800] = { .flags = FL_BASE2, .num_ports = 8, .base_baud = 460800, .uart_offset = 8, }, [pbn_b2_16_460800] = { .flags = FL_BASE2, .num_ports = 16, .base_baud = 460800, .uart_offset = 8, }, [pbn_b2_1_921600] = { .flags = FL_BASE2, .num_ports = 1, .base_baud = 921600, .uart_offset = 8, }, [pbn_b2_4_921600] = { .flags = FL_BASE2, .num_ports = 4, .base_baud = 921600, .uart_offset = 8, }, [pbn_b2_8_921600] = { .flags = FL_BASE2, .num_ports = 8, .base_baud = 921600, .uart_offset = 8, }, [pbn_b2_bt_1_115200] = { .flags = FL_BASE2|FL_BASE_BARS, .num_ports = 1, .base_baud = 115200, .uart_offset = 8, }, [pbn_b2_bt_2_115200] = { .flags = FL_BASE2|FL_BASE_BARS, .num_ports = 2, .base_baud = 115200, .uart_offset = 8, }, [pbn_b2_bt_4_115200] = { .flags = FL_BASE2|FL_BASE_BARS, .num_ports = 4, .base_baud = 115200, .uart_offset = 8, }, [pbn_b2_bt_2_921600] = { .flags = FL_BASE2|FL_BASE_BARS, .num_ports = 2, .base_baud = 921600, .uart_offset = 8, }, [pbn_b2_bt_4_921600] = { .flags = FL_BASE2|FL_BASE_BARS, .num_ports = 4, .base_baud = 921600, .uart_offset = 8, }, [pbn_b3_4_115200] = { .flags = FL_BASE3, .num_ports = 4, .base_baud = 115200, .uart_offset = 8, }, [pbn_b3_8_115200] = { .flags = FL_BASE3, .num_ports = 8, .base_baud = 115200, .uart_offset = 8, }, /* * Entries following this are board-specific. */ /* * Panacom - IOMEM */ [pbn_panacom] = { .flags = FL_BASE2, .num_ports = 2, .base_baud = 921600, .uart_offset = 0x400, .reg_shift = 7, }, [pbn_panacom2] = { .flags = FL_BASE2|FL_BASE_BARS, .num_ports = 2, .base_baud = 921600, .uart_offset = 0x400, .reg_shift = 7, }, [pbn_panacom4] = { .flags = FL_BASE2|FL_BASE_BARS, .num_ports = 4, .base_baud = 921600, .uart_offset = 0x400, .reg_shift = 7, }, /* I think this entry is broken - the first_offset looks wrong --rmk */ [pbn_plx_romulus] = { .flags = FL_BASE2, .num_ports = 4, .base_baud = 921600, .uart_offset = 8 << 2, .reg_shift = 2, .first_offset = 0x03, }, /* * This board uses the size of PCI Base region 0 to * signal now many ports are available */ [pbn_oxsemi] = { .flags = FL_BASE0|FL_REGION_SZ_CAP, .num_ports = 32, .base_baud = 115200, .uart_offset = 8, }, /* * EKF addition for i960 Boards form EKF with serial port. * Max 256 ports. */ [pbn_intel_i960] = { .flags = FL_BASE0, .num_ports = 32, .base_baud = 921600, .uart_offset = 8 << 2, .reg_shift = 2, .first_offset = 0x10000, }, [pbn_sgi_ioc3] = { .flags = FL_BASE0|FL_NOIRQ, .num_ports = 1, .base_baud = 458333, .uart_offset = 8, .reg_shift = 0, .first_offset = 0x20178, }, /* * NEC Vrc-5074 (Nile 4) builtin UART. */ [pbn_nec_nile4] = { .flags = FL_BASE0, .num_ports = 1, .base_baud = 520833, .uart_offset = 8 << 3, .reg_shift = 3, .first_offset = 0x300, }, /* * Computone - uses IOMEM. */ [pbn_computone_4] = { .flags = FL_BASE0, .num_ports = 4, .base_baud = 921600, .uart_offset = 0x40, .reg_shift = 2, .first_offset = 0x200, }, [pbn_computone_6] = { .flags = FL_BASE0, .num_ports = 6, .base_baud = 921600, .uart_offset = 0x40, .reg_shift = 2, .first_offset = 0x200, }, [pbn_computone_8] = { .flags = FL_BASE0, .num_ports = 8, .base_baud = 921600, .uart_offset = 0x40, .reg_shift = 2, .first_offset = 0x200, }, [pbn_sbsxrsio] = { .flags = FL_BASE0, .num_ports = 8, .base_baud = 460800, .uart_offset = 256, .reg_shift = 4, }, /* * Exar Corp. XR17C15[248] Dual/Quad/Octal UART * Only basic 16550A support. * XR17C15[24] are not tested, but they should work. */ [pbn_exar_XR17C152] = { .flags = FL_BASE0, .num_ports = 2, .base_baud = 921600, .uart_offset = 0x200, }, [pbn_exar_XR17C154] = { .flags = FL_BASE0, .num_ports = 4, .base_baud = 921600, .uart_offset = 0x200, }, [pbn_exar_XR17C158] = { .flags = FL_BASE0, .num_ports = 8, .base_baud = 921600, .uart_offset = 0x200, },};/* * Given a complete unknown PCI device, try to use some heuristics to * guess what the configuration might be, based on the pitiful PCI * serial specs. Returns 0 on success, 1 on failure. */static int __devinitserial_pci_guess_board(struct pci_dev *dev, struct pci_board *board){ int num_iomem, num_port, first_port = -1, i; /* * If it is not a communications device or the programming * interface is greater than 6, give up. * * (Should we try to make guesses for multiport serial devices * later?) */ if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) && ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) || (dev->class & 0xff) > 6) return -ENODEV; num_iomem = num_port = 0; for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { if (pci_resource_flags(dev, i) & IORESOURCE_IO) { num_port++; if (first_port == -1) first_port = i; } if (pci_resource_flags(dev, i) & IORESOURCE_MEM) num_iomem++; } /* * If there is 1 or 0 iomem regions, and exactly one port, * use it. We guess the number of ports based on the IO * region size. */ if (num_iomem <= 1 && num_port == 1) { board->flags = first_port; board->num_ports = pci_resource_len(dev, first_port) / 8; return 0; } /* * Now guess if we've got a board which indexes by BARs. * Each IO BAR should be 8 bytes, and they should follow * consecutively. */ first_port = -1; num_port = 0; for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { if (pci_resource_flags(dev, i) & IORESOURCE_IO && pci_resource_len(dev, i) == 8 && (first_port == -1 || (first_port + num_port) == i)) { num_port++; if (first_port == -1) first_port = i; } } if (num_port > 1) { board->flags = first_port | FL_BASE_BARS; board->num_ports = num_port; return 0; } return -ENODEV;}static inline intserial_pci_matches(struct pci_board *board, struct pci_board *guessed){ return board->num_ports == guessed->num_ports && board->base_baud == guessed->base_baud && board->uart_offset == guessed->uart_offset && board->reg_shift == guessed->reg_shift && board->first_offset == guessed->first_offset;}/* * Probe one serial board. Unfortunately, there is no rhyme nor reason * to the arrangement of serial ports on a PCI card. */static int __devinitpciserial_init_one(struct pci_dev *dev, const struct pci_device_id *ent){ struct serial_private *priv; struct pci_board *board, tmp; struct pci_serial_quirk *quirk; struct serial_struct serial_req; int rc, nr_ports, i; if (ent->driver_data >= ARRAY_SIZE(pci_boards)) { printk(KERN_ERR "pci_init_one: invalid driver_data: %ld\n", ent->driver_data); return -EINVAL; } board = &pci_boards[ent->driver_data]; rc = pci_enable_device(dev); if (rc) return rc; if (ent->driver_data == pbn_default) { /* * Use a copy of the pci_board entry for this; * avoid changing entries in the table. */ memcpy(&tmp, board, sizeof(struct pci_board)); board = &tmp; /* * We matched one of our class entries. Try to * determine the parameters of this board. */ rc = serial_pci_guess_board(dev, board); if (rc) goto disable; } else { /* * We matched an explicit entry. If we are able to * detect this boards settings with our heuristic, * then we no longer need this entry. */ memcpy(&tmp, &pci_boards[pbn_default], sizeof(struct pci_board)); rc = serial_pci_guess_board(dev, &tmp); if (rc == 0 && serial_pci_matches(board, &tmp)) moan_device("Redundant entry in serial pci_table.", dev); } nr_ports = board->num_ports; /* * Find an init and setup quirks. */ quirk = find_quirk(dev); /* * Run the new-style initialization function. * The initialization function returns: * <0 - error * 0 - use board->num_ports * >0 - number of ports */ if (quirk->init) { rc = quirk->init(dev); if (rc < 0) goto disable; if (rc) nr_ports = rc; } priv = kmalloc(sizeof(struct serial_private) + sizeof(unsigned int) * nr_ports, GFP_KERNEL);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?