cpqphp.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. /*
  2. * Compaq Hot Plug Controller Driver
  3. *
  4. * Copyright (C) 1995,2001 Compaq Computer Corporation
  5. * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
  6. * Copyright (C) 2001 IBM
  7. *
  8. * All rights reserved.
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or (at
  13. * your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful, but
  16. * WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  18. * NON INFRINGEMENT. See the GNU General Public License for more
  19. * details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24. *
  25. * Send feedback to <greg@kroah.com>
  26. *
  27. */
  28. #ifndef _CPQPHP_H
  29. #define _CPQPHP_H
  30. #include <linux/interrupt.h>
  31. #include <asm/io.h> /* for read? and write? functions */
  32. #include <linux/delay.h> /* for delays */
  33. #include <linux/mutex.h>
  34. #define MY_NAME "cpqphp"
  35. #define dbg(fmt, arg...) do { if (cpqhp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
  36. #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
  37. #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
  38. #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
  39. struct smbios_system_slot {
  40. u8 type;
  41. u8 length;
  42. u16 handle;
  43. u8 name_string_num;
  44. u8 slot_type;
  45. u8 slot_width;
  46. u8 slot_current_usage;
  47. u8 slot_length;
  48. u16 slot_number;
  49. u8 properties1;
  50. u8 properties2;
  51. } __attribute__ ((packed));
  52. /* offsets to the smbios generic type based on the above structure layout */
  53. enum smbios_system_slot_offsets {
  54. SMBIOS_SLOT_GENERIC_TYPE = offsetof(struct smbios_system_slot, type),
  55. SMBIOS_SLOT_GENERIC_LENGTH = offsetof(struct smbios_system_slot, length),
  56. SMBIOS_SLOT_GENERIC_HANDLE = offsetof(struct smbios_system_slot, handle),
  57. SMBIOS_SLOT_NAME_STRING_NUM = offsetof(struct smbios_system_slot, name_string_num),
  58. SMBIOS_SLOT_TYPE = offsetof(struct smbios_system_slot, slot_type),
  59. SMBIOS_SLOT_WIDTH = offsetof(struct smbios_system_slot, slot_width),
  60. SMBIOS_SLOT_CURRENT_USAGE = offsetof(struct smbios_system_slot, slot_current_usage),
  61. SMBIOS_SLOT_LENGTH = offsetof(struct smbios_system_slot, slot_length),
  62. SMBIOS_SLOT_NUMBER = offsetof(struct smbios_system_slot, slot_number),
  63. SMBIOS_SLOT_PROPERTIES1 = offsetof(struct smbios_system_slot, properties1),
  64. SMBIOS_SLOT_PROPERTIES2 = offsetof(struct smbios_system_slot, properties2),
  65. };
  66. struct smbios_generic {
  67. u8 type;
  68. u8 length;
  69. u16 handle;
  70. } __attribute__ ((packed));
  71. /* offsets to the smbios generic type based on the above structure layout */
  72. enum smbios_generic_offsets {
  73. SMBIOS_GENERIC_TYPE = offsetof(struct smbios_generic, type),
  74. SMBIOS_GENERIC_LENGTH = offsetof(struct smbios_generic, length),
  75. SMBIOS_GENERIC_HANDLE = offsetof(struct smbios_generic, handle),
  76. };
  77. struct smbios_entry_point {
  78. char anchor[4];
  79. u8 ep_checksum;
  80. u8 ep_length;
  81. u8 major_version;
  82. u8 minor_version;
  83. u16 max_size_entry;
  84. u8 ep_rev;
  85. u8 reserved[5];
  86. char int_anchor[5];
  87. u8 int_checksum;
  88. u16 st_length;
  89. u32 st_address;
  90. u16 number_of_entrys;
  91. u8 bcd_rev;
  92. } __attribute__ ((packed));
  93. /* offsets to the smbios entry point based on the above structure layout */
  94. enum smbios_entry_point_offsets {
  95. ANCHOR = offsetof(struct smbios_entry_point, anchor[0]),
  96. EP_CHECKSUM = offsetof(struct smbios_entry_point, ep_checksum),
  97. EP_LENGTH = offsetof(struct smbios_entry_point, ep_length),
  98. MAJOR_VERSION = offsetof(struct smbios_entry_point, major_version),
  99. MINOR_VERSION = offsetof(struct smbios_entry_point, minor_version),
  100. MAX_SIZE_ENTRY = offsetof(struct smbios_entry_point, max_size_entry),
  101. EP_REV = offsetof(struct smbios_entry_point, ep_rev),
  102. INT_ANCHOR = offsetof(struct smbios_entry_point, int_anchor[0]),
  103. INT_CHECKSUM = offsetof(struct smbios_entry_point, int_checksum),
  104. ST_LENGTH = offsetof(struct smbios_entry_point, st_length),
  105. ST_ADDRESS = offsetof(struct smbios_entry_point, st_address),
  106. NUMBER_OF_ENTRYS = offsetof(struct smbios_entry_point, number_of_entrys),
  107. BCD_REV = offsetof(struct smbios_entry_point, bcd_rev),
  108. };
  109. struct ctrl_reg { /* offset */
  110. u8 slot_RST; /* 0x00 */
  111. u8 slot_enable; /* 0x01 */
  112. u16 misc; /* 0x02 */
  113. u32 led_control; /* 0x04 */
  114. u32 int_input_clear; /* 0x08 */
  115. u32 int_mask; /* 0x0a */
  116. u8 reserved0; /* 0x10 */
  117. u8 reserved1; /* 0x11 */
  118. u8 reserved2; /* 0x12 */
  119. u8 gen_output_AB; /* 0x13 */
  120. u32 non_int_input; /* 0x14 */
  121. u32 reserved3; /* 0x18 */
  122. u32 reserved4; /* 0x1a */
  123. u32 reserved5; /* 0x20 */
  124. u8 reserved6; /* 0x24 */
  125. u8 reserved7; /* 0x25 */
  126. u16 reserved8; /* 0x26 */
  127. u8 slot_mask; /* 0x28 */
  128. u8 reserved9; /* 0x29 */
  129. u8 reserved10; /* 0x2a */
  130. u8 reserved11; /* 0x2b */
  131. u8 slot_SERR; /* 0x2c */
  132. u8 slot_power; /* 0x2d */
  133. u8 reserved12; /* 0x2e */
  134. u8 reserved13; /* 0x2f */
  135. u8 next_curr_freq; /* 0x30 */
  136. u8 reset_freq_mode; /* 0x31 */
  137. } __attribute__ ((packed));
  138. /* offsets to the controller registers based on the above structure layout */
  139. enum ctrl_offsets {
  140. SLOT_RST = offsetof(struct ctrl_reg, slot_RST),
  141. SLOT_ENABLE = offsetof(struct ctrl_reg, slot_enable),
  142. MISC = offsetof(struct ctrl_reg, misc),
  143. LED_CONTROL = offsetof(struct ctrl_reg, led_control),
  144. INT_INPUT_CLEAR = offsetof(struct ctrl_reg, int_input_clear),
  145. INT_MASK = offsetof(struct ctrl_reg, int_mask),
  146. CTRL_RESERVED0 = offsetof(struct ctrl_reg, reserved0),
  147. CTRL_RESERVED1 = offsetof(struct ctrl_reg, reserved1),
  148. CTRL_RESERVED2 = offsetof(struct ctrl_reg, reserved1),
  149. GEN_OUTPUT_AB = offsetof(struct ctrl_reg, gen_output_AB),
  150. NON_INT_INPUT = offsetof(struct ctrl_reg, non_int_input),
  151. CTRL_RESERVED3 = offsetof(struct ctrl_reg, reserved3),
  152. CTRL_RESERVED4 = offsetof(struct ctrl_reg, reserved4),
  153. CTRL_RESERVED5 = offsetof(struct ctrl_reg, reserved5),
  154. CTRL_RESERVED6 = offsetof(struct ctrl_reg, reserved6),
  155. CTRL_RESERVED7 = offsetof(struct ctrl_reg, reserved7),
  156. CTRL_RESERVED8 = offsetof(struct ctrl_reg, reserved8),
  157. SLOT_MASK = offsetof(struct ctrl_reg, slot_mask),
  158. CTRL_RESERVED9 = offsetof(struct ctrl_reg, reserved9),
  159. CTRL_RESERVED10 = offsetof(struct ctrl_reg, reserved10),
  160. CTRL_RESERVED11 = offsetof(struct ctrl_reg, reserved11),
  161. SLOT_SERR = offsetof(struct ctrl_reg, slot_SERR),
  162. SLOT_POWER = offsetof(struct ctrl_reg, slot_power),
  163. NEXT_CURR_FREQ = offsetof(struct ctrl_reg, next_curr_freq),
  164. RESET_FREQ_MODE = offsetof(struct ctrl_reg, reset_freq_mode),
  165. };
  166. struct hrt {
  167. char sig0;
  168. char sig1;
  169. char sig2;
  170. char sig3;
  171. u16 unused_IRQ;
  172. u16 PCIIRQ;
  173. u8 number_of_entries;
  174. u8 revision;
  175. u16 reserved1;
  176. u32 reserved2;
  177. } __attribute__ ((packed));
  178. /* offsets to the hotplug resource table registers based on the above
  179. * structure layout
  180. */
  181. enum hrt_offsets {
  182. SIG0 = offsetof(struct hrt, sig0),
  183. SIG1 = offsetof(struct hrt, sig1),
  184. SIG2 = offsetof(struct hrt, sig2),
  185. SIG3 = offsetof(struct hrt, sig3),
  186. UNUSED_IRQ = offsetof(struct hrt, unused_IRQ),
  187. PCIIRQ = offsetof(struct hrt, PCIIRQ),
  188. NUMBER_OF_ENTRIES = offsetof(struct hrt, number_of_entries),
  189. REVISION = offsetof(struct hrt, revision),
  190. HRT_RESERVED1 = offsetof(struct hrt, reserved1),
  191. HRT_RESERVED2 = offsetof(struct hrt, reserved2),
  192. };
  193. struct slot_rt {
  194. u8 dev_func;
  195. u8 primary_bus;
  196. u8 secondary_bus;
  197. u8 max_bus;
  198. u16 io_base;
  199. u16 io_length;
  200. u16 mem_base;
  201. u16 mem_length;
  202. u16 pre_mem_base;
  203. u16 pre_mem_length;
  204. } __attribute__ ((packed));
  205. /* offsets to the hotplug slot resource table registers based on the above
  206. * structure layout
  207. */
  208. enum slot_rt_offsets {
  209. DEV_FUNC = offsetof(struct slot_rt, dev_func),
  210. PRIMARY_BUS = offsetof(struct slot_rt, primary_bus),
  211. SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus),
  212. MAX_BUS = offsetof(struct slot_rt, max_bus),
  213. IO_BASE = offsetof(struct slot_rt, io_base),
  214. IO_LENGTH = offsetof(struct slot_rt, io_length),
  215. MEM_BASE = offsetof(struct slot_rt, mem_base),
  216. MEM_LENGTH = offsetof(struct slot_rt, mem_length),
  217. PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base),
  218. PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length),
  219. };
  220. struct pci_func {
  221. struct pci_func *next;
  222. u8 bus;
  223. u8 device;
  224. u8 function;
  225. u8 is_a_board;
  226. u16 status;
  227. u8 configured;
  228. u8 switch_save;
  229. u8 presence_save;
  230. u32 base_length[0x06];
  231. u8 base_type[0x06];
  232. u16 reserved2;
  233. u32 config_space[0x20];
  234. struct pci_resource *mem_head;
  235. struct pci_resource *p_mem_head;
  236. struct pci_resource *io_head;
  237. struct pci_resource *bus_head;
  238. struct timer_list *p_task_event;
  239. struct pci_dev* pci_dev;
  240. };
  241. struct slot {
  242. struct slot *next;
  243. u8 bus;
  244. u8 device;
  245. u8 number;
  246. u8 is_a_board;
  247. u8 configured;
  248. u8 state;
  249. u8 switch_save;
  250. u8 presence_save;
  251. u32 capabilities;
  252. u16 reserved2;
  253. struct timer_list task_event;
  254. u8 hp_slot;
  255. struct controller *ctrl;
  256. void __iomem *p_sm_slot;
  257. struct hotplug_slot *hotplug_slot;
  258. };
  259. struct pci_resource {
  260. struct pci_resource * next;
  261. u32 base;
  262. u32 length;
  263. };
  264. struct event_info {
  265. u32 event_type;
  266. u8 hp_slot;
  267. };
  268. struct controller {
  269. struct controller *next;
  270. u32 ctrl_int_comp;
  271. struct mutex crit_sect; /* critical section mutex */
  272. void __iomem *hpc_reg; /* cookie for our pci controller location */
  273. struct pci_resource *mem_head;
  274. struct pci_resource *p_mem_head;
  275. struct pci_resource *io_head;
  276. struct pci_resource *bus_head;
  277. struct pci_dev *pci_dev;
  278. struct pci_bus *pci_bus;
  279. struct event_info event_queue[10];
  280. struct slot *slot;
  281. u8 next_event;
  282. u8 interrupt;
  283. u8 cfgspc_irq;
  284. u8 bus; /* bus number for the pci hotplug controller */
  285. u8 rev;
  286. u8 slot_device_offset;
  287. u8 first_slot;
  288. u8 add_support;
  289. u8 push_flag;
  290. enum pci_bus_speed speed;
  291. enum pci_bus_speed speed_capability;
  292. u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */
  293. u8 slot_switch_type; /* 0 = no switch, 1 = switch present */
  294. u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */
  295. u8 alternate_base_address; /* 0 = not supported, 1 = supported */
  296. u8 pci_config_space; /* Index/data access to working registers 0 = not supported, 1 = supported */
  297. u8 pcix_speed_capability; /* PCI-X */
  298. u8 pcix_support; /* PCI-X */
  299. u16 vendor_id;
  300. struct work_struct int_task_event;
  301. wait_queue_head_t queue; /* sleep & wake process */
  302. struct dentry *dentry; /* debugfs dentry */
  303. };
  304. struct irq_mapping {
  305. u8 barber_pole;
  306. u8 valid_INT;
  307. u8 interrupt[4];
  308. };
  309. struct resource_lists {
  310. struct pci_resource *mem_head;
  311. struct pci_resource *p_mem_head;
  312. struct pci_resource *io_head;
  313. struct pci_resource *bus_head;
  314. struct irq_mapping *irqs;
  315. };
  316. #define ROM_PHY_ADDR 0x0F0000
  317. #define ROM_PHY_LEN 0x00ffff
  318. #define PCI_HPC_ID 0xA0F7
  319. #define PCI_SUB_HPC_ID 0xA2F7
  320. #define PCI_SUB_HPC_ID2 0xA2F8
  321. #define PCI_SUB_HPC_ID3 0xA2F9
  322. #define PCI_SUB_HPC_ID_INTC 0xA2FA
  323. #define PCI_SUB_HPC_ID4 0xA2FD
  324. #define INT_BUTTON_IGNORE 0
  325. #define INT_PRESENCE_ON 1
  326. #define INT_PRESENCE_OFF 2
  327. #define INT_SWITCH_CLOSE 3
  328. #define INT_SWITCH_OPEN 4
  329. #define INT_POWER_FAULT 5
  330. #define INT_POWER_FAULT_CLEAR 6
  331. #define INT_BUTTON_PRESS 7
  332. #define INT_BUTTON_RELEASE 8
  333. #define INT_BUTTON_CANCEL 9
  334. #define STATIC_STATE 0
  335. #define BLINKINGON_STATE 1
  336. #define BLINKINGOFF_STATE 2
  337. #define POWERON_STATE 3
  338. #define POWEROFF_STATE 4
  339. #define PCISLOT_INTERLOCK_CLOSED 0x00000001
  340. #define PCISLOT_ADAPTER_PRESENT 0x00000002
  341. #define PCISLOT_POWERED 0x00000004
  342. #define PCISLOT_66_MHZ_OPERATION 0x00000008
  343. #define PCISLOT_64_BIT_OPERATION 0x00000010
  344. #define PCISLOT_REPLACE_SUPPORTED 0x00000020
  345. #define PCISLOT_ADD_SUPPORTED 0x00000040
  346. #define PCISLOT_INTERLOCK_SUPPORTED 0x00000080
  347. #define PCISLOT_66_MHZ_SUPPORTED 0x00000100
  348. #define PCISLOT_64_BIT_SUPPORTED 0x00000200
  349. #define PCI_TO_PCI_BRIDGE_CLASS 0x00060400
  350. #define INTERLOCK_OPEN 0x00000002
  351. #define ADD_NOT_SUPPORTED 0x00000003
  352. #define CARD_FUNCTIONING 0x00000005
  353. #define ADAPTER_NOT_SAME 0x00000006
  354. #define NO_ADAPTER_PRESENT 0x00000009
  355. #define NOT_ENOUGH_RESOURCES 0x0000000B
  356. #define DEVICE_TYPE_NOT_SUPPORTED 0x0000000C
  357. #define POWER_FAILURE 0x0000000E
  358. #define REMOVE_NOT_SUPPORTED 0x00000003
  359. /*
  360. * error Messages
  361. */
  362. #define msg_initialization_err "Initialization failure, error=%d\n"
  363. #define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"
  364. #define msg_HPC_non_compaq_or_intel "The PCI hot plug controller is not supported by this driver.\n"
  365. #define msg_HPC_not_supported "this system is not supported by this version of cpqphpd. Upgrade to a newer version of cpqphpd\n"
  366. #define msg_unable_to_save "unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
  367. #define msg_button_on "PCI slot #%d - powering on due to button press.\n"
  368. #define msg_button_off "PCI slot #%d - powering off due to button press.\n"
  369. #define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"
  370. #define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"
  371. /* debugfs functions for the hotplug controller info */
  372. extern void cpqhp_initialize_debugfs(void);
  373. extern void cpqhp_shutdown_debugfs(void);
  374. extern void cpqhp_create_debugfs_files(struct controller *ctrl);
  375. extern void cpqhp_remove_debugfs_files(struct controller *ctrl);
  376. /* controller functions */
  377. extern void cpqhp_pushbutton_thread(unsigned long event_pointer);
  378. extern irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data);
  379. extern int cpqhp_find_available_resources(struct controller *ctrl,
  380. void __iomem *rom_start);
  381. extern int cpqhp_event_start_thread(void);
  382. extern void cpqhp_event_stop_thread(void);
  383. extern struct pci_func *cpqhp_slot_create(unsigned char busnumber);
  384. extern struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device,
  385. unsigned char index);
  386. extern int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func);
  387. extern int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func);
  388. extern int cpqhp_hardware_test(struct controller *ctrl, int test_num);
  389. /* resource functions */
  390. extern int cpqhp_resource_sort_and_combine (struct pci_resource **head);
  391. /* pci functions */
  392. extern int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
  393. extern int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num,
  394. u8 slot);
  395. extern int cpqhp_save_config(struct controller *ctrl, int busnumber,
  396. int is_hot_plug);
  397. extern int cpqhp_save_base_addr_length(struct controller *ctrl,
  398. struct pci_func *func);
  399. extern int cpqhp_save_used_resources(struct controller *ctrl,
  400. struct pci_func *func);
  401. extern int cpqhp_configure_board(struct controller *ctrl,
  402. struct pci_func *func);
  403. extern int cpqhp_save_slot_config(struct controller *ctrl,
  404. struct pci_func *new_slot);
  405. extern int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func);
  406. extern void cpqhp_destroy_board_resources(struct pci_func *func);
  407. extern int cpqhp_return_board_resources (struct pci_func *func,
  408. struct resource_lists *resources);
  409. extern void cpqhp_destroy_resource_list(struct resource_lists *resources);
  410. extern int cpqhp_configure_device(struct controller *ctrl,
  411. struct pci_func *func);
  412. extern int cpqhp_unconfigure_device(struct pci_func *func);
  413. /* Global variables */
  414. extern int cpqhp_debug;
  415. extern int cpqhp_legacy_mode;
  416. extern struct controller *cpqhp_ctrl_list;
  417. extern struct pci_func *cpqhp_slot_list[256];
  418. extern struct irq_routing_table *cpqhp_routing_table;
  419. /* these can be gotten rid of, but for debugging they are purty */
  420. extern u8 cpqhp_nic_irq;
  421. extern u8 cpqhp_disk_irq;
  422. /* inline functions */
  423. static inline const char *slot_name(struct slot *slot)
  424. {
  425. return hotplug_slot_name(slot->hotplug_slot);
  426. }
  427. /*
  428. * return_resource
  429. *
  430. * Puts node back in the resource list pointed to by head
  431. */
  432. static inline void return_resource(struct pci_resource **head,
  433. struct pci_resource *node)
  434. {
  435. if (!node || !head)
  436. return;
  437. node->next = *head;
  438. *head = node;
  439. }
  440. static inline void set_SOGO(struct controller *ctrl)
  441. {
  442. u16 misc;
  443. misc = readw(ctrl->hpc_reg + MISC);
  444. misc = (misc | 0x0001) & 0xFFFB;
  445. writew(misc, ctrl->hpc_reg + MISC);
  446. }
  447. static inline void amber_LED_on(struct controller *ctrl, u8 slot)
  448. {
  449. u32 led_control;
  450. led_control = readl(ctrl->hpc_reg + LED_CONTROL);
  451. led_control |= (0x01010000L << slot);
  452. writel(led_control, ctrl->hpc_reg + LED_CONTROL);
  453. }
  454. static inline void amber_LED_off(struct controller *ctrl, u8 slot)
  455. {
  456. u32 led_control;
  457. led_control = readl(ctrl->hpc_reg + LED_CONTROL);
  458. led_control &= ~(0x01010000L << slot);
  459. writel(led_control, ctrl->hpc_reg + LED_CONTROL);
  460. }
  461. static inline int read_amber_LED(struct controller *ctrl, u8 slot)
  462. {
  463. u32 led_control;
  464. led_control = readl(ctrl->hpc_reg + LED_CONTROL);
  465. led_control &= (0x01010000L << slot);
  466. return led_control ? 1 : 0;
  467. }
  468. static inline void green_LED_on(struct controller *ctrl, u8 slot)
  469. {
  470. u32 led_control;
  471. led_control = readl(ctrl->hpc_reg + LED_CONTROL);
  472. led_control |= 0x0101L << slot;
  473. writel(led_control, ctrl->hpc_reg + LED_CONTROL);
  474. }
  475. static inline void green_LED_off(struct controller *ctrl, u8 slot)
  476. {
  477. u32 led_control;
  478. led_control = readl(ctrl->hpc_reg + LED_CONTROL);
  479. led_control &= ~(0x0101L << slot);
  480. writel(led_control, ctrl->hpc_reg + LED_CONTROL);
  481. }
  482. static inline void green_LED_blink(struct controller *ctrl, u8 slot)
  483. {
  484. u32 led_control;
  485. led_control = readl(ctrl->hpc_reg + LED_CONTROL);
  486. led_control &= ~(0x0101L << slot);
  487. led_control |= (0x0001L << slot);
  488. writel(led_control, ctrl->hpc_reg + LED_CONTROL);
  489. }
  490. static inline void slot_disable(struct controller *ctrl, u8 slot)
  491. {
  492. u8 slot_enable;
  493. slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
  494. slot_enable &= ~(0x01 << slot);
  495. writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
  496. }
  497. static inline void slot_enable(struct controller *ctrl, u8 slot)
  498. {
  499. u8 slot_enable;
  500. slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
  501. slot_enable |= (0x01 << slot);
  502. writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
  503. }
  504. static inline u8 is_slot_enabled(struct controller *ctrl, u8 slot)
  505. {
  506. u8 slot_enable;
  507. slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
  508. slot_enable &= (0x01 << slot);
  509. return slot_enable ? 1 : 0;
  510. }
  511. static inline u8 read_slot_enable(struct controller *ctrl)
  512. {
  513. return readb(ctrl->hpc_reg + SLOT_ENABLE);
  514. }
  515. /**
  516. * get_controller_speed - find the current frequency/mode of controller.
  517. *
  518. * @ctrl: controller to get frequency/mode for.
  519. *
  520. * Returns controller speed.
  521. */
  522. static inline u8 get_controller_speed(struct controller *ctrl)
  523. {
  524. u8 curr_freq;
  525. u16 misc;
  526. if (ctrl->pcix_support) {
  527. curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ);
  528. if ((curr_freq & 0xB0) == 0xB0)
  529. return PCI_SPEED_133MHz_PCIX;
  530. if ((curr_freq & 0xA0) == 0xA0)
  531. return PCI_SPEED_100MHz_PCIX;
  532. if ((curr_freq & 0x90) == 0x90)
  533. return PCI_SPEED_66MHz_PCIX;
  534. if (curr_freq & 0x10)
  535. return PCI_SPEED_66MHz;
  536. return PCI_SPEED_33MHz;
  537. }
  538. misc = readw(ctrl->hpc_reg + MISC);
  539. return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
  540. }
  541. /**
  542. * get_adapter_speed - find the max supported frequency/mode of adapter.
  543. *
  544. * @ctrl: hotplug controller.
  545. * @hp_slot: hotplug slot where adapter is installed.
  546. *
  547. * Returns adapter speed.
  548. */
  549. static inline u8 get_adapter_speed(struct controller *ctrl, u8 hp_slot)
  550. {
  551. u32 temp_dword = readl(ctrl->hpc_reg + NON_INT_INPUT);
  552. dbg("slot: %d, PCIXCAP: %8x\n", hp_slot, temp_dword);
  553. if (ctrl->pcix_support) {
  554. if (temp_dword & (0x10000 << hp_slot))
  555. return PCI_SPEED_133MHz_PCIX;
  556. if (temp_dword & (0x100 << hp_slot))
  557. return PCI_SPEED_66MHz_PCIX;
  558. }
  559. if (temp_dword & (0x01 << hp_slot))
  560. return PCI_SPEED_66MHz;
  561. return PCI_SPEED_33MHz;
  562. }
  563. static inline void enable_slot_power(struct controller *ctrl, u8 slot)
  564. {
  565. u8 slot_power;
  566. slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
  567. slot_power |= (0x01 << slot);
  568. writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
  569. }
  570. static inline void disable_slot_power(struct controller *ctrl, u8 slot)
  571. {
  572. u8 slot_power;
  573. slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
  574. slot_power &= ~(0x01 << slot);
  575. writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
  576. }
  577. static inline int cpq_get_attention_status(struct controller *ctrl, struct slot *slot)
  578. {
  579. u8 hp_slot;
  580. hp_slot = slot->device - ctrl->slot_device_offset;
  581. return read_amber_LED(ctrl, hp_slot);
  582. }
  583. static inline int get_slot_enabled(struct controller *ctrl, struct slot *slot)
  584. {
  585. u8 hp_slot;
  586. hp_slot = slot->device - ctrl->slot_device_offset;
  587. return is_slot_enabled(ctrl, hp_slot);
  588. }
  589. static inline int cpq_get_latch_status(struct controller *ctrl,
  590. struct slot *slot)
  591. {
  592. u32 status;
  593. u8 hp_slot;
  594. hp_slot = slot->device - ctrl->slot_device_offset;
  595. dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d \n",
  596. __func__, slot->device, ctrl->slot_device_offset);
  597. status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot));
  598. return(status == 0) ? 1 : 0;
  599. }
  600. static inline int get_presence_status(struct controller *ctrl,
  601. struct slot *slot)
  602. {
  603. int presence_save = 0;
  604. u8 hp_slot;
  605. u32 tempdword;
  606. hp_slot = slot->device - ctrl->slot_device_offset;
  607. tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
  608. presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15))
  609. >> hp_slot) & 0x02;
  610. return presence_save;
  611. }
  612. static inline int wait_for_ctrl_irq(struct controller *ctrl)
  613. {
  614. DECLARE_WAITQUEUE(wait, current);
  615. int retval = 0;
  616. dbg("%s - start\n", __func__);
  617. add_wait_queue(&ctrl->queue, &wait);
  618. /* Sleep for up to 1 second to wait for the LED to change. */
  619. msleep_interruptible(1000);
  620. remove_wait_queue(&ctrl->queue, &wait);
  621. if (signal_pending(current))
  622. retval = -EINTR;
  623. dbg("%s - end\n", __func__);
  624. return retval;
  625. }
  626. #include <asm/pci_x86.h>
  627. static inline int cpqhp_routing_table_length(void)
  628. {
  629. BUG_ON(cpqhp_routing_table == NULL);
  630. return ((cpqhp_routing_table->size - sizeof(struct irq_routing_table)) /
  631. sizeof(struct irq_info));
  632. }
  633. #endif