ide-pnp.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/drivers/ide/ide-pnp.c
  3.  *
  4.  * This file provides autodetection for ISA PnP IDE interfaces.
  5.  * It was tested with "ESS ES1868 Plug and Play AudioDrive" IDE interface.
  6.  *
  7.  * Copyright (C) 2000 Andrey Panin <pazke@orbita.don.sitek.net>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * (for example /usr/src/linux/COPYING); if not, write to the Free
  16.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
  17.  */
  18. #include <linux/ide.h>
  19. #include <linux/init.h>
  20. #include <linux/isapnp.h>
  21. #ifndef PREPARE_FUNC
  22. #define PREPARE_FUNC(dev)  (dev->prepare)
  23. #define ACTIVATE_FUNC(dev)  (dev->activate)
  24. #define DEACTIVATE_FUNC(dev)  (dev->deactivate)
  25. #endif
  26. #define DEV_IO(dev, index) (dev->resource[index].start)
  27. #define DEV_IRQ(dev, index) (dev->irq_resource[index].start)
  28. #define DEV_NAME(dev) (dev->bus->name ? dev->bus->name : "ISA PnP")
  29. #define GENERIC_HD_DATA 0
  30. #define GENERIC_HD_ERROR 1
  31. #define GENERIC_HD_NSECTOR 2
  32. #define GENERIC_HD_SECTOR 3
  33. #define GENERIC_HD_LCYL 4
  34. #define GENERIC_HD_HCYL 5
  35. #define GENERIC_HD_SELECT 6
  36. #define GENERIC_HD_STATUS 7
  37. static int generic_ide_offsets[IDE_NR_PORTS] __initdata = {
  38. GENERIC_HD_DATA, GENERIC_HD_ERROR, GENERIC_HD_NSECTOR, 
  39. GENERIC_HD_SECTOR, GENERIC_HD_LCYL, GENERIC_HD_HCYL,
  40. GENERIC_HD_SELECT, GENERIC_HD_STATUS, -1, -1
  41. };
  42. /* ISA PnP device table entry */
  43. struct pnp_dev_t {
  44. unsigned short card_vendor, card_device, vendor, device;
  45. int (*init_fn)(struct pci_dev *dev, int enable);
  46. };
  47. /* Generic initialisation function for ISA PnP IDE interface */
  48. static int __init pnpide_generic_init(struct pci_dev *dev, int enable)
  49. {
  50. hw_regs_t hw;
  51. int index;
  52. if (!enable)
  53. return 0;
  54. if (!(DEV_IO(dev, 0) && DEV_IO(dev, 1) && DEV_IRQ(dev, 0)))
  55. return 1;
  56. ide_setup_ports(&hw, (ide_ioreg_t) DEV_IO(dev, 0),
  57. generic_ide_offsets, (ide_ioreg_t) DEV_IO(dev, 1),
  58. 0, NULL, DEV_IRQ(dev, 0));
  59. index = ide_register_hw(&hw, NULL);
  60. if (index != -1) {
  61.      printk("ide%d: %s IDE interfacen", index, DEV_NAME(dev));
  62. return 0;
  63. }
  64. return 1;
  65. }
  66. /* Add your devices here :)) */
  67. struct pnp_dev_t idepnp_devices[] __initdata = {
  68.    /* Generic ESDI/IDE/ATA compatible hard disk controller */
  69. { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
  70. ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0600),
  71. pnpide_generic_init },
  72. { 0 }
  73. };
  74. #ifdef MODULE
  75. #define NR_PNP_DEVICES 8
  76. struct pnp_dev_inst {
  77. struct pci_dev *dev;
  78. struct pnp_dev_t *dev_type;
  79. };
  80. static struct pnp_dev_inst devices[NR_PNP_DEVICES];
  81. static int pnp_ide_dev_idx = 0;
  82. #endif
  83. /*
  84.  * Probe for ISA PnP IDE interfaces.
  85.  */
  86. void __init pnpide_init(int enable)
  87. {
  88. struct pci_dev *dev = NULL;
  89. struct pnp_dev_t *dev_type;
  90. if (!isapnp_present())
  91. return;
  92. #ifdef MODULE
  93. /* Module unload, deactivate all registered devices. */
  94. if (!enable) {
  95. int i;
  96. for (i = 0; i < pnp_ide_dev_idx; i++) {
  97. devices[i].dev_type->init_fn(dev, 0);
  98. if (DEACTIVATE_FUNC(devices[i].dev))
  99. DEACTIVATE_FUNC(devices[i].dev)(devices[i].dev);
  100. }
  101. return;
  102. }
  103. #endif
  104. for (dev_type = idepnp_devices; dev_type->vendor; dev_type++) {
  105. while ((dev = isapnp_find_dev(NULL, dev_type->vendor,
  106. dev_type->device, dev))) {
  107. if (dev->active)
  108. continue;
  109.         if (PREPARE_FUNC(dev) && (PREPARE_FUNC(dev))(dev) < 0) {
  110. printk("ide: %s prepare failedn", DEV_NAME(dev));
  111. continue;
  112. }
  113. if (ACTIVATE_FUNC(dev) && (ACTIVATE_FUNC(dev))(dev) < 0) {
  114. printk("ide: %s activate failedn", DEV_NAME(dev));
  115. continue;
  116. }
  117. /* Call device initialization function */
  118. if (dev_type->init_fn(dev, 1)) {
  119. if (DEACTIVATE_FUNC(dev))
  120. DEACTIVATE_FUNC(dev)(dev);
  121. } else {
  122. #ifdef MODULE
  123. /*
  124.  * Register device in the array to
  125.  * deactivate it on a module unload.
  126.  */
  127. if (pnp_ide_dev_idx >= NR_PNP_DEVICES)
  128. return;
  129. devices[pnp_ide_dev_idx].dev = dev;
  130. devices[pnp_ide_dev_idx].dev_type = dev_type;
  131. pnp_ide_dev_idx++;
  132. #endif
  133. }
  134. }
  135. }
  136. }