ibmphp_core.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * IBM Hot Plug Controller Driver
  4. *
  5. * Written By: Chuck Cole, Jyoti Shah, Tong Yu, Irene Zubarev, IBM Corporation
  6. *
  7. * Copyright (C) 2001,2003 Greg Kroah-Hartman (greg@kroah.com)
  8. * Copyright (C) 2001-2003 IBM Corp.
  9. *
  10. * All rights reserved.
  11. *
  12. * Send feedback to <gregkh@us.ibm.com>
  13. *
  14. */
  15. #include <linux/init.h>
  16. #include <linux/module.h>
  17. #include <linux/slab.h>
  18. #include <linux/pci.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/delay.h>
  21. #include <linux/wait.h>
  22. #include "../pci.h"
  23. #include <asm/pci_x86.h> /* for struct irq_routing_table */
  24. #include <asm/io_apic.h>
  25. #include "ibmphp.h"
  26. #define attn_on(sl) ibmphp_hpc_writeslot(sl, HPC_SLOT_ATTNON)
  27. #define attn_off(sl) ibmphp_hpc_writeslot(sl, HPC_SLOT_ATTNOFF)
  28. #define attn_LED_blink(sl) ibmphp_hpc_writeslot(sl, HPC_SLOT_BLINKLED)
  29. #define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot(sl, READ_REVLEVEL, rev)
  30. #define get_hpc_options(sl, opt) ibmphp_hpc_readslot(sl, READ_HPCOPTIONS, opt)
  31. #define DRIVER_VERSION "0.6"
  32. #define DRIVER_DESC "IBM Hot Plug PCI Controller Driver"
  33. int ibmphp_debug;
  34. static bool debug;
  35. module_param(debug, bool, S_IRUGO | S_IWUSR);
  36. MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
  37. MODULE_LICENSE("GPL");
  38. MODULE_DESCRIPTION(DRIVER_DESC);
  39. struct pci_bus *ibmphp_pci_bus;
  40. static int max_slots;
  41. static int irqs[16]; /* PIC mode IRQs we're using so far (in case MPS
  42. * tables don't provide default info for empty slots */
  43. static int init_flag;
  44. /*
  45. static int get_max_adapter_speed_1 (struct hotplug_slot *, u8 *, u8);
  46. static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)
  47. {
  48. return get_max_adapter_speed_1 (hs, value, 1);
  49. }
  50. */
  51. static inline int get_cur_bus_info(struct slot **sl)
  52. {
  53. int rc = 1;
  54. struct slot *slot_cur = *sl;
  55. debug("options = %x\n", slot_cur->ctrl->options);
  56. debug("revision = %x\n", slot_cur->ctrl->revision);
  57. if (READ_BUS_STATUS(slot_cur->ctrl))
  58. rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL);
  59. if (rc)
  60. return rc;
  61. slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);
  62. if (READ_BUS_MODE(slot_cur->ctrl))
  63. slot_cur->bus_on->current_bus_mode =
  64. CURRENT_BUS_MODE(slot_cur->busstatus);
  65. else
  66. slot_cur->bus_on->current_bus_mode = 0xFF;
  67. debug("busstatus = %x, bus_speed = %x, bus_mode = %x\n",
  68. slot_cur->busstatus,
  69. slot_cur->bus_on->current_speed,
  70. slot_cur->bus_on->current_bus_mode);
  71. *sl = slot_cur;
  72. return 0;
  73. }
  74. static inline int slot_update(struct slot **sl)
  75. {
  76. int rc;
  77. rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL);
  78. if (rc)
  79. return rc;
  80. if (!init_flag)
  81. rc = get_cur_bus_info(sl);
  82. return rc;
  83. }
  84. static int __init get_max_slots(void)
  85. {
  86. struct slot *slot_cur;
  87. u8 slot_count = 0;
  88. list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
  89. /* sometimes the hot-pluggable slots start with 4 (not always from 1) */
  90. slot_count = max(slot_count, slot_cur->number);
  91. }
  92. return slot_count;
  93. }
  94. /* This routine will put the correct slot->device information per slot. It's
  95. * called from initialization of the slot structures. It will also assign
  96. * interrupt numbers per each slot.
  97. * Parameters: struct slot
  98. * Returns 0 or errors
  99. */
  100. int ibmphp_init_devno(struct slot **cur_slot)
  101. {
  102. struct irq_routing_table *rtable;
  103. int len;
  104. int loop;
  105. int i;
  106. rtable = pcibios_get_irq_routing_table();
  107. if (!rtable) {
  108. err("no BIOS routing table...\n");
  109. return -ENOMEM;
  110. }
  111. len = (rtable->size - sizeof(struct irq_routing_table)) /
  112. sizeof(struct irq_info);
  113. if (!len) {
  114. kfree(rtable);
  115. return -1;
  116. }
  117. for (loop = 0; loop < len; loop++) {
  118. if ((*cur_slot)->number == rtable->slots[loop].slot &&
  119. (*cur_slot)->bus == rtable->slots[loop].bus) {
  120. (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn);
  121. for (i = 0; i < 4; i++)
  122. (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus,
  123. (int) (*cur_slot)->device, i);
  124. debug("(*cur_slot)->irq[0] = %x\n",
  125. (*cur_slot)->irq[0]);
  126. debug("(*cur_slot)->irq[1] = %x\n",
  127. (*cur_slot)->irq[1]);
  128. debug("(*cur_slot)->irq[2] = %x\n",
  129. (*cur_slot)->irq[2]);
  130. debug("(*cur_slot)->irq[3] = %x\n",
  131. (*cur_slot)->irq[3]);
  132. debug("rtable->exclusive_irqs = %x\n",
  133. rtable->exclusive_irqs);
  134. debug("rtable->slots[loop].irq[0].bitmap = %x\n",
  135. rtable->slots[loop].irq[0].bitmap);
  136. debug("rtable->slots[loop].irq[1].bitmap = %x\n",
  137. rtable->slots[loop].irq[1].bitmap);
  138. debug("rtable->slots[loop].irq[2].bitmap = %x\n",
  139. rtable->slots[loop].irq[2].bitmap);
  140. debug("rtable->slots[loop].irq[3].bitmap = %x\n",
  141. rtable->slots[loop].irq[3].bitmap);
  142. debug("rtable->slots[loop].irq[0].link = %x\n",
  143. rtable->slots[loop].irq[0].link);
  144. debug("rtable->slots[loop].irq[1].link = %x\n",
  145. rtable->slots[loop].irq[1].link);
  146. debug("rtable->slots[loop].irq[2].link = %x\n",
  147. rtable->slots[loop].irq[2].link);
  148. debug("rtable->slots[loop].irq[3].link = %x\n",
  149. rtable->slots[loop].irq[3].link);
  150. debug("end of init_devno\n");
  151. kfree(rtable);
  152. return 0;
  153. }
  154. }
  155. kfree(rtable);
  156. return -1;
  157. }
  158. static inline int power_on(struct slot *slot_cur)
  159. {
  160. u8 cmd = HPC_SLOT_ON;
  161. int retval;
  162. retval = ibmphp_hpc_writeslot(slot_cur, cmd);
  163. if (retval) {
  164. err("power on failed\n");
  165. return retval;
  166. }
  167. if (CTLR_RESULT(slot_cur->ctrl->status)) {
  168. err("command not completed successfully in power_on\n");
  169. return -EIO;
  170. }
  171. msleep(3000); /* For ServeRAID cards, and some 66 PCI */
  172. return 0;
  173. }
  174. static inline int power_off(struct slot *slot_cur)
  175. {
  176. u8 cmd = HPC_SLOT_OFF;
  177. int retval;
  178. retval = ibmphp_hpc_writeslot(slot_cur, cmd);
  179. if (retval) {
  180. err("power off failed\n");
  181. return retval;
  182. }
  183. if (CTLR_RESULT(slot_cur->ctrl->status)) {
  184. err("command not completed successfully in power_off\n");
  185. retval = -EIO;
  186. }
  187. return retval;
  188. }
  189. static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)
  190. {
  191. int rc = 0;
  192. struct slot *pslot;
  193. u8 cmd = 0x00; /* avoid compiler warning */
  194. debug("set_attention_status - Entry hotplug_slot[%lx] value[%x]\n",
  195. (ulong) hotplug_slot, value);
  196. ibmphp_lock_operations();
  197. if (hotplug_slot) {
  198. switch (value) {
  199. case HPC_SLOT_ATTN_OFF:
  200. cmd = HPC_SLOT_ATTNOFF;
  201. break;
  202. case HPC_SLOT_ATTN_ON:
  203. cmd = HPC_SLOT_ATTNON;
  204. break;
  205. case HPC_SLOT_ATTN_BLINK:
  206. cmd = HPC_SLOT_BLINKLED;
  207. break;
  208. default:
  209. rc = -ENODEV;
  210. err("set_attention_status - Error : invalid input [%x]\n",
  211. value);
  212. break;
  213. }
  214. if (rc == 0) {
  215. pslot = to_slot(hotplug_slot);
  216. rc = ibmphp_hpc_writeslot(pslot, cmd);
  217. }
  218. } else
  219. rc = -ENODEV;
  220. ibmphp_unlock_operations();
  221. debug("set_attention_status - Exit rc[%d]\n", rc);
  222. return rc;
  223. }
  224. static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
  225. {
  226. int rc = -ENODEV;
  227. struct slot *pslot;
  228. struct slot myslot;
  229. debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
  230. (ulong) hotplug_slot, (ulong) value);
  231. ibmphp_lock_operations();
  232. if (hotplug_slot) {
  233. pslot = to_slot(hotplug_slot);
  234. memcpy(&myslot, pslot, sizeof(struct slot));
  235. rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
  236. &myslot.status);
  237. if (!rc)
  238. rc = ibmphp_hpc_readslot(pslot, READ_EXTSLOTSTATUS,
  239. &myslot.ext_status);
  240. if (!rc)
  241. *value = SLOT_ATTN(myslot.status, myslot.ext_status);
  242. }
  243. ibmphp_unlock_operations();
  244. debug("get_attention_status - Exit rc[%d] value[%x]\n", rc, *value);
  245. return rc;
  246. }
  247. static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
  248. {
  249. int rc = -ENODEV;
  250. struct slot *pslot;
  251. struct slot myslot;
  252. debug("get_latch_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
  253. (ulong) hotplug_slot, (ulong) value);
  254. ibmphp_lock_operations();
  255. if (hotplug_slot) {
  256. pslot = to_slot(hotplug_slot);
  257. memcpy(&myslot, pslot, sizeof(struct slot));
  258. rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
  259. &myslot.status);
  260. if (!rc)
  261. *value = SLOT_LATCH(myslot.status);
  262. }
  263. ibmphp_unlock_operations();
  264. debug("get_latch_status - Exit rc[%d] rc[%x] value[%x]\n",
  265. rc, rc, *value);
  266. return rc;
  267. }
  268. static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
  269. {
  270. int rc = -ENODEV;
  271. struct slot *pslot;
  272. struct slot myslot;
  273. debug("get_power_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
  274. (ulong) hotplug_slot, (ulong) value);
  275. ibmphp_lock_operations();
  276. if (hotplug_slot) {
  277. pslot = to_slot(hotplug_slot);
  278. memcpy(&myslot, pslot, sizeof(struct slot));
  279. rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
  280. &myslot.status);
  281. if (!rc)
  282. *value = SLOT_PWRGD(myslot.status);
  283. }
  284. ibmphp_unlock_operations();
  285. debug("get_power_status - Exit rc[%d] rc[%x] value[%x]\n",
  286. rc, rc, *value);
  287. return rc;
  288. }
  289. static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 *value)
  290. {
  291. int rc = -ENODEV;
  292. struct slot *pslot;
  293. u8 present;
  294. struct slot myslot;
  295. debug("get_adapter_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",
  296. (ulong) hotplug_slot, (ulong) value);
  297. ibmphp_lock_operations();
  298. if (hotplug_slot) {
  299. pslot = to_slot(hotplug_slot);
  300. memcpy(&myslot, pslot, sizeof(struct slot));
  301. rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
  302. &myslot.status);
  303. if (!rc) {
  304. present = SLOT_PRESENT(myslot.status);
  305. if (present == HPC_SLOT_EMPTY)
  306. *value = 0;
  307. else
  308. *value = 1;
  309. }
  310. }
  311. ibmphp_unlock_operations();
  312. debug("get_adapter_present - Exit rc[%d] value[%x]\n", rc, *value);
  313. return rc;
  314. }
  315. static int get_max_bus_speed(struct slot *slot)
  316. {
  317. int rc = 0;
  318. u8 mode = 0;
  319. enum pci_bus_speed speed;
  320. struct pci_bus *bus = slot->hotplug_slot.pci_slot->bus;
  321. debug("%s - Entry slot[%p]\n", __func__, slot);
  322. ibmphp_lock_operations();
  323. mode = slot->supported_bus_mode;
  324. speed = slot->supported_speed;
  325. ibmphp_unlock_operations();
  326. switch (speed) {
  327. case BUS_SPEED_33:
  328. break;
  329. case BUS_SPEED_66:
  330. if (mode == BUS_MODE_PCIX)
  331. speed += 0x01;
  332. break;
  333. case BUS_SPEED_100:
  334. case BUS_SPEED_133:
  335. speed += 0x01;
  336. break;
  337. default:
  338. /* Note (will need to change): there would be soon 256, 512 also */
  339. rc = -ENODEV;
  340. }
  341. if (!rc)
  342. bus->max_bus_speed = speed;
  343. debug("%s - Exit rc[%d] speed[%x]\n", __func__, rc, speed);
  344. return rc;
  345. }
  346. /*
  347. static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 *value, u8 flag)
  348. {
  349. int rc = -ENODEV;
  350. struct slot *pslot;
  351. struct slot myslot;
  352. debug("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n",
  353. (ulong)hotplug_slot, (ulong) value);
  354. if (flag)
  355. ibmphp_lock_operations();
  356. if (hotplug_slot && value) {
  357. pslot = hotplug_slot->private;
  358. if (pslot) {
  359. memcpy(&myslot, pslot, sizeof(struct slot));
  360. rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS,
  361. &(myslot.status));
  362. if (!(SLOT_LATCH (myslot.status)) &&
  363. (SLOT_PRESENT (myslot.status))) {
  364. rc = ibmphp_hpc_readslot(pslot,
  365. READ_EXTSLOTSTATUS,
  366. &(myslot.ext_status));
  367. if (!rc)
  368. *value = SLOT_SPEED(myslot.ext_status);
  369. } else
  370. *value = MAX_ADAPTER_NONE;
  371. }
  372. }
  373. if (flag)
  374. ibmphp_unlock_operations();
  375. debug("get_max_adapter_speed_1 - Exit rc[%d] value[%x]\n", rc, *value);
  376. return rc;
  377. }
  378. static int get_bus_name(struct hotplug_slot *hotplug_slot, char *value)
  379. {
  380. int rc = -ENODEV;
  381. struct slot *pslot = NULL;
  382. debug("get_bus_name - Entry hotplug_slot[%lx]\n", (ulong)hotplug_slot);
  383. ibmphp_lock_operations();
  384. if (hotplug_slot) {
  385. pslot = hotplug_slot->private;
  386. if (pslot) {
  387. rc = 0;
  388. snprintf(value, 100, "Bus %x", pslot->bus);
  389. }
  390. } else
  391. rc = -ENODEV;
  392. ibmphp_unlock_operations();
  393. debug("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
  394. return rc;
  395. }
  396. */
  397. /****************************************************************************
  398. * This routine will initialize the ops data structure used in the validate
  399. * function. It will also power off empty slots that are powered on since BIOS
  400. * leaves those on, albeit disconnected
  401. ****************************************************************************/
  402. static int __init init_ops(void)
  403. {
  404. struct slot *slot_cur;
  405. int retval;
  406. int rc;
  407. list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
  408. debug("BEFORE GETTING SLOT STATUS, slot # %x\n",
  409. slot_cur->number);
  410. if (slot_cur->ctrl->revision == 0xFF)
  411. if (get_ctrl_revision(slot_cur,
  412. &slot_cur->ctrl->revision))
  413. return -1;
  414. if (slot_cur->bus_on->current_speed == 0xFF)
  415. if (get_cur_bus_info(&slot_cur))
  416. return -1;
  417. get_max_bus_speed(slot_cur);
  418. if (slot_cur->ctrl->options == 0xFF)
  419. if (get_hpc_options(slot_cur, &slot_cur->ctrl->options))
  420. return -1;
  421. retval = slot_update(&slot_cur);
  422. if (retval)
  423. return retval;
  424. debug("status = %x\n", slot_cur->status);
  425. debug("ext_status = %x\n", slot_cur->ext_status);
  426. debug("SLOT_POWER = %x\n", SLOT_POWER(slot_cur->status));
  427. debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));
  428. debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status));
  429. if ((SLOT_PWRGD(slot_cur->status)) &&
  430. !(SLOT_PRESENT(slot_cur->status)) &&
  431. !(SLOT_LATCH(slot_cur->status))) {
  432. debug("BEFORE POWER OFF COMMAND\n");
  433. rc = power_off(slot_cur);
  434. if (rc)
  435. return rc;
  436. /* retval = slot_update(&slot_cur);
  437. * if (retval)
  438. * return retval;
  439. * ibmphp_update_slot_info(slot_cur);
  440. */
  441. }
  442. }
  443. init_flag = 0;
  444. return 0;
  445. }
  446. /* This operation will check whether the slot is within the bounds and
  447. * the operation is valid to perform on that slot
  448. * Parameters: slot, operation
  449. * Returns: 0 or error codes
  450. */
  451. static int validate(struct slot *slot_cur, int opn)
  452. {
  453. int number;
  454. int retval;
  455. if (!slot_cur)
  456. return -ENODEV;
  457. number = slot_cur->number;
  458. if ((number > max_slots) || (number < 0))
  459. return -EBADSLT;
  460. debug("slot_number in validate is %d\n", slot_cur->number);
  461. retval = slot_update(&slot_cur);
  462. if (retval)
  463. return retval;
  464. switch (opn) {
  465. case ENABLE:
  466. if (!(SLOT_PWRGD(slot_cur->status)) &&
  467. (SLOT_PRESENT(slot_cur->status)) &&
  468. !(SLOT_LATCH(slot_cur->status)))
  469. return 0;
  470. break;
  471. case DISABLE:
  472. if ((SLOT_PWRGD(slot_cur->status)) &&
  473. (SLOT_PRESENT(slot_cur->status)) &&
  474. !(SLOT_LATCH(slot_cur->status)))
  475. return 0;
  476. break;
  477. default:
  478. break;
  479. }
  480. err("validate failed....\n");
  481. return -EINVAL;
  482. }
  483. /****************************************************************************
  484. * This routine is for updating the data structures in the hotplug core
  485. * Parameters: struct slot
  486. * Returns: 0 or error
  487. ****************************************************************************/
  488. int ibmphp_update_slot_info(struct slot *slot_cur)
  489. {
  490. struct pci_bus *bus = slot_cur->hotplug_slot.pci_slot->bus;
  491. u8 bus_speed;
  492. u8 mode;
  493. bus_speed = slot_cur->bus_on->current_speed;
  494. mode = slot_cur->bus_on->current_bus_mode;
  495. switch (bus_speed) {
  496. case BUS_SPEED_33:
  497. break;
  498. case BUS_SPEED_66:
  499. if (mode == BUS_MODE_PCIX)
  500. bus_speed += 0x01;
  501. else if (mode == BUS_MODE_PCI)
  502. ;
  503. else
  504. bus_speed = PCI_SPEED_UNKNOWN;
  505. break;
  506. case BUS_SPEED_100:
  507. case BUS_SPEED_133:
  508. bus_speed += 0x01;
  509. break;
  510. default:
  511. bus_speed = PCI_SPEED_UNKNOWN;
  512. }
  513. bus->cur_bus_speed = bus_speed;
  514. // To do: bus_names
  515. return 0;
  516. }
  517. /******************************************************************************
  518. * This function will return the pci_func, given bus and devfunc, or NULL. It
  519. * is called from visit routines
  520. ******************************************************************************/
  521. static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)
  522. {
  523. struct pci_func *func_cur;
  524. struct slot *slot_cur;
  525. list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
  526. if (slot_cur->func) {
  527. func_cur = slot_cur->func;
  528. while (func_cur) {
  529. if ((func_cur->busno == busno) &&
  530. (func_cur->device == device) &&
  531. (func_cur->function == function))
  532. return func_cur;
  533. func_cur = func_cur->next;
  534. }
  535. }
  536. }
  537. return NULL;
  538. }
  539. /*************************************************************
  540. * This routine frees up memory used by struct slot, including
  541. * the pointers to pci_func, bus, hotplug_slot, controller,
  542. * and deregistering from the hotplug core
  543. *************************************************************/
  544. static void free_slots(void)
  545. {
  546. struct slot *slot_cur, *next;
  547. debug("%s -- enter\n", __func__);
  548. list_for_each_entry_safe(slot_cur, next, &ibmphp_slot_head,
  549. ibm_slot_list) {
  550. pci_hp_del(&slot_cur->hotplug_slot);
  551. slot_cur->ctrl = NULL;
  552. slot_cur->bus_on = NULL;
  553. /*
  554. * We don't want to actually remove the resources,
  555. * since ibmphp_free_resources() will do just that.
  556. */
  557. ibmphp_unconfigure_card(&slot_cur, -1);
  558. pci_hp_destroy(&slot_cur->hotplug_slot);
  559. kfree(slot_cur);
  560. }
  561. debug("%s -- exit\n", __func__);
  562. }
  563. static void ibm_unconfigure_device(struct pci_func *func)
  564. {
  565. struct pci_dev *temp;
  566. u8 j;
  567. debug("inside %s\n", __func__);
  568. debug("func->device = %x, func->function = %x\n",
  569. func->device, func->function);
  570. debug("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
  571. pci_lock_rescan_remove();
  572. for (j = 0; j < 0x08; j++) {
  573. temp = pci_get_domain_bus_and_slot(0, func->busno,
  574. (func->device << 3) | j);
  575. if (temp) {
  576. pci_stop_and_remove_bus_device(temp);
  577. pci_dev_put(temp);
  578. }
  579. }
  580. pci_dev_put(func->dev);
  581. pci_unlock_rescan_remove();
  582. }
  583. /*
  584. * The following function is to fix kernel bug regarding
  585. * getting bus entries, here we manually add those primary
  586. * bus entries to kernel bus structure whenever apply
  587. */
  588. static u8 bus_structure_fixup(u8 busno)
  589. {
  590. struct pci_bus *bus, *b;
  591. struct pci_dev *dev;
  592. u16 l;
  593. if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno)))
  594. return 1;
  595. bus = kmalloc(sizeof(*bus), GFP_KERNEL);
  596. if (!bus)
  597. return 1;
  598. dev = kmalloc(sizeof(*dev), GFP_KERNEL);
  599. if (!dev) {
  600. kfree(bus);
  601. return 1;
  602. }
  603. bus->number = busno;
  604. bus->ops = ibmphp_pci_bus->ops;
  605. dev->bus = bus;
  606. for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
  607. if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
  608. (l != 0x0000) && (l != 0xffff)) {
  609. debug("%s - Inside bus_structure_fixup()\n",
  610. __func__);
  611. b = pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);
  612. if (!b)
  613. continue;
  614. pci_bus_add_devices(b);
  615. break;
  616. }
  617. }
  618. kfree(dev);
  619. kfree(bus);
  620. return 0;
  621. }
  622. static int ibm_configure_device(struct pci_func *func)
  623. {
  624. struct pci_bus *child;
  625. int num;
  626. int flag = 0; /* this is to make sure we don't double scan the bus,
  627. for bridged devices primarily */
  628. pci_lock_rescan_remove();
  629. if (!(bus_structure_fixup(func->busno)))
  630. flag = 1;
  631. if (func->dev == NULL)
  632. func->dev = pci_get_domain_bus_and_slot(0, func->busno,
  633. PCI_DEVFN(func->device, func->function));
  634. if (func->dev == NULL) {
  635. struct pci_bus *bus = pci_find_bus(0, func->busno);
  636. if (!bus)
  637. goto out;
  638. num = pci_scan_slot(bus,
  639. PCI_DEVFN(func->device, func->function));
  640. if (num)
  641. pci_bus_add_devices(bus);
  642. func->dev = pci_get_domain_bus_and_slot(0, func->busno,
  643. PCI_DEVFN(func->device, func->function));
  644. if (func->dev == NULL) {
  645. err("ERROR... : pci_dev still NULL\n");
  646. goto out;
  647. }
  648. }
  649. if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
  650. pci_hp_add_bridge(func->dev);
  651. child = func->dev->subordinate;
  652. if (child)
  653. pci_bus_add_devices(child);
  654. }
  655. out:
  656. pci_unlock_rescan_remove();
  657. return 0;
  658. }
  659. /*******************************************************
  660. * Returns whether the bus is empty or not
  661. *******************************************************/
  662. static int is_bus_empty(struct slot *slot_cur)
  663. {
  664. int rc;
  665. struct slot *tmp_slot;
  666. u8 i = slot_cur->bus_on->slot_min;
  667. while (i <= slot_cur->bus_on->slot_max) {
  668. if (i == slot_cur->number) {
  669. i++;
  670. continue;
  671. }
  672. tmp_slot = ibmphp_get_slot_from_physical_num(i);
  673. if (!tmp_slot)
  674. return 0;
  675. rc = slot_update(&tmp_slot);
  676. if (rc)
  677. return 0;
  678. if (SLOT_PRESENT(tmp_slot->status) &&
  679. SLOT_PWRGD(tmp_slot->status))
  680. return 0;
  681. i++;
  682. }
  683. return 1;
  684. }
  685. /***********************************************************
  686. * If the HPC permits and the bus currently empty, tries to set the
  687. * bus speed and mode at the maximum card and bus capability
  688. * Parameters: slot
  689. * Returns: bus is set (0) or error code
  690. ***********************************************************/
  691. static int set_bus(struct slot *slot_cur)
  692. {
  693. int rc;
  694. u8 speed;
  695. u8 cmd = 0x0;
  696. int retval;
  697. static const struct pci_device_id ciobx[] = {
  698. { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },
  699. { },
  700. };
  701. debug("%s - entry slot # %d\n", __func__, slot_cur->number);
  702. if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) {
  703. rc = slot_update(&slot_cur);
  704. if (rc)
  705. return rc;
  706. speed = SLOT_SPEED(slot_cur->ext_status);
  707. debug("ext_status = %x, speed = %x\n", slot_cur->ext_status, speed);
  708. switch (speed) {
  709. case HPC_SLOT_SPEED_33:
  710. cmd = HPC_BUS_33CONVMODE;
  711. break;
  712. case HPC_SLOT_SPEED_66:
  713. if (SLOT_PCIX(slot_cur->ext_status)) {
  714. if ((slot_cur->supported_speed >= BUS_SPEED_66) &&
  715. (slot_cur->supported_bus_mode == BUS_MODE_PCIX))
  716. cmd = HPC_BUS_66PCIXMODE;
  717. else if (!SLOT_BUS_MODE(slot_cur->ext_status))
  718. /* if max slot/bus capability is 66 pci
  719. and there's no bus mode mismatch, then
  720. the adapter supports 66 pci */
  721. cmd = HPC_BUS_66CONVMODE;
  722. else
  723. cmd = HPC_BUS_33CONVMODE;
  724. } else {
  725. if (slot_cur->supported_speed >= BUS_SPEED_66)
  726. cmd = HPC_BUS_66CONVMODE;
  727. else
  728. cmd = HPC_BUS_33CONVMODE;
  729. }
  730. break;
  731. case HPC_SLOT_SPEED_133:
  732. switch (slot_cur->supported_speed) {
  733. case BUS_SPEED_33:
  734. cmd = HPC_BUS_33CONVMODE;
  735. break;
  736. case BUS_SPEED_66:
  737. if (slot_cur->supported_bus_mode == BUS_MODE_PCIX)
  738. cmd = HPC_BUS_66PCIXMODE;
  739. else
  740. cmd = HPC_BUS_66CONVMODE;
  741. break;
  742. case BUS_SPEED_100:
  743. cmd = HPC_BUS_100PCIXMODE;
  744. break;
  745. case BUS_SPEED_133:
  746. /* This is to take care of the bug in CIOBX chip */
  747. if (pci_dev_present(ciobx))
  748. ibmphp_hpc_writeslot(slot_cur,
  749. HPC_BUS_100PCIXMODE);
  750. cmd = HPC_BUS_133PCIXMODE;
  751. break;
  752. default:
  753. err("Wrong bus speed\n");
  754. return -ENODEV;
  755. }
  756. break;
  757. default:
  758. err("wrong slot speed\n");
  759. return -ENODEV;
  760. }
  761. debug("setting bus speed for slot %d, cmd %x\n",
  762. slot_cur->number, cmd);
  763. retval = ibmphp_hpc_writeslot(slot_cur, cmd);
  764. if (retval) {
  765. err("setting bus speed failed\n");
  766. return retval;
  767. }
  768. if (CTLR_RESULT(slot_cur->ctrl->status)) {
  769. err("command not completed successfully in set_bus\n");
  770. return -EIO;
  771. }
  772. }
  773. /* This is for x440, once Brandon fixes the firmware,
  774. will not need this delay */
  775. msleep(1000);
  776. debug("%s -Exit\n", __func__);
  777. return 0;
  778. }
  779. /* This routine checks the bus limitations that the slot is on from the BIOS.
  780. * This is used in deciding whether or not to power up the slot.
  781. * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on
  782. * same bus)
  783. * Parameters: slot
  784. * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus
  785. */
  786. static int check_limitations(struct slot *slot_cur)
  787. {
  788. u8 i;
  789. struct slot *tmp_slot;
  790. u8 count = 0;
  791. u8 limitation = 0;
  792. for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
  793. tmp_slot = ibmphp_get_slot_from_physical_num(i);
  794. if (!tmp_slot)
  795. return -ENODEV;
  796. if ((SLOT_PWRGD(tmp_slot->status)) &&
  797. !(SLOT_CONNECT(tmp_slot->status)))
  798. count++;
  799. }
  800. get_cur_bus_info(&slot_cur);
  801. switch (slot_cur->bus_on->current_speed) {
  802. case BUS_SPEED_33:
  803. limitation = slot_cur->bus_on->slots_at_33_conv;
  804. break;
  805. case BUS_SPEED_66:
  806. if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
  807. limitation = slot_cur->bus_on->slots_at_66_pcix;
  808. else
  809. limitation = slot_cur->bus_on->slots_at_66_conv;
  810. break;
  811. case BUS_SPEED_100:
  812. limitation = slot_cur->bus_on->slots_at_100_pcix;
  813. break;
  814. case BUS_SPEED_133:
  815. limitation = slot_cur->bus_on->slots_at_133_pcix;
  816. break;
  817. }
  818. if ((count + 1) > limitation)
  819. return -EINVAL;
  820. return 0;
  821. }
  822. static inline void print_card_capability(struct slot *slot_cur)
  823. {
  824. info("capability of the card is ");
  825. if ((slot_cur->ext_status & CARD_INFO) == PCIX133)
  826. info(" 133 MHz PCI-X\n");
  827. else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)
  828. info(" 66 MHz PCI-X\n");
  829. else if ((slot_cur->ext_status & CARD_INFO) == PCI66)
  830. info(" 66 MHz PCI\n");
  831. else
  832. info(" 33 MHz PCI\n");
  833. }
  834. /* This routine will power on the slot, configure the device(s) and find the
  835. * drivers for them.
  836. * Parameters: hotplug_slot
  837. * Returns: 0 or failure codes
  838. */
  839. static int enable_slot(struct hotplug_slot *hs)
  840. {
  841. int rc, i, rcpr;
  842. struct slot *slot_cur;
  843. u8 function;
  844. struct pci_func *tmp_func;
  845. ibmphp_lock_operations();
  846. debug("ENABLING SLOT........\n");
  847. slot_cur = to_slot(hs);
  848. rc = validate(slot_cur, ENABLE);
  849. if (rc) {
  850. err("validate function failed\n");
  851. goto error_nopower;
  852. }
  853. attn_LED_blink(slot_cur);
  854. rc = set_bus(slot_cur);
  855. if (rc) {
  856. err("was not able to set the bus\n");
  857. goto error_nopower;
  858. }
  859. /*-----------------debugging------------------------------*/
  860. get_cur_bus_info(&slot_cur);
  861. debug("the current bus speed right after set_bus = %x\n",
  862. slot_cur->bus_on->current_speed);
  863. /*----------------------------------------------------------*/
  864. rc = check_limitations(slot_cur);
  865. if (rc) {
  866. err("Adding this card exceeds the limitations of this bus.\n");
  867. err("(i.e., >1 133MHz cards running on same bus, or >2 66 PCI cards running on same bus.\n");
  868. err("Try hot-adding into another bus\n");
  869. rc = -EINVAL;
  870. goto error_nopower;
  871. }
  872. rc = power_on(slot_cur);
  873. if (rc) {
  874. err("something wrong when powering up... please see below for details\n");
  875. /* need to turn off before on, otherwise, blinking overwrites */
  876. attn_off(slot_cur);
  877. attn_on(slot_cur);
  878. if (slot_update(&slot_cur)) {
  879. attn_off(slot_cur);
  880. attn_on(slot_cur);
  881. rc = -ENODEV;
  882. goto exit;
  883. }
  884. /* Check to see the error of why it failed */
  885. if ((SLOT_POWER(slot_cur->status)) &&
  886. !(SLOT_PWRGD(slot_cur->status)))
  887. err("power fault occurred trying to power up\n");
  888. else if (SLOT_BUS_SPEED(slot_cur->status)) {
  889. err("bus speed mismatch occurred. please check current bus speed and card capability\n");
  890. print_card_capability(slot_cur);
  891. } else if (SLOT_BUS_MODE(slot_cur->ext_status)) {
  892. err("bus mode mismatch occurred. please check current bus mode and card capability\n");
  893. print_card_capability(slot_cur);
  894. }
  895. ibmphp_update_slot_info(slot_cur);
  896. goto exit;
  897. }
  898. debug("after power_on\n");
  899. /*-----------------------debugging---------------------------*/
  900. get_cur_bus_info(&slot_cur);
  901. debug("the current bus speed right after power_on = %x\n",
  902. slot_cur->bus_on->current_speed);
  903. /*----------------------------------------------------------*/
  904. rc = slot_update(&slot_cur);
  905. if (rc)
  906. goto error_power;
  907. rc = -EINVAL;
  908. if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {
  909. err("power fault occurred trying to power up...\n");
  910. goto error_power;
  911. }
  912. if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) {
  913. err("bus speed mismatch occurred. please check current bus speed and card capability\n");
  914. print_card_capability(slot_cur);
  915. goto error_power;
  916. }
  917. /* Don't think this case will happen after above checks...
  918. * but just in case, for paranoia sake */
  919. if (!(SLOT_POWER(slot_cur->status))) {
  920. err("power on failed...\n");
  921. goto error_power;
  922. }
  923. slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
  924. if (!slot_cur->func) {
  925. /* do update_slot_info here? */
  926. rc = -ENOMEM;
  927. goto error_power;
  928. }
  929. slot_cur->func->busno = slot_cur->bus;
  930. slot_cur->func->device = slot_cur->device;
  931. for (i = 0; i < 4; i++)
  932. slot_cur->func->irq[i] = slot_cur->irq[i];
  933. debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
  934. slot_cur->bus, slot_cur->device);
  935. if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
  936. err("configure_card was unsuccessful...\n");
  937. /* true because don't need to actually deallocate resources,
  938. * just remove references */
  939. ibmphp_unconfigure_card(&slot_cur, 1);
  940. debug("after unconfigure_card\n");
  941. slot_cur->func = NULL;
  942. rc = -ENOMEM;
  943. goto error_power;
  944. }
  945. function = 0x00;
  946. do {
  947. tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
  948. function++);
  949. if (tmp_func && !(tmp_func->dev))
  950. ibm_configure_device(tmp_func);
  951. } while (tmp_func);
  952. attn_off(slot_cur);
  953. if (slot_update(&slot_cur)) {
  954. rc = -EFAULT;
  955. goto exit;
  956. }
  957. ibmphp_print_test();
  958. rc = ibmphp_update_slot_info(slot_cur);
  959. exit:
  960. ibmphp_unlock_operations();
  961. return rc;
  962. error_nopower:
  963. attn_off(slot_cur); /* need to turn off if was blinking b4 */
  964. attn_on(slot_cur);
  965. error_cont:
  966. rcpr = slot_update(&slot_cur);
  967. if (rcpr) {
  968. rc = rcpr;
  969. goto exit;
  970. }
  971. ibmphp_update_slot_info(slot_cur);
  972. goto exit;
  973. error_power:
  974. attn_off(slot_cur); /* need to turn off if was blinking b4 */
  975. attn_on(slot_cur);
  976. rcpr = power_off(slot_cur);
  977. if (rcpr) {
  978. rc = rcpr;
  979. goto exit;
  980. }
  981. goto error_cont;
  982. }
  983. /**************************************************************
  984. * HOT REMOVING ADAPTER CARD *
  985. * INPUT: POINTER TO THE HOTPLUG SLOT STRUCTURE *
  986. * OUTPUT: SUCCESS 0 ; FAILURE: UNCONFIGURE , VALIDATE *
  987. * DISABLE POWER , *
  988. **************************************************************/
  989. static int ibmphp_disable_slot(struct hotplug_slot *hotplug_slot)
  990. {
  991. struct slot *slot = to_slot(hotplug_slot);
  992. int rc;
  993. ibmphp_lock_operations();
  994. rc = ibmphp_do_disable_slot(slot);
  995. ibmphp_unlock_operations();
  996. return rc;
  997. }
  998. int ibmphp_do_disable_slot(struct slot *slot_cur)
  999. {
  1000. int rc;
  1001. u8 flag;
  1002. debug("DISABLING SLOT...\n");
  1003. if ((slot_cur == NULL) || (slot_cur->ctrl == NULL))
  1004. return -ENODEV;
  1005. flag = slot_cur->flag;
  1006. slot_cur->flag = 1;
  1007. if (flag == 1) {
  1008. rc = validate(slot_cur, DISABLE);
  1009. /* checking if powered off already & valid slot # */
  1010. if (rc)
  1011. goto error;
  1012. }
  1013. attn_LED_blink(slot_cur);
  1014. if (slot_cur->func == NULL) {
  1015. /* We need this for functions that were there on bootup */
  1016. slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
  1017. if (!slot_cur->func) {
  1018. rc = -ENOMEM;
  1019. goto error;
  1020. }
  1021. slot_cur->func->busno = slot_cur->bus;
  1022. slot_cur->func->device = slot_cur->device;
  1023. }
  1024. ibm_unconfigure_device(slot_cur->func);
  1025. /*
  1026. * If we got here from latch suddenly opening on operating card or
  1027. * a power fault, there's no power to the card, so cannot
  1028. * read from it to determine what resources it occupied. This operation
  1029. * is forbidden anyhow. The best we can do is remove it from kernel
  1030. * lists at least */
  1031. if (!flag) {
  1032. attn_off(slot_cur);
  1033. return 0;
  1034. }
  1035. rc = ibmphp_unconfigure_card(&slot_cur, 0);
  1036. slot_cur->func = NULL;
  1037. debug("in disable_slot. after unconfigure_card\n");
  1038. if (rc) {
  1039. err("could not unconfigure card.\n");
  1040. goto error;
  1041. }
  1042. rc = ibmphp_hpc_writeslot(slot_cur, HPC_SLOT_OFF);
  1043. if (rc)
  1044. goto error;
  1045. attn_off(slot_cur);
  1046. rc = slot_update(&slot_cur);
  1047. if (rc)
  1048. goto exit;
  1049. rc = ibmphp_update_slot_info(slot_cur);
  1050. ibmphp_print_test();
  1051. exit:
  1052. return rc;
  1053. error:
  1054. /* Need to turn off if was blinking b4 */
  1055. attn_off(slot_cur);
  1056. attn_on(slot_cur);
  1057. if (slot_update(&slot_cur)) {
  1058. rc = -EFAULT;
  1059. goto exit;
  1060. }
  1061. if (flag)
  1062. ibmphp_update_slot_info(slot_cur);
  1063. goto exit;
  1064. }
  1065. const struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
  1066. .set_attention_status = set_attention_status,
  1067. .enable_slot = enable_slot,
  1068. .disable_slot = ibmphp_disable_slot,
  1069. .hardware_test = NULL,
  1070. .get_power_status = get_power_status,
  1071. .get_attention_status = get_attention_status,
  1072. .get_latch_status = get_latch_status,
  1073. .get_adapter_status = get_adapter_present,
  1074. /* .get_max_adapter_speed = get_max_adapter_speed,
  1075. .get_bus_name_status = get_bus_name,
  1076. */
  1077. };
  1078. static void ibmphp_unload(void)
  1079. {
  1080. free_slots();
  1081. debug("after slots\n");
  1082. ibmphp_free_resources();
  1083. debug("after resources\n");
  1084. ibmphp_free_bus_info_queue();
  1085. debug("after bus info\n");
  1086. ibmphp_free_ebda_hpc_queue();
  1087. debug("after ebda hpc\n");
  1088. ibmphp_free_ebda_pci_rsrc_queue();
  1089. debug("after ebda pci rsrc\n");
  1090. kfree(ibmphp_pci_bus);
  1091. }
  1092. static int __init ibmphp_init(void)
  1093. {
  1094. struct pci_bus *bus;
  1095. int i = 0;
  1096. int rc = 0;
  1097. init_flag = 1;
  1098. info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
  1099. ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
  1100. if (!ibmphp_pci_bus) {
  1101. rc = -ENOMEM;
  1102. goto exit;
  1103. }
  1104. bus = pci_find_bus(0, 0);
  1105. if (!bus) {
  1106. err("Can't find the root pci bus, can not continue\n");
  1107. rc = -ENODEV;
  1108. goto error;
  1109. }
  1110. memcpy(ibmphp_pci_bus, bus, sizeof(*ibmphp_pci_bus));
  1111. ibmphp_debug = debug;
  1112. ibmphp_hpc_initvars();
  1113. for (i = 0; i < 16; i++)
  1114. irqs[i] = 0;
  1115. rc = ibmphp_access_ebda();
  1116. if (rc)
  1117. goto error;
  1118. debug("after ibmphp_access_ebda()\n");
  1119. rc = ibmphp_rsrc_init();
  1120. if (rc)
  1121. goto error;
  1122. debug("AFTER Resource & EBDA INITIALIZATIONS\n");
  1123. max_slots = get_max_slots();
  1124. rc = ibmphp_register_pci();
  1125. if (rc)
  1126. goto error;
  1127. if (init_ops()) {
  1128. rc = -ENODEV;
  1129. goto error;
  1130. }
  1131. ibmphp_print_test();
  1132. rc = ibmphp_hpc_start_poll_thread();
  1133. if (rc)
  1134. goto error;
  1135. exit:
  1136. return rc;
  1137. error:
  1138. ibmphp_unload();
  1139. goto exit;
  1140. }
  1141. static void __exit ibmphp_exit(void)
  1142. {
  1143. ibmphp_hpc_stop_poll_thread();
  1144. debug("after polling\n");
  1145. ibmphp_unload();
  1146. debug("done\n");
  1147. }
  1148. module_init(ibmphp_init);
  1149. module_exit(ibmphp_exit);