hcdp_serial.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:7k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/char/hcdp_serial.c
  3.  *
  4.  *  Copyright (C) 2002  Hewlett-Packard Co.
  5.  *  Copyright (C) 2002  Khalid Aziz <khalid_aziz@hp.com>
  6.  *
  7.  *  Parse the EFI HCDP table to locate serial console and debug ports
  8.  *  and initialize them
  9.  *
  10.  */
  11. #include <linux/kernel.h>
  12. #include <linux/types.h>
  13. #include <linux/pci.h>
  14. #include <linux/pm.h>
  15. #include <linux/init.h>
  16. #include <linux/serial.h>
  17. #include <linux/serialP.h>
  18. #include <linux/efi.h>
  19. #include <asm/serial.h>
  20. #include <asm/io.h>
  21. #include <linux/hcdp_serial.h>
  22. #undef SERIAL_DEBUG_HCDP
  23. extern struct serial_state rs_table[];
  24. extern int serial_nr_ports;
  25. /*
  26.  * Parse the HCDP table to find descriptions for headless console and 
  27.  * debug serial ports and add them to rs_table[]. A pointer to HCDP
  28.  * table is passed as parameter. This function should be called 
  29.  * before serial_console_init() is called to make sure the HCDP serial 
  30.  * console will be available for use. IA-64 kernel calls this function
  31.  * from setup_arch() after the EFI and ACPI tables have been parsed.
  32.  */
  33. void __init setup_serial_hcdp(void *tablep) 
  34. {
  35. hcdp_t hcdp;
  36. hcdp_dev_t *hcdp_dev;
  37. struct serial_struct serial_req;
  38. unsigned long iobase;
  39. int global_sys_irq;
  40. int i, nr;
  41. int shift_once = 1;
  42. #ifdef SERIAL_DEBUG_HCDP
  43. printk("Entering setup_serial_hcdp()n");
  44. #endif
  45. /* Verify we have a valid table pointer */
  46. if (tablep == NULL) {
  47. return;
  48. }
  49. /*
  50.  * We do not trust firmware to give us a table starting at an
  51.  * aligned address. Make a local copy of the HCDP table with 
  52.  * aligned structures.
  53.  */
  54. memcpy(&hcdp, tablep, sizeof(hcdp));
  55. /*
  56.  * Perform a sanity check on the table. Table should have a 
  57.  * signature of "HCDP" and it should be atleast 82 bytes
  58.  * long to have any useful information.
  59.  */
  60. if ((strncmp(hcdp.signature, HCDP_SIGNATURE, 
  61. HCDP_SIG_LEN) != 0)) {
  62. return;
  63. }
  64. if (hcdp.len < 82) {
  65. return;
  66. }
  67. #ifdef SERIAL_DEBUG_HCDP
  68. printk("setup_serial_hcdp(): table pointer = 0x%pn", tablep);
  69. printk("                     sig = '%c%c%c%c'n",
  70. hcdp.signature[0],
  71. hcdp.signature[1],
  72. hcdp.signature[2],
  73. hcdp.signature[3]);
  74. printk("                     length = %dn", hcdp.len);
  75. printk("                     Rev = %dn", hcdp.rev);
  76. printk("                     OEM ID = %c%c%c%c%c%cn", 
  77. hcdp.oemid[0], hcdp.oemid[1], hcdp.oemid[2],
  78. hcdp.oemid[3], hcdp.oemid[4], hcdp.oemid[5]);
  79. printk("                     Number of entries = %dn", hcdp.num_entries);
  80. #endif
  81. /*
  82.  * Parse each device entry
  83.  */
  84. for (nr=0; nr<hcdp.num_entries; nr++) {
  85. hcdp_dev = &(hcdp.hcdp_dev[nr]);
  86. /*
  87.  * We will parse only the primary console device
  88.  * which is the first entry for these devices. We will
  89.  * ignore rest of the entries for the same type device that
  90.  * has already been parsed and initialized
  91.  */
  92. if (hcdp_dev->type != HCDP_DEV_CONSOLE)
  93. continue;
  94. iobase = (u64)(hcdp_dev->base_addr.addrhi)<<32 | hcdp_dev->base_addr.addrlo;
  95. global_sys_irq = hcdp_dev->global_int;
  96. #ifdef SERIAL_DEBUG_HCDP
  97. printk("                 type = %sn", 
  98. ((hcdp_dev->type == HCDP_DEV_CONSOLE)?"Headless Console":((hcdp_dev->type == HCDP_DEV_DEBUG)?"Debug port":"Huh????")));
  99. printk("                 Base address space = %sn", ((hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE)?"Memory Space":((hcdp_dev->base_addr.space_id == ACPI_IO_SPACE)?"I/O space":"PCI space")));
  100. printk("                 Base address = 0x%pn", iobase);
  101. printk("                 Global System Int = %dn", global_sys_irq);
  102. printk("                 Baud rate = %dn", hcdp_dev->baud);
  103. printk("                 Bits = %dn", hcdp_dev->bits);
  104. printk("                 Clock rate = %dn", hcdp_dev->clock_rate);
  105. if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE) {
  106. printk("                     PCI serial port:n");
  107. printk("                         Bus %d, Device %d, Vendor ID 0x%x, Dev ID 0x%xn",
  108. hcdp_dev->pci_bus, hcdp_dev->pci_dev,
  109. hcdp_dev->pci_vendor_id, hcdp_dev->pci_dev_id);
  110. }
  111. #endif
  112. /* 
  113.   * Now build a serial_req structure to update the entry in
  114.   * rs_table for the headless console port.
  115.   */
  116. if (hcdp_dev->clock_rate)
  117. serial_req.baud_base = hcdp_dev->clock_rate;
  118. else
  119. serial_req.baud_base = DEFAULT_BAUD_BASE;
  120. /*
  121.   * Check if this is an I/O mapped address or a memory mapped address
  122.   */
  123. if (hcdp_dev->base_addr.space_id == ACPI_MEM_SPACE) {
  124. serial_req.port = 0;
  125. serial_req.port_high = 0;
  126. serial_req.iomem_base = (void *)ioremap(iobase, 64);
  127. serial_req.io_type = SERIAL_IO_MEM;
  128. }
  129. else if (hcdp_dev->base_addr.space_id == ACPI_IO_SPACE) {
  130. serial_req.port = (unsigned long) iobase & 0xffffffff;
  131. serial_req.port_high = (unsigned long)(((u64)iobase) >> 32);
  132. serial_req.iomem_base = NULL;
  133. serial_req.io_type = SERIAL_IO_PORT;
  134. }
  135. else if (hcdp_dev->base_addr.space_id == ACPI_PCICONF_SPACE) {
  136. printk("WARNING: No support for PCI serial consolen");
  137. return;
  138. }
  139. /*
  140.  * Check if HCDP defines a port already in rs_table
  141.  */
  142. for (i = 0; i < serial_nr_ports; i++) {
  143. if ((rs_table[i].port == serial_req.port) &&
  144. (rs_table[i].iomem_base==serial_req.iomem_base))
  145. break;
  146. }
  147. if (i == serial_nr_ports) {
  148. /*
  149.  * We have reserved a slot for HCDP defined console
  150.  * port at HCDP_SERIAL_CONSOLE_PORT in rs_table
  151.  * which is not 0. This means using this slot would
  152.  * put the console at a device other than ttyS0. 
  153.  * Users expect to see the console at ttyS0. Now 
  154.  * that we have determined HCDP does describe a 
  155.  * serial console and it is not one of the compiled
  156.  * in ports, let us move the entries in rs_table
  157.  * up by a slot towards HCDP_SERIAL_CONSOLE_PORT to 
  158.  * make room for the HCDP console at ttyS0. We may go
  159.  * through this loop more than once if 
  160.  * early_serial_setup() fails. Make sure we shift the
  161.  * entries in rs_table only once.
  162.  */
  163. if (shift_once) {
  164. int j;
  165. for (j=HCDP_SERIAL_CONSOLE_PORT; j>0; j--)
  166. memcpy(rs_table+j, rs_table+j-1, 
  167. sizeof(struct serial_state));
  168. shift_once = 0;
  169. }
  170. serial_req.line = 0;
  171. }
  172. else
  173. serial_req.line = i;
  174. /*
  175.   * If the table does not have IRQ information, use 0 for IRQ. 
  176.   * This will force rs_init() to probe for IRQ. 
  177.   */
  178. serial_req.irq = global_sys_irq;
  179. if (global_sys_irq == 0) {
  180. serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF;
  181. }
  182. else {
  183. serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF|
  184. ASYNC_AUTO_IRQ;
  185. }
  186. serial_req.xmit_fifo_size = serial_req.custom_divisor = 0;
  187. serial_req.close_delay = serial_req.hub6 = serial_req.closing_wait = 0;
  188. serial_req.iomem_reg_shift = 0;
  189. if (early_serial_setup(&serial_req) < 0) {
  190. printk("setup_serial_hcdp(): early_serial_setup() for HCDP serial console port failed. Will try any additional consoles in HCDP.n");
  191. continue;
  192. }
  193. else
  194. if (hcdp_dev->type == HCDP_DEV_CONSOLE)
  195. break;
  196. #ifdef SERIAL_DEBUG_HCDP
  197. printk("n");
  198. #endif
  199. }
  200. #ifdef SERIAL_DEBUG_HCDP
  201. printk("Leaving setup_serial_hcdp()n");
  202. #endif
  203. }