pciehp_hpc.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456
  1. /*
  2. * PCI Express PCI Hot Plug 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 Corp.
  7. * Copyright (C) 2003-2004 Intel Corporation
  8. *
  9. * All rights reserved.
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or (at
  14. * your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful, but
  17. * WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  19. * NON INFRINGEMENT. See the GNU General Public License for more
  20. * details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program; if not, write to the Free Software
  24. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25. *
  26. * Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
  27. *
  28. */
  29. #include <linux/kernel.h>
  30. #include <linux/module.h>
  31. #include <linux/types.h>
  32. #include <linux/pci.h>
  33. #include "../pci.h"
  34. #include "pciehp.h"
  35. #ifdef DEBUG
  36. #define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */
  37. #define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */
  38. #define DBG_K_INFO ((unsigned int)0x00000004) /* Info messages */
  39. #define DBG_K_ERROR ((unsigned int)0x00000008) /* Error messages */
  40. #define DBG_K_TRACE (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT)
  41. #define DBG_K_STANDARD (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE)
  42. /* Redefine this flagword to set debug level */
  43. #define DEBUG_LEVEL DBG_K_STANDARD
  44. #define DEFINE_DBG_BUFFER char __dbg_str_buf[256];
  45. #define DBG_PRINT( dbg_flags, args... ) \
  46. do { \
  47. if ( DEBUG_LEVEL & ( dbg_flags ) ) \
  48. { \
  49. int len; \
  50. len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \
  51. __FILE__, __LINE__, __FUNCTION__ ); \
  52. sprintf( __dbg_str_buf + len, args ); \
  53. printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \
  54. } \
  55. } while (0)
  56. #define DBG_ENTER_ROUTINE DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]");
  57. #define DBG_LEAVE_ROUTINE DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]");
  58. #else
  59. #define DEFINE_DBG_BUFFER
  60. #define DBG_ENTER_ROUTINE
  61. #define DBG_LEAVE_ROUTINE
  62. #endif /* DEBUG */
  63. struct ctrl_reg {
  64. u8 cap_id;
  65. u8 nxt_ptr;
  66. u16 cap_reg;
  67. u32 dev_cap;
  68. u16 dev_ctrl;
  69. u16 dev_status;
  70. u32 lnk_cap;
  71. u16 lnk_ctrl;
  72. u16 lnk_status;
  73. u32 slot_cap;
  74. u16 slot_ctrl;
  75. u16 slot_status;
  76. u16 root_ctrl;
  77. u16 rsvp;
  78. u32 root_status;
  79. } __attribute__ ((packed));
  80. /* offsets to the controller registers based on the above structure layout */
  81. enum ctrl_offsets {
  82. PCIECAPID = offsetof(struct ctrl_reg, cap_id),
  83. NXTCAPPTR = offsetof(struct ctrl_reg, nxt_ptr),
  84. CAPREG = offsetof(struct ctrl_reg, cap_reg),
  85. DEVCAP = offsetof(struct ctrl_reg, dev_cap),
  86. DEVCTRL = offsetof(struct ctrl_reg, dev_ctrl),
  87. DEVSTATUS = offsetof(struct ctrl_reg, dev_status),
  88. LNKCAP = offsetof(struct ctrl_reg, lnk_cap),
  89. LNKCTRL = offsetof(struct ctrl_reg, lnk_ctrl),
  90. LNKSTATUS = offsetof(struct ctrl_reg, lnk_status),
  91. SLOTCAP = offsetof(struct ctrl_reg, slot_cap),
  92. SLOTCTRL = offsetof(struct ctrl_reg, slot_ctrl),
  93. SLOTSTATUS = offsetof(struct ctrl_reg, slot_status),
  94. ROOTCTRL = offsetof(struct ctrl_reg, root_ctrl),
  95. ROOTSTATUS = offsetof(struct ctrl_reg, root_status),
  96. };
  97. static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */
  98. #define PCIE_CAP_ID(cb) ( cb + PCIECAPID )
  99. #define NXT_CAP_PTR(cb) ( cb + NXTCAPPTR )
  100. #define CAP_REG(cb) ( cb + CAPREG )
  101. #define DEV_CAP(cb) ( cb + DEVCAP )
  102. #define DEV_CTRL(cb) ( cb + DEVCTRL )
  103. #define DEV_STATUS(cb) ( cb + DEVSTATUS )
  104. #define LNK_CAP(cb) ( cb + LNKCAP )
  105. #define LNK_CTRL(cb) ( cb + LNKCTRL )
  106. #define LNK_STATUS(cb) ( cb + LNKSTATUS )
  107. #define SLOT_CAP(cb) ( cb + SLOTCAP )
  108. #define SLOT_CTRL(cb) ( cb + SLOTCTRL )
  109. #define SLOT_STATUS(cb) ( cb + SLOTSTATUS )
  110. #define ROOT_CTRL(cb) ( cb + ROOTCTRL )
  111. #define ROOT_STATUS(cb) ( cb + ROOTSTATUS )
  112. #define hp_register_read_word(pdev, reg , value) \
  113. pci_read_config_word(pdev, reg, &value)
  114. #define hp_register_read_dword(pdev, reg , value) \
  115. pci_read_config_dword(pdev, reg, &value)
  116. #define hp_register_write_word(pdev, reg , value) \
  117. pci_write_config_word(pdev, reg, value)
  118. #define hp_register_dwrite_word(pdev, reg , value) \
  119. pci_write_config_dword(pdev, reg, value)
  120. /* Field definitions in PCI Express Capabilities Register */
  121. #define CAP_VER 0x000F
  122. #define DEV_PORT_TYPE 0x00F0
  123. #define SLOT_IMPL 0x0100
  124. #define MSG_NUM 0x3E00
  125. /* Device or Port Type */
  126. #define NAT_ENDPT 0x00
  127. #define LEG_ENDPT 0x01
  128. #define ROOT_PORT 0x04
  129. #define UP_STREAM 0x05
  130. #define DN_STREAM 0x06
  131. #define PCIE_PCI_BRDG 0x07
  132. #define PCI_PCIE_BRDG 0x10
  133. /* Field definitions in Device Capabilities Register */
  134. #define DATTN_BUTTN_PRSN 0x1000
  135. #define DATTN_LED_PRSN 0x2000
  136. #define DPWR_LED_PRSN 0x4000
  137. /* Field definitions in Link Capabilities Register */
  138. #define MAX_LNK_SPEED 0x000F
  139. #define MAX_LNK_WIDTH 0x03F0
  140. /* Link Width Encoding */
  141. #define LNK_X1 0x01
  142. #define LNK_X2 0x02
  143. #define LNK_X4 0x04
  144. #define LNK_X8 0x08
  145. #define LNK_X12 0x0C
  146. #define LNK_X16 0x10
  147. #define LNK_X32 0x20
  148. /*Field definitions of Link Status Register */
  149. #define LNK_SPEED 0x000F
  150. #define NEG_LINK_WD 0x03F0
  151. #define LNK_TRN_ERR 0x0400
  152. #define LNK_TRN 0x0800
  153. #define SLOT_CLK_CONF 0x1000
  154. /* Field definitions in Slot Capabilities Register */
  155. #define ATTN_BUTTN_PRSN 0x00000001
  156. #define PWR_CTRL_PRSN 0x00000002
  157. #define MRL_SENS_PRSN 0x00000004
  158. #define ATTN_LED_PRSN 0x00000008
  159. #define PWR_LED_PRSN 0x00000010
  160. #define HP_SUPR_RM_SUP 0x00000020
  161. #define HP_CAP 0x00000040
  162. #define SLOT_PWR_VALUE 0x000003F8
  163. #define SLOT_PWR_LIMIT 0x00000C00
  164. #define PSN 0xFFF80000 /* PSN: Physical Slot Number */
  165. /* Field definitions in Slot Control Register */
  166. #define ATTN_BUTTN_ENABLE 0x0001
  167. #define PWR_FAULT_DETECT_ENABLE 0x0002
  168. #define MRL_DETECT_ENABLE 0x0004
  169. #define PRSN_DETECT_ENABLE 0x0008
  170. #define CMD_CMPL_INTR_ENABLE 0x0010
  171. #define HP_INTR_ENABLE 0x0020
  172. #define ATTN_LED_CTRL 0x00C0
  173. #define PWR_LED_CTRL 0x0300
  174. #define PWR_CTRL 0x0400
  175. /* Attention indicator and Power indicator states */
  176. #define LED_ON 0x01
  177. #define LED_BLINK 0x10
  178. #define LED_OFF 0x11
  179. /* Power Control Command */
  180. #define POWER_ON 0
  181. #define POWER_OFF 0x0400
  182. /* Field definitions in Slot Status Register */
  183. #define ATTN_BUTTN_PRESSED 0x0001
  184. #define PWR_FAULT_DETECTED 0x0002
  185. #define MRL_SENS_CHANGED 0x0004
  186. #define PRSN_DETECT_CHANGED 0x0008
  187. #define CMD_COMPLETED 0x0010
  188. #define MRL_STATE 0x0020
  189. #define PRSN_STATE 0x0040
  190. static spinlock_t hpc_event_lock;
  191. DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
  192. static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
  193. static int ctlr_seq_num = 0; /* Controller sequence # */
  194. static spinlock_t list_lock;
  195. static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs);
  196. static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
  197. /* This is the interrupt polling timeout function. */
  198. static void int_poll_timeout(unsigned long lphp_ctlr)
  199. {
  200. struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr;
  201. DBG_ENTER_ROUTINE
  202. if ( !php_ctlr ) {
  203. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  204. return;
  205. }
  206. /* Poll for interrupt events. regs == NULL => polling */
  207. pcie_isr( 0, (void *)php_ctlr, NULL );
  208. init_timer(&php_ctlr->int_poll_timer);
  209. if (!pciehp_poll_time)
  210. pciehp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/
  211. start_int_poll_timer(php_ctlr, pciehp_poll_time);
  212. return;
  213. }
  214. /* This function starts the interrupt polling timer. */
  215. static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds)
  216. {
  217. if (!php_ctlr) {
  218. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  219. return;
  220. }
  221. if ( ( seconds <= 0 ) || ( seconds > 60 ) )
  222. seconds = 2; /* Clamp to sane value */
  223. php_ctlr->int_poll_timer.function = &int_poll_timeout;
  224. php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; /* Instance data */
  225. php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ;
  226. add_timer(&php_ctlr->int_poll_timer);
  227. return;
  228. }
  229. static int pcie_write_cmd(struct slot *slot, u16 cmd)
  230. {
  231. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  232. int retval = 0;
  233. u16 slot_status;
  234. DBG_ENTER_ROUTINE
  235. if (!php_ctlr) {
  236. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  237. return -1;
  238. }
  239. retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
  240. if (retval) {
  241. err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
  242. return retval;
  243. }
  244. if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) {
  245. /* After 1 sec and CMD_COMPLETED still not set, just proceed forward to issue
  246. the next command according to spec. Just print out the error message */
  247. dbg("%s : CMD_COMPLETED not clear after 1 sec.\n", __FUNCTION__);
  248. }
  249. retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE);
  250. if (retval) {
  251. err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
  252. return retval;
  253. }
  254. DBG_LEAVE_ROUTINE
  255. return retval;
  256. }
  257. static int hpc_check_lnk_status(struct controller *ctrl)
  258. {
  259. struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
  260. u16 lnk_status;
  261. int retval = 0;
  262. DBG_ENTER_ROUTINE
  263. if (!php_ctlr) {
  264. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  265. return -1;
  266. }
  267. retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status);
  268. if (retval) {
  269. err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
  270. return retval;
  271. }
  272. dbg("%s: lnk_status = %x\n", __FUNCTION__, lnk_status);
  273. if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) ||
  274. !(lnk_status & NEG_LINK_WD)) {
  275. err("%s : Link Training Error occurs \n", __FUNCTION__);
  276. retval = -1;
  277. return retval;
  278. }
  279. DBG_LEAVE_ROUTINE
  280. return retval;
  281. }
  282. static int hpc_get_attention_status(struct slot *slot, u8 *status)
  283. {
  284. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  285. u16 slot_ctrl;
  286. u8 atten_led_state;
  287. int retval = 0;
  288. DBG_ENTER_ROUTINE
  289. if (!php_ctlr) {
  290. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  291. return -1;
  292. }
  293. retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
  294. if (retval) {
  295. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  296. return retval;
  297. }
  298. dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
  299. atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
  300. switch (atten_led_state) {
  301. case 0:
  302. *status = 0xFF; /* Reserved */
  303. break;
  304. case 1:
  305. *status = 1; /* On */
  306. break;
  307. case 2:
  308. *status = 2; /* Blink */
  309. break;
  310. case 3:
  311. *status = 0; /* Off */
  312. break;
  313. default:
  314. *status = 0xFF;
  315. break;
  316. }
  317. DBG_LEAVE_ROUTINE
  318. return 0;
  319. }
  320. static int hpc_get_power_status(struct slot * slot, u8 *status)
  321. {
  322. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  323. u16 slot_ctrl;
  324. u8 pwr_state;
  325. int retval = 0;
  326. DBG_ENTER_ROUTINE
  327. if (!php_ctlr) {
  328. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  329. return -1;
  330. }
  331. retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
  332. if (retval) {
  333. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  334. return retval;
  335. }
  336. dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
  337. pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
  338. switch (pwr_state) {
  339. case 0:
  340. *status = 1;
  341. break;
  342. case 1:
  343. *status = 0;
  344. break;
  345. default:
  346. *status = 0xFF;
  347. break;
  348. }
  349. DBG_LEAVE_ROUTINE
  350. return retval;
  351. }
  352. static int hpc_get_latch_status(struct slot *slot, u8 *status)
  353. {
  354. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  355. u16 slot_status;
  356. int retval = 0;
  357. DBG_ENTER_ROUTINE
  358. if (!php_ctlr) {
  359. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  360. return -1;
  361. }
  362. retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
  363. if (retval) {
  364. err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
  365. return retval;
  366. }
  367. *status = (((slot_status & MRL_STATE) >> 5) == 0) ? 0 : 1;
  368. DBG_LEAVE_ROUTINE
  369. return 0;
  370. }
  371. static int hpc_get_adapter_status(struct slot *slot, u8 *status)
  372. {
  373. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  374. u16 slot_status;
  375. u8 card_state;
  376. int retval = 0;
  377. DBG_ENTER_ROUTINE
  378. if (!php_ctlr) {
  379. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  380. return -1;
  381. }
  382. retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
  383. if (retval) {
  384. err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
  385. return retval;
  386. }
  387. card_state = (u8)((slot_status & PRSN_STATE) >> 6);
  388. *status = (card_state == 1) ? 1 : 0;
  389. DBG_LEAVE_ROUTINE
  390. return 0;
  391. }
  392. static int hpc_query_power_fault(struct slot * slot)
  393. {
  394. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  395. u16 slot_status;
  396. u8 pwr_fault;
  397. int retval = 0;
  398. DBG_ENTER_ROUTINE
  399. if (!php_ctlr) {
  400. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  401. return -1;
  402. }
  403. retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);
  404. if (retval) {
  405. err("%s : Cannot check for power fault\n", __FUNCTION__);
  406. return retval;
  407. }
  408. pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
  409. DBG_LEAVE_ROUTINE
  410. return pwr_fault;
  411. }
  412. static int hpc_set_attention_status(struct slot *slot, u8 value)
  413. {
  414. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  415. u16 slot_cmd = 0;
  416. u16 slot_ctrl;
  417. int rc = 0;
  418. DBG_ENTER_ROUTINE
  419. if (!php_ctlr) {
  420. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  421. return -1;
  422. }
  423. if (slot->hp_slot >= php_ctlr->num_slots) {
  424. err("%s: Invalid HPC slot number!\n", __FUNCTION__);
  425. return -1;
  426. }
  427. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
  428. if (rc) {
  429. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  430. return rc;
  431. }
  432. switch (value) {
  433. case 0 : /* turn off */
  434. slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x00C0;
  435. break;
  436. case 1: /* turn on */
  437. slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0040;
  438. break;
  439. case 2: /* turn blink */
  440. slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0080;
  441. break;
  442. default:
  443. return -1;
  444. }
  445. if (!pciehp_poll_mode)
  446. slot_cmd = slot_cmd | HP_INTR_ENABLE;
  447. pcie_write_cmd(slot, slot_cmd);
  448. dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
  449. DBG_LEAVE_ROUTINE
  450. return rc;
  451. }
  452. static void hpc_set_green_led_on(struct slot *slot)
  453. {
  454. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  455. u16 slot_cmd;
  456. u16 slot_ctrl;
  457. int rc = 0;
  458. DBG_ENTER_ROUTINE
  459. if (!php_ctlr) {
  460. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  461. return ;
  462. }
  463. if (slot->hp_slot >= php_ctlr->num_slots) {
  464. err("%s: Invalid HPC slot number!\n", __FUNCTION__);
  465. return ;
  466. }
  467. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
  468. if (rc) {
  469. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  470. return;
  471. }
  472. slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100;
  473. if (!pciehp_poll_mode)
  474. slot_cmd = slot_cmd | HP_INTR_ENABLE;
  475. pcie_write_cmd(slot, slot_cmd);
  476. dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
  477. DBG_LEAVE_ROUTINE
  478. return;
  479. }
  480. static void hpc_set_green_led_off(struct slot *slot)
  481. {
  482. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  483. u16 slot_cmd;
  484. u16 slot_ctrl;
  485. int rc = 0;
  486. DBG_ENTER_ROUTINE
  487. if (!php_ctlr) {
  488. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  489. return ;
  490. }
  491. if (slot->hp_slot >= php_ctlr->num_slots) {
  492. err("%s: Invalid HPC slot number!\n", __FUNCTION__);
  493. return ;
  494. }
  495. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
  496. if (rc) {
  497. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  498. return;
  499. }
  500. slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300;
  501. if (!pciehp_poll_mode)
  502. slot_cmd = slot_cmd | HP_INTR_ENABLE;
  503. pcie_write_cmd(slot, slot_cmd);
  504. dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
  505. DBG_LEAVE_ROUTINE
  506. return;
  507. }
  508. static void hpc_set_green_led_blink(struct slot *slot)
  509. {
  510. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  511. u16 slot_cmd;
  512. u16 slot_ctrl;
  513. int rc = 0;
  514. DBG_ENTER_ROUTINE
  515. if (!php_ctlr) {
  516. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  517. return ;
  518. }
  519. if (slot->hp_slot >= php_ctlr->num_slots) {
  520. err("%s: Invalid HPC slot number!\n", __FUNCTION__);
  521. return ;
  522. }
  523. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
  524. if (rc) {
  525. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  526. return;
  527. }
  528. slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200;
  529. if (!pciehp_poll_mode)
  530. slot_cmd = slot_cmd | HP_INTR_ENABLE;
  531. pcie_write_cmd(slot, slot_cmd);
  532. dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
  533. DBG_LEAVE_ROUTINE
  534. return;
  535. }
  536. int pcie_get_ctlr_slot_config(struct controller *ctrl,
  537. int *num_ctlr_slots, /* number of slots in this HPC; only 1 in PCIE */
  538. int *first_device_num, /* PCI dev num of the first slot in this PCIE */
  539. int *physical_slot_num, /* phy slot num of the first slot in this PCIE */
  540. u8 *ctrlcap)
  541. {
  542. struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
  543. u32 slot_cap;
  544. int rc = 0;
  545. DBG_ENTER_ROUTINE
  546. if (!php_ctlr) {
  547. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  548. return -1;
  549. }
  550. *first_device_num = 0;
  551. *num_ctlr_slots = 1;
  552. rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
  553. if (rc) {
  554. err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__);
  555. return -1;
  556. }
  557. *physical_slot_num = slot_cap >> 19;
  558. dbg("%s: PSN %d \n", __FUNCTION__, *physical_slot_num);
  559. *ctrlcap = slot_cap & 0x0000007f;
  560. DBG_LEAVE_ROUTINE
  561. return 0;
  562. }
  563. static void hpc_release_ctlr(struct controller *ctrl)
  564. {
  565. struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
  566. struct php_ctlr_state_s *p, *p_prev;
  567. DBG_ENTER_ROUTINE
  568. if (!php_ctlr) {
  569. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  570. return ;
  571. }
  572. if (pciehp_poll_mode) {
  573. del_timer(&php_ctlr->int_poll_timer);
  574. } else {
  575. if (php_ctlr->irq) {
  576. free_irq(php_ctlr->irq, ctrl);
  577. php_ctlr->irq = 0;
  578. if (!pcie_mch_quirk)
  579. pci_disable_msi(php_ctlr->pci_dev);
  580. }
  581. }
  582. if (php_ctlr->pci_dev)
  583. php_ctlr->pci_dev = NULL;
  584. spin_lock(&list_lock);
  585. p = php_ctlr_list_head;
  586. p_prev = NULL;
  587. while (p) {
  588. if (p == php_ctlr) {
  589. if (p_prev)
  590. p_prev->pnext = p->pnext;
  591. else
  592. php_ctlr_list_head = p->pnext;
  593. break;
  594. } else {
  595. p_prev = p;
  596. p = p->pnext;
  597. }
  598. }
  599. spin_unlock(&list_lock);
  600. kfree(php_ctlr);
  601. DBG_LEAVE_ROUTINE
  602. }
  603. static int hpc_power_on_slot(struct slot * slot)
  604. {
  605. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  606. u16 slot_cmd;
  607. u16 slot_ctrl;
  608. int retval = 0;
  609. DBG_ENTER_ROUTINE
  610. if (!php_ctlr) {
  611. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  612. return -1;
  613. }
  614. dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);
  615. if (slot->hp_slot >= php_ctlr->num_slots) {
  616. err("%s: Invalid HPC slot number!\n", __FUNCTION__);
  617. return -1;
  618. }
  619. retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
  620. if (retval) {
  621. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  622. return retval;
  623. }
  624. slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;
  625. if (!pciehp_poll_mode)
  626. slot_cmd = slot_cmd | HP_INTR_ENABLE;
  627. retval = pcie_write_cmd(slot, slot_cmd);
  628. if (retval) {
  629. err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);
  630. return -1;
  631. }
  632. dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
  633. DBG_LEAVE_ROUTINE
  634. return retval;
  635. }
  636. static int hpc_power_off_slot(struct slot * slot)
  637. {
  638. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  639. u16 slot_cmd;
  640. u16 slot_ctrl;
  641. int retval = 0;
  642. DBG_ENTER_ROUTINE
  643. if (!php_ctlr) {
  644. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  645. return -1;
  646. }
  647. dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);
  648. slot->hp_slot = 0;
  649. if (slot->hp_slot >= php_ctlr->num_slots) {
  650. err("%s: Invalid HPC slot number!\n", __FUNCTION__);
  651. return -1;
  652. }
  653. retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);
  654. if (retval) {
  655. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  656. return retval;
  657. }
  658. slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;
  659. if (!pciehp_poll_mode)
  660. slot_cmd = slot_cmd | HP_INTR_ENABLE;
  661. retval = pcie_write_cmd(slot, slot_cmd);
  662. if (retval) {
  663. err("%s: Write command failed!\n", __FUNCTION__);
  664. return -1;
  665. }
  666. dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);
  667. DBG_LEAVE_ROUTINE
  668. return retval;
  669. }
  670. static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs)
  671. {
  672. struct controller *ctrl = NULL;
  673. struct php_ctlr_state_s *php_ctlr;
  674. u8 schedule_flag = 0;
  675. u16 slot_status, intr_detect, intr_loc;
  676. u16 temp_word;
  677. int hp_slot = 0; /* only 1 slot per PCI Express port */
  678. int rc = 0;
  679. if (!dev_id)
  680. return IRQ_NONE;
  681. if (!pciehp_poll_mode) {
  682. ctrl = dev_id;
  683. php_ctlr = ctrl->hpc_ctlr_handle;
  684. } else {
  685. php_ctlr = dev_id;
  686. ctrl = (struct controller *)php_ctlr->callback_instance_id;
  687. }
  688. if (!ctrl) {
  689. dbg("%s: dev_id %p ctlr == NULL\n", __FUNCTION__, (void*) dev_id);
  690. return IRQ_NONE;
  691. }
  692. if (!php_ctlr) {
  693. dbg("%s: php_ctlr == NULL\n", __FUNCTION__);
  694. return IRQ_NONE;
  695. }
  696. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
  697. if (rc) {
  698. err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
  699. return IRQ_NONE;
  700. }
  701. intr_detect = ( ATTN_BUTTN_PRESSED | PWR_FAULT_DETECTED | MRL_SENS_CHANGED |
  702. PRSN_DETECT_CHANGED | CMD_COMPLETED );
  703. intr_loc = slot_status & intr_detect;
  704. /* Check to see if it was our interrupt */
  705. if ( !intr_loc )
  706. return IRQ_NONE;
  707. dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
  708. /* Mask Hot-plug Interrupt Enable */
  709. if (!pciehp_poll_mode) {
  710. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
  711. if (rc) {
  712. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  713. return IRQ_NONE;
  714. }
  715. dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);
  716. temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
  717. rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
  718. if (rc) {
  719. err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
  720. return IRQ_NONE;
  721. }
  722. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
  723. if (rc) {
  724. err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
  725. return IRQ_NONE;
  726. }
  727. dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status);
  728. /* Clear command complete interrupt caused by this write */
  729. temp_word = 0x1f;
  730. rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
  731. if (rc) {
  732. err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
  733. return IRQ_NONE;
  734. }
  735. }
  736. if (intr_loc & CMD_COMPLETED) {
  737. /*
  738. * Command Complete Interrupt Pending
  739. */
  740. wake_up_interruptible(&ctrl->queue);
  741. }
  742. if ((php_ctlr->switch_change_callback) && (intr_loc & MRL_SENS_CHANGED))
  743. schedule_flag += php_ctlr->switch_change_callback(
  744. hp_slot, php_ctlr->callback_instance_id);
  745. if ((php_ctlr->attention_button_callback) && (intr_loc & ATTN_BUTTN_PRESSED))
  746. schedule_flag += php_ctlr->attention_button_callback(
  747. hp_slot, php_ctlr->callback_instance_id);
  748. if ((php_ctlr->presence_change_callback) && (intr_loc & PRSN_DETECT_CHANGED))
  749. schedule_flag += php_ctlr->presence_change_callback(
  750. hp_slot , php_ctlr->callback_instance_id);
  751. if ((php_ctlr->power_fault_callback) && (intr_loc & PWR_FAULT_DETECTED))
  752. schedule_flag += php_ctlr->power_fault_callback(
  753. hp_slot, php_ctlr->callback_instance_id);
  754. /* Clear all events after serving them */
  755. temp_word = 0x1F;
  756. rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
  757. if (rc) {
  758. err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
  759. return IRQ_NONE;
  760. }
  761. /* Unmask Hot-plug Interrupt Enable */
  762. if (!pciehp_poll_mode) {
  763. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
  764. if (rc) {
  765. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  766. return IRQ_NONE;
  767. }
  768. dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);
  769. temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
  770. rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);
  771. if (rc) {
  772. err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
  773. return IRQ_NONE;
  774. }
  775. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
  776. if (rc) {
  777. err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
  778. return IRQ_NONE;
  779. }
  780. /* Clear command complete interrupt caused by this write */
  781. temp_word = 0x1F;
  782. rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
  783. if (rc) {
  784. err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
  785. return IRQ_NONE;
  786. }
  787. dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);
  788. }
  789. return IRQ_HANDLED;
  790. }
  791. static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
  792. {
  793. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  794. enum pcie_link_speed lnk_speed;
  795. u32 lnk_cap;
  796. int retval = 0;
  797. DBG_ENTER_ROUTINE
  798. if (!php_ctlr) {
  799. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  800. return -1;
  801. }
  802. if (slot->hp_slot >= php_ctlr->num_slots) {
  803. err("%s: Invalid HPC slot number!\n", __FUNCTION__);
  804. return -1;
  805. }
  806. retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
  807. if (retval) {
  808. err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__);
  809. return retval;
  810. }
  811. switch (lnk_cap & 0x000F) {
  812. case 1:
  813. lnk_speed = PCIE_2PT5GB;
  814. break;
  815. default:
  816. lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
  817. break;
  818. }
  819. *value = lnk_speed;
  820. dbg("Max link speed = %d\n", lnk_speed);
  821. DBG_LEAVE_ROUTINE
  822. return retval;
  823. }
  824. static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value)
  825. {
  826. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  827. enum pcie_link_width lnk_wdth;
  828. u32 lnk_cap;
  829. int retval = 0;
  830. DBG_ENTER_ROUTINE
  831. if (!php_ctlr) {
  832. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  833. return -1;
  834. }
  835. if (slot->hp_slot >= php_ctlr->num_slots) {
  836. err("%s: Invalid HPC slot number!\n", __FUNCTION__);
  837. return -1;
  838. }
  839. retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap);
  840. if (retval) {
  841. err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__);
  842. return retval;
  843. }
  844. switch ((lnk_cap & 0x03F0) >> 4){
  845. case 0:
  846. lnk_wdth = PCIE_LNK_WIDTH_RESRV;
  847. break;
  848. case 1:
  849. lnk_wdth = PCIE_LNK_X1;
  850. break;
  851. case 2:
  852. lnk_wdth = PCIE_LNK_X2;
  853. break;
  854. case 4:
  855. lnk_wdth = PCIE_LNK_X4;
  856. break;
  857. case 8:
  858. lnk_wdth = PCIE_LNK_X8;
  859. break;
  860. case 12:
  861. lnk_wdth = PCIE_LNK_X12;
  862. break;
  863. case 16:
  864. lnk_wdth = PCIE_LNK_X16;
  865. break;
  866. case 32:
  867. lnk_wdth = PCIE_LNK_X32;
  868. break;
  869. default:
  870. lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
  871. break;
  872. }
  873. *value = lnk_wdth;
  874. dbg("Max link width = %d\n", lnk_wdth);
  875. DBG_LEAVE_ROUTINE
  876. return retval;
  877. }
  878. static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
  879. {
  880. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  881. enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN;
  882. int retval = 0;
  883. u16 lnk_status;
  884. DBG_ENTER_ROUTINE
  885. if (!php_ctlr) {
  886. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  887. return -1;
  888. }
  889. if (slot->hp_slot >= php_ctlr->num_slots) {
  890. err("%s: Invalid HPC slot number!\n", __FUNCTION__);
  891. return -1;
  892. }
  893. retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
  894. if (retval) {
  895. err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
  896. return retval;
  897. }
  898. switch (lnk_status & 0x0F) {
  899. case 1:
  900. lnk_speed = PCIE_2PT5GB;
  901. break;
  902. default:
  903. lnk_speed = PCIE_LNK_SPEED_UNKNOWN;
  904. break;
  905. }
  906. *value = lnk_speed;
  907. dbg("Current link speed = %d\n", lnk_speed);
  908. DBG_LEAVE_ROUTINE
  909. return retval;
  910. }
  911. static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value)
  912. {
  913. struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
  914. enum pcie_link_width lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
  915. int retval = 0;
  916. u16 lnk_status;
  917. DBG_ENTER_ROUTINE
  918. if (!php_ctlr) {
  919. err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
  920. return -1;
  921. }
  922. if (slot->hp_slot >= php_ctlr->num_slots) {
  923. err("%s: Invalid HPC slot number!\n", __FUNCTION__);
  924. return -1;
  925. }
  926. retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status);
  927. if (retval) {
  928. err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__);
  929. return retval;
  930. }
  931. switch ((lnk_status & 0x03F0) >> 4){
  932. case 0:
  933. lnk_wdth = PCIE_LNK_WIDTH_RESRV;
  934. break;
  935. case 1:
  936. lnk_wdth = PCIE_LNK_X1;
  937. break;
  938. case 2:
  939. lnk_wdth = PCIE_LNK_X2;
  940. break;
  941. case 4:
  942. lnk_wdth = PCIE_LNK_X4;
  943. break;
  944. case 8:
  945. lnk_wdth = PCIE_LNK_X8;
  946. break;
  947. case 12:
  948. lnk_wdth = PCIE_LNK_X12;
  949. break;
  950. case 16:
  951. lnk_wdth = PCIE_LNK_X16;
  952. break;
  953. case 32:
  954. lnk_wdth = PCIE_LNK_X32;
  955. break;
  956. default:
  957. lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
  958. break;
  959. }
  960. *value = lnk_wdth;
  961. dbg("Current link width = %d\n", lnk_wdth);
  962. DBG_LEAVE_ROUTINE
  963. return retval;
  964. }
  965. static struct hpc_ops pciehp_hpc_ops = {
  966. .power_on_slot = hpc_power_on_slot,
  967. .power_off_slot = hpc_power_off_slot,
  968. .set_attention_status = hpc_set_attention_status,
  969. .get_power_status = hpc_get_power_status,
  970. .get_attention_status = hpc_get_attention_status,
  971. .get_latch_status = hpc_get_latch_status,
  972. .get_adapter_status = hpc_get_adapter_status,
  973. .get_max_bus_speed = hpc_get_max_lnk_speed,
  974. .get_cur_bus_speed = hpc_get_cur_lnk_speed,
  975. .get_max_lnk_width = hpc_get_max_lnk_width,
  976. .get_cur_lnk_width = hpc_get_cur_lnk_width,
  977. .query_power_fault = hpc_query_power_fault,
  978. .green_led_on = hpc_set_green_led_on,
  979. .green_led_off = hpc_set_green_led_off,
  980. .green_led_blink = hpc_set_green_led_blink,
  981. .release_ctlr = hpc_release_ctlr,
  982. .check_lnk_status = hpc_check_lnk_status,
  983. };
  984. int pcie_init(struct controller * ctrl, struct pcie_device *dev)
  985. {
  986. struct php_ctlr_state_s *php_ctlr, *p;
  987. void *instance_id = ctrl;
  988. int rc;
  989. static int first = 1;
  990. u16 temp_word;
  991. u16 cap_reg;
  992. u16 intr_enable = 0;
  993. u32 slot_cap;
  994. int cap_base, saved_cap_base;
  995. u16 slot_status, slot_ctrl;
  996. struct pci_dev *pdev;
  997. DBG_ENTER_ROUTINE
  998. spin_lock_init(&list_lock);
  999. php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL);
  1000. if (!php_ctlr) { /* allocate controller state data */
  1001. err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
  1002. goto abort;
  1003. }
  1004. memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
  1005. pdev = dev->port;
  1006. php_ctlr->pci_dev = pdev; /* save pci_dev in context */
  1007. dbg("%s: hotplug controller vendor id 0x%x device id 0x%x\n",
  1008. __FUNCTION__, pdev->vendor, pdev->device);
  1009. saved_cap_base = pcie_cap_base;
  1010. if ((cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP)) == 0) {
  1011. dbg("%s: Can't find PCI_CAP_ID_EXP (0x10)\n", __FUNCTION__);
  1012. goto abort_free_ctlr;
  1013. }
  1014. ctrl->cap_base = cap_base;
  1015. dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base);
  1016. rc = hp_register_read_word(pdev, CAP_REG(ctrl->cap_base), cap_reg);
  1017. if (rc) {
  1018. err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
  1019. goto abort_free_ctlr;
  1020. }
  1021. dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG(ctrl->cap_base), cap_reg);
  1022. if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040)
  1023. && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) {
  1024. dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__);
  1025. goto abort_free_ctlr;
  1026. }
  1027. rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);
  1028. if (rc) {
  1029. err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__);
  1030. goto abort_free_ctlr;
  1031. }
  1032. dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP(ctrl->cap_base), slot_cap);
  1033. if (!(slot_cap & HP_CAP)) {
  1034. dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__);
  1035. goto abort_free_ctlr;
  1036. }
  1037. /* For debugging purpose */
  1038. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
  1039. if (rc) {
  1040. err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
  1041. goto abort_free_ctlr;
  1042. }
  1043. dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status);
  1044. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
  1045. if (rc) {
  1046. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  1047. goto abort_free_ctlr;
  1048. }
  1049. dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl);
  1050. if (first) {
  1051. spin_lock_init(&hpc_event_lock);
  1052. first = 0;
  1053. }
  1054. for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
  1055. if (pci_resource_len(pdev, rc) > 0)
  1056. dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
  1057. pci_resource_start(pdev, rc), pci_resource_len(pdev, rc));
  1058. info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device,
  1059. pdev->subsystem_vendor, pdev->subsystem_device);
  1060. if (pci_enable_device(pdev))
  1061. goto abort_free_ctlr;
  1062. init_MUTEX(&ctrl->crit_sect);
  1063. /* setup wait queue */
  1064. init_waitqueue_head(&ctrl->queue);
  1065. /* find the IRQ */
  1066. php_ctlr->irq = dev->irq;
  1067. /* Save interrupt callback info */
  1068. php_ctlr->attention_button_callback = pciehp_handle_attention_button;
  1069. php_ctlr->switch_change_callback = pciehp_handle_switch_change;
  1070. php_ctlr->presence_change_callback = pciehp_handle_presence_change;
  1071. php_ctlr->power_fault_callback = pciehp_handle_power_fault;
  1072. php_ctlr->callback_instance_id = instance_id;
  1073. /* return PCI Controller Info */
  1074. php_ctlr->slot_device_offset = 0;
  1075. php_ctlr->num_slots = 1;
  1076. /* Mask Hot-plug Interrupt Enable */
  1077. rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
  1078. if (rc) {
  1079. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  1080. goto abort_free_ctlr;
  1081. }
  1082. dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word);
  1083. temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;
  1084. rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
  1085. if (rc) {
  1086. err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
  1087. goto abort_free_ctlr;
  1088. }
  1089. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
  1090. if (rc) {
  1091. err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
  1092. goto abort_free_ctlr;
  1093. }
  1094. temp_word = 0x1F; /* Clear all events */
  1095. rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
  1096. if (rc) {
  1097. err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
  1098. goto abort_free_ctlr;
  1099. }
  1100. if (pciehp_poll_mode) {/* Install interrupt polling code */
  1101. /* Install and start the interrupt polling timer */
  1102. init_timer(&php_ctlr->int_poll_timer);
  1103. start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
  1104. } else {
  1105. /* Installs the interrupt handler */
  1106. rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
  1107. dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
  1108. if (rc) {
  1109. err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
  1110. goto abort_free_ctlr;
  1111. }
  1112. }
  1113. dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number,
  1114. PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
  1115. rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
  1116. if (rc) {
  1117. err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);
  1118. goto abort_free_ctlr;
  1119. }
  1120. intr_enable = intr_enable | PRSN_DETECT_ENABLE;
  1121. if (ATTN_BUTTN(slot_cap))
  1122. intr_enable = intr_enable | ATTN_BUTTN_ENABLE;
  1123. if (POWER_CTRL(slot_cap))
  1124. intr_enable = intr_enable | PWR_FAULT_DETECT_ENABLE;
  1125. if (MRL_SENS(slot_cap))
  1126. intr_enable = intr_enable | MRL_DETECT_ENABLE;
  1127. temp_word = (temp_word & ~intr_enable) | intr_enable;
  1128. if (pciehp_poll_mode) {
  1129. temp_word = (temp_word & ~HP_INTR_ENABLE) | 0x0;
  1130. } else {
  1131. temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;
  1132. }
  1133. /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */
  1134. rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word);
  1135. if (rc) {
  1136. err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);
  1137. goto abort_free_ctlr;
  1138. }
  1139. rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);
  1140. if (rc) {
  1141. err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);
  1142. goto abort_free_ctlr;
  1143. }
  1144. temp_word = 0x1F; /* Clear all events */
  1145. rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);
  1146. if (rc) {
  1147. err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);
  1148. goto abort_free_ctlr;
  1149. }
  1150. if (pciehp_force) {
  1151. dbg("Bypassing BIOS check for pciehp use on %s\n",
  1152. pci_name(ctrl->pci_dev));
  1153. } else {
  1154. rc = pciehp_get_hp_hw_control_from_firmware(ctrl->pci_dev);
  1155. if (rc)
  1156. goto abort_free_ctlr;
  1157. }
  1158. /* Add this HPC instance into the HPC list */
  1159. spin_lock(&list_lock);
  1160. if (php_ctlr_list_head == 0) {
  1161. php_ctlr_list_head = php_ctlr;
  1162. p = php_ctlr_list_head;
  1163. p->pnext = NULL;
  1164. } else {
  1165. p = php_ctlr_list_head;
  1166. while (p->pnext)
  1167. p = p->pnext;
  1168. p->pnext = php_ctlr;
  1169. }
  1170. spin_unlock(&list_lock);
  1171. ctlr_seq_num++;
  1172. ctrl->hpc_ctlr_handle = php_ctlr;
  1173. ctrl->hpc_ops = &pciehp_hpc_ops;
  1174. DBG_LEAVE_ROUTINE
  1175. return 0;
  1176. /* We end up here for the many possible ways to fail this API. */
  1177. abort_free_ctlr:
  1178. pcie_cap_base = saved_cap_base;
  1179. kfree(php_ctlr);
  1180. abort:
  1181. DBG_LEAVE_ROUTINE
  1182. return -1;
  1183. }