📄 8250_pci.c
字号:
return 0;}/* * This is the configuration table for all of the PCI serial boards * which we support. It is directly indexed by the pci_board_num_t enum * value, which is encoded in the pci_device_id PCI probe table's * driver_data member. */enum pci_board_num_t { pbn_b0_1_115200, pbn_default = 0, pbn_b0_2_115200, pbn_b0_4_115200, pbn_b0_1_921600, pbn_b0_2_921600, pbn_b0_4_921600, pbn_b0_bt_1_115200, pbn_b0_bt_2_115200, pbn_b0_bt_1_460800, pbn_b0_bt_2_460800, pbn_b1_1_115200, pbn_b1_2_115200, pbn_b1_4_115200, pbn_b1_8_115200, pbn_b1_2_921600, pbn_b1_4_921600, pbn_b1_8_921600, pbn_b1_2_1382400, pbn_b1_4_1382400, pbn_b1_8_1382400, pbn_b2_8_115200, pbn_b2_4_460800, pbn_b2_8_460800, pbn_b2_16_460800, pbn_b2_4_921600, pbn_b2_8_921600, pbn_b2_bt_1_115200, pbn_b2_bt_2_115200, pbn_b2_bt_4_115200, pbn_b2_bt_2_921600, pbn_panacom, pbn_panacom2, pbn_panacom4, pbn_plx_romulus, pbn_oxsemi, pbn_timedia, pbn_intel_i960, pbn_sgi_ioc3,#ifdef CONFIG_DDB5074 pbn_nec_nile4,#endif#if 0 pbn_dci_pccom8,#endif pbn_xircom_combo, pbn_siig10x_0, pbn_siig10x_1, pbn_siig10x_2, pbn_siig10x_4, pbn_siig20x_0, pbn_siig20x_2, pbn_siig20x_4, pbn_computone_4, pbn_computone_6, pbn_computone_8,};static struct pci_board pci_boards[] __devinitdata = { /* * PCI Flags, Number of Ports, Base (Maximum) Baud Rate, * Offset to get to next UART's registers, * Register shift to use for memory-mapped I/O, * Initialization function, first UART offset */ /* Generic serial board, pbn_b0_1_115200, pbn_default */ { SPCI_FL_BASE0, 1, 115200 }, /* pbn_b0_1_115200, pbn_default */ { SPCI_FL_BASE0, 2, 115200 }, /* pbn_b0_2_115200 */ { SPCI_FL_BASE0, 4, 115200 }, /* pbn_b0_4_115200 */ { SPCI_FL_BASE0, 1, 921600 }, /* pbn_b0_1_921600 */ { SPCI_FL_BASE0, 2, 921600 }, /* pbn_b0_2_921600 */ { SPCI_FL_BASE0, 4, 921600 }, /* pbn_b0_4_921600 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b0_bt_1_115200 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b0_bt_2_115200 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 }, /* pbn_b0_bt_1_460800 */ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, /* pbn_b0_bt_2_460800 */ { SPCI_FL_BASE1, 1, 115200 }, /* pbn_b1_1_115200 */ { SPCI_FL_BASE1, 2, 115200 }, /* pbn_b1_2_115200 */ { SPCI_FL_BASE1, 4, 115200 }, /* pbn_b1_4_115200 */ { SPCI_FL_BASE1, 8, 115200 }, /* pbn_b1_8_115200 */ { SPCI_FL_BASE1, 2, 921600 }, /* pbn_b1_2_921600 */ { SPCI_FL_BASE1, 4, 921600 }, /* pbn_b1_4_921600 */ { SPCI_FL_BASE1, 8, 921600 }, /* pbn_b1_8_921600 */ { SPCI_FL_BASE1, 2, 1382400 }, /* pbn_b1_2_1382400 */ { SPCI_FL_BASE1, 4, 1382400 }, /* pbn_b1_4_1382400 */ { SPCI_FL_BASE1, 8, 1382400 }, /* pbn_b1_8_1382400 */ { SPCI_FL_BASE2, 8, 115200 }, /* pbn_b2_8_115200 */ { SPCI_FL_BASE2, 4, 460800 }, /* pbn_b2_4_460800 */ { SPCI_FL_BASE2, 8, 460800 }, /* pbn_b2_8_460800 */ { SPCI_FL_BASE2, 16, 460800 }, /* pbn_b2_16_460800 */ { SPCI_FL_BASE2, 4, 921600 }, /* pbn_b2_4_921600 */ { SPCI_FL_BASE2, 8, 921600 }, /* pbn_b2_8_921600 */ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b2_bt_1_115200 */ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b2_bt_2_115200 */ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 115200 }, /* pbn_b2_bt_4_115200 */ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600 }, /* pbn_b2_bt_2_921600 */ { SPCI_FL_BASE2, 2, 921600, /* IOMEM */ /* pbn_panacom */ 0x400, 7, pci_plx9050_fn }, { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600, /* pbn_panacom2 */ 0x400, 7, pci_plx9050_fn }, { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600, /* pbn_panacom4 */ 0x400, 7, pci_plx9050_fn }, { SPCI_FL_BASE2, 4, 921600, /* pbn_plx_romulus */ 0x20, 2, pci_plx9050_fn, 0x03 }, /* This board uses the size of PCI Base region 0 to * signal now many ports are available */ { SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 }, /* pbn_oxsemi */ { SPCI_FL_BASE_TABLE, 1, 921600, /* pbn_timedia */ 0, 0, pci_timedia_fn }, /* EKF addition for i960 Boards form EKF with serial port */ { SPCI_FL_BASE0, 32, 921600, /* max 256 ports */ /* pbn_intel_i960 */ 8<<2, 2, pci_inteli960ni_fn, 0x10000}, { SPCI_FL_BASE0 | SPCI_FL_IRQRESOURCE, /* pbn_sgi_ioc3 */ 1, 458333, 0, 0, 0, 0x20178 },#ifdef CONFIG_DDB5074 /* * NEC Vrc-5074 (Nile 4) builtin UART. * Conditionally compiled in since this is a motherboard device. */ { SPCI_FL_BASE0, 1, 520833, /* pbn_nec_nile4 */ 64, 3, NULL, 0x300 },#endif#if 0 /* PCI_DEVICE_ID_DCI_PCCOM8 ? */ /* pbn_dci_pccom8 */ { SPCI_FL_BASE3, 8, 115200, 8 },#endif { SPCI_FL_BASE0, 1, 115200, /* pbn_xircom_combo */ 0, 0, pci_xircom_fn }, { SPCI_FL_BASE2, 1, 460800, /* pbn_siig10x_0 */ 0, 0, pci_siig10x_fn }, { SPCI_FL_BASE2, 1, 921600, /* pbn_siig10x_1 */ 0, 0, pci_siig10x_fn }, { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600, /* pbn_siig10x_2 */ 0, 0, pci_siig10x_fn }, { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600, /* pbn_siig10x_4 */ 0, 0, pci_siig10x_fn }, { SPCI_FL_BASE0, 1, 921600, /* pbn_siix20x_0 */ 0, 0, pci_siig20x_fn }, { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600, /* pbn_siix20x_2 */ 0, 0, pci_siig20x_fn }, { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 921600, /* pbn_siix20x_4 */ 0, 0, pci_siig20x_fn }, { SPCI_FL_BASE0, 4, 921600, /* IOMEM */ /* pbn_computone_4 */ 0x40, 2, NULL, 0x200 }, { SPCI_FL_BASE0, 6, 921600, /* IOMEM */ /* pbn_computone_6 */ 0x40, 2, NULL, 0x200 }, { SPCI_FL_BASE0, 8, 921600, /* IOMEM */ /* pbn_computone_8 */ 0x40, 2, NULL, 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 __devinit serial_pci_guess_board(struct pci_dev *dev, struct pci_board *board){ int num_iomem = 0, num_port = 0, first_port = -1; int 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 1; for (i=0; i < 6; i++) { if (IS_PCI_REGION_IOPORT(dev, i)) { num_port++; if (first_port == -1) first_port = i; } if (IS_PCI_REGION_IOMEM(dev, i)) num_iomem++; } /* * If there is 1 or 0 iomem regions, and exactly one port, use * it. */ if (num_iomem <= 1 && num_port == 1) { board->flags = first_port; return 0; } return 1;}/* * return -1 to refuse */static int pci_init_one(struct pci_dev *dev, const struct pci_device_id *ent){ struct serial_private *priv; struct pci_board *board, tmp; struct serial_struct serial_req; int base_baud, rc, k; board = &pci_boards[ent->driver_data]; rc = pci_enable_device(dev); if (rc) return rc; if (ent->driver_data == pbn_default && serial_pci_guess_board(dev, board)) return -ENODEV; else if (serial_pci_guess_board(dev, &tmp) == 0) { printk(KERN_INFO "Redundant entry in serial pci_table. " "Please send the output of\n" "lspci -vv, this message (%d,%d,%d,%d)\n" "and the manufacturer and name of " "serial board or modem board\n" "to serial-pci-info@lists.sourceforge.net.\n", dev->vendor, dev->device, pci_get_subvendor(dev), pci_get_subdevice(dev)); } priv = kmalloc(sizeof(struct serial_private) + sizeof(unsigned int) * board->num_ports, GFP_KERNEL); if (!priv) return -ENOMEM; /* * Run the initialization function, if any */ if (board->init_fn && ((board->init_fn)(dev, board, 1) != 0)) { kfree(priv); return -ENODEV; } base_baud = board->base_baud; if (!base_baud) base_baud = BASE_BAUD; memset(&serial_req, 0, sizeof(serial_req)); for (k=0; k < board->num_ports; k++) { serial_req.irq = get_pci_irq(dev, board, k); if (get_pci_port(dev, board, &serial_req, k)) break;#ifdef SERIAL_DEBUG_PCI printk("Setup PCI/PNP port: port %x, irq %d, type %d\n", serial_req.port, serial_req.irq, serial_req.io_type);#endif serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE; serial_req.baud_base = base_baud; priv->line[k] = register_serial(&serial_req); if (priv->line[k] < 0) break; } priv->board = board; priv->nr = k; pci_set_drvdata(dev, priv); return 0;}static void pci_remove_one(struct pci_dev *dev){ struct serial_private *priv = pci_get_drvdata(dev); int i; pci_set_drvdata(dev, NULL); for (i = 0; i < priv->nr; i++) unregister_serial(priv->line[i]); priv->board->init_fn(dev, priv->board, 0); kfree(priv);}static struct pci_device_id serial_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0, pbn_b1_8_1382400 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0, pbn_b1_4_1382400 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0, pbn_b1_2_1382400 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0, pbn_b1_8_1382400 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0, pbn_b1_4_1382400 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0, pbn_b1_2_1382400 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485, 0, 0, pbn_b1_8_921600 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4, 0, 0, pbn_b1_8_921600 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0, pbn_b1_4_921600 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2, 0, 0, pbn_b1_4_921600 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, PCI_SUBVENDOR_ID_CONNECT_TECH, PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0, pbn_b1_2_921600 }, { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351, PCI_SUBVENDOR_ID_CONNECT_TECH,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -