cpci_hotplug_pci.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. /*
  2. * CompactPCI Hot Plug Driver PCI functions
  3. *
  4. * Copyright (C) 2002 by SOMA Networks, Inc.
  5. *
  6. * All rights reserved.
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or (at
  11. * your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  16. * NON INFRINGEMENT. See the GNU General Public License for more
  17. * details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. *
  23. * Send feedback to <scottm@somanetworks.com>
  24. */
  25. #include <linux/config.h>
  26. #include <linux/module.h>
  27. #include <linux/kernel.h>
  28. #include <linux/pci.h>
  29. #include <linux/proc_fs.h>
  30. #include "../pci.h"
  31. #include "pci_hotplug.h"
  32. #include "cpci_hotplug.h"
  33. #if !defined(MODULE)
  34. #define MY_NAME "cpci_hotplug"
  35. #else
  36. #define MY_NAME THIS_MODULE->name
  37. #endif
  38. extern int cpci_debug;
  39. #define dbg(format, arg...) \
  40. do { \
  41. if(cpci_debug) \
  42. printk (KERN_DEBUG "%s: " format "\n", \
  43. MY_NAME , ## arg); \
  44. } while(0)
  45. #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
  46. #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
  47. #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
  48. #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
  49. u8 cpci_get_attention_status(struct slot* slot)
  50. {
  51. int hs_cap;
  52. u16 hs_csr;
  53. hs_cap = pci_bus_find_capability(slot->bus,
  54. slot->devfn,
  55. PCI_CAP_ID_CHSWP);
  56. if(!hs_cap) {
  57. return 0;
  58. }
  59. if(pci_bus_read_config_word(slot->bus,
  60. slot->devfn,
  61. hs_cap + 2,
  62. &hs_csr)) {
  63. return 0;
  64. }
  65. return hs_csr & 0x0008 ? 1 : 0;
  66. }
  67. int cpci_set_attention_status(struct slot* slot, int status)
  68. {
  69. int hs_cap;
  70. u16 hs_csr;
  71. hs_cap = pci_bus_find_capability(slot->bus,
  72. slot->devfn,
  73. PCI_CAP_ID_CHSWP);
  74. if(!hs_cap) {
  75. return 0;
  76. }
  77. if(pci_bus_read_config_word(slot->bus,
  78. slot->devfn,
  79. hs_cap + 2,
  80. &hs_csr)) {
  81. return 0;
  82. }
  83. if(status) {
  84. hs_csr |= HS_CSR_LOO;
  85. } else {
  86. hs_csr &= ~HS_CSR_LOO;
  87. }
  88. if(pci_bus_write_config_word(slot->bus,
  89. slot->devfn,
  90. hs_cap + 2,
  91. hs_csr)) {
  92. return 0;
  93. }
  94. return 1;
  95. }
  96. u16 cpci_get_hs_csr(struct slot* slot)
  97. {
  98. int hs_cap;
  99. u16 hs_csr;
  100. hs_cap = pci_bus_find_capability(slot->bus,
  101. slot->devfn,
  102. PCI_CAP_ID_CHSWP);
  103. if(!hs_cap) {
  104. return 0xFFFF;
  105. }
  106. if(pci_bus_read_config_word(slot->bus,
  107. slot->devfn,
  108. hs_cap + 2,
  109. &hs_csr)) {
  110. return 0xFFFF;
  111. }
  112. return hs_csr;
  113. }
  114. #if 0
  115. u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr)
  116. {
  117. int hs_cap;
  118. u16 new_hs_csr;
  119. hs_cap = pci_bus_find_capability(slot->bus,
  120. slot->devfn,
  121. PCI_CAP_ID_CHSWP);
  122. if(!hs_cap) {
  123. return 0xFFFF;
  124. }
  125. /* Write out the new value */
  126. if(pci_bus_write_config_word(slot->bus,
  127. slot->devfn,
  128. hs_cap + 2,
  129. hs_csr)) {
  130. return 0xFFFF;
  131. }
  132. /* Read back what we just wrote out */
  133. if(pci_bus_read_config_word(slot->bus,
  134. slot->devfn,
  135. hs_cap + 2,
  136. &new_hs_csr)) {
  137. return 0xFFFF;
  138. }
  139. return new_hs_csr;
  140. }
  141. #endif
  142. int cpci_check_and_clear_ins(struct slot* slot)
  143. {
  144. int hs_cap;
  145. u16 hs_csr;
  146. int ins = 0;
  147. hs_cap = pci_bus_find_capability(slot->bus,
  148. slot->devfn,
  149. PCI_CAP_ID_CHSWP);
  150. if(!hs_cap) {
  151. return 0;
  152. }
  153. if(pci_bus_read_config_word(slot->bus,
  154. slot->devfn,
  155. hs_cap + 2,
  156. &hs_csr)) {
  157. return 0;
  158. }
  159. if(hs_csr & HS_CSR_INS) {
  160. /* Clear INS (by setting it) */
  161. if(pci_bus_write_config_word(slot->bus,
  162. slot->devfn,
  163. hs_cap + 2,
  164. hs_csr)) {
  165. ins = 0;
  166. }
  167. ins = 1;
  168. }
  169. return ins;
  170. }
  171. int cpci_check_ext(struct slot* slot)
  172. {
  173. int hs_cap;
  174. u16 hs_csr;
  175. int ext = 0;
  176. hs_cap = pci_bus_find_capability(slot->bus,
  177. slot->devfn,
  178. PCI_CAP_ID_CHSWP);
  179. if(!hs_cap) {
  180. return 0;
  181. }
  182. if(pci_bus_read_config_word(slot->bus,
  183. slot->devfn,
  184. hs_cap + 2,
  185. &hs_csr)) {
  186. return 0;
  187. }
  188. if(hs_csr & HS_CSR_EXT) {
  189. ext = 1;
  190. }
  191. return ext;
  192. }
  193. int cpci_clear_ext(struct slot* slot)
  194. {
  195. int hs_cap;
  196. u16 hs_csr;
  197. hs_cap = pci_bus_find_capability(slot->bus,
  198. slot->devfn,
  199. PCI_CAP_ID_CHSWP);
  200. if(!hs_cap) {
  201. return -ENODEV;
  202. }
  203. if(pci_bus_read_config_word(slot->bus,
  204. slot->devfn,
  205. hs_cap + 2,
  206. &hs_csr)) {
  207. return -ENODEV;
  208. }
  209. if(hs_csr & HS_CSR_EXT) {
  210. /* Clear EXT (by setting it) */
  211. if(pci_bus_write_config_word(slot->bus,
  212. slot->devfn,
  213. hs_cap + 2,
  214. hs_csr)) {
  215. return -ENODEV;
  216. }
  217. }
  218. return 0;
  219. }
  220. int cpci_led_on(struct slot* slot)
  221. {
  222. int hs_cap;
  223. u16 hs_csr;
  224. hs_cap = pci_bus_find_capability(slot->bus,
  225. slot->devfn,
  226. PCI_CAP_ID_CHSWP);
  227. if(!hs_cap) {
  228. return -ENODEV;
  229. }
  230. if(pci_bus_read_config_word(slot->bus,
  231. slot->devfn,
  232. hs_cap + 2,
  233. &hs_csr)) {
  234. return -ENODEV;
  235. }
  236. if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) {
  237. /* Set LOO */
  238. hs_csr |= HS_CSR_LOO;
  239. if(pci_bus_write_config_word(slot->bus,
  240. slot->devfn,
  241. hs_cap + 2,
  242. hs_csr)) {
  243. err("Could not set LOO for slot %s",
  244. slot->hotplug_slot->name);
  245. return -ENODEV;
  246. }
  247. }
  248. return 0;
  249. }
  250. int cpci_led_off(struct slot* slot)
  251. {
  252. int hs_cap;
  253. u16 hs_csr;
  254. hs_cap = pci_bus_find_capability(slot->bus,
  255. slot->devfn,
  256. PCI_CAP_ID_CHSWP);
  257. if(!hs_cap) {
  258. return -ENODEV;
  259. }
  260. if(pci_bus_read_config_word(slot->bus,
  261. slot->devfn,
  262. hs_cap + 2,
  263. &hs_csr)) {
  264. return -ENODEV;
  265. }
  266. if(hs_csr & HS_CSR_LOO) {
  267. /* Clear LOO */
  268. hs_csr &= ~HS_CSR_LOO;
  269. if(pci_bus_write_config_word(slot->bus,
  270. slot->devfn,
  271. hs_cap + 2,
  272. hs_csr)) {
  273. err("Could not clear LOO for slot %s",
  274. slot->hotplug_slot->name);
  275. return -ENODEV;
  276. }
  277. }
  278. return 0;
  279. }
  280. /*
  281. * Device configuration functions
  282. */
  283. static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev)
  284. {
  285. u8 irq_pin;
  286. int r;
  287. dbg("%s - enter", __FUNCTION__);
  288. /* NOTE: device already setup from prior scan */
  289. /* FIXME: How would we know if we need to enable the expansion ROM? */
  290. pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L);
  291. /* Assign resources */
  292. dbg("assigning resources for %02x:%02x.%x",
  293. dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
  294. for (r = 0; r < 6; r++) {
  295. struct resource *res = dev->resource + r;
  296. if(res->flags)
  297. pci_assign_resource(dev, r);
  298. }
  299. dbg("finished assigning resources for %02x:%02x.%x",
  300. dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
  301. /* Does this function have an interrupt at all? */
  302. dbg("checking for function interrupt");
  303. pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
  304. if(irq_pin) {
  305. dbg("function uses interrupt pin %d", irq_pin);
  306. }
  307. /*
  308. * Need to explicitly set irq field to 0 so that it'll get assigned
  309. * by the pcibios platform dependent code called by pci_enable_device.
  310. */
  311. dev->irq = 0;
  312. dbg("enabling device");
  313. pci_enable_device(dev); /* XXX check return */
  314. dbg("now dev->irq = %d", dev->irq);
  315. if(irq_pin && dev->irq) {
  316. pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
  317. }
  318. /* Can't use pci_insert_device at the moment, do it manually for now */
  319. pci_proc_attach_device(dev);
  320. dbg("notifying drivers");
  321. //pci_announce_device_to_drivers(dev);
  322. dbg("%s - exit", __FUNCTION__);
  323. return 0;
  324. }
  325. static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
  326. {
  327. int rc;
  328. struct pci_bus* child;
  329. struct resource* r;
  330. u8 max, n;
  331. u16 command;
  332. dbg("%s - enter", __FUNCTION__);
  333. /* Do basic bridge initialization */
  334. rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
  335. if(rc) {
  336. printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__);
  337. }
  338. rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40);
  339. if(rc) {
  340. printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__);
  341. }
  342. rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
  343. if(rc) {
  344. printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__);
  345. }
  346. /*
  347. * Set parent bridge's subordinate field so that configuration space
  348. * access will work in pci_scan_bridge and friends.
  349. */
  350. max = pci_max_busnr();
  351. bus->subordinate = max + 1;
  352. pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1);
  353. /* Scan behind bridge */
  354. n = pci_scan_bridge(bus, dev, max, 2);
  355. child = pci_find_bus(0, max + 1);
  356. if (!child)
  357. return -ENODEV;
  358. pci_proc_attach_bus(child);
  359. /*
  360. * Update parent bridge's subordinate field if there were more bridges
  361. * behind the bridge that was scanned.
  362. */
  363. if(n > max) {
  364. bus->subordinate = n;
  365. pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n);
  366. }
  367. /*
  368. * Update the bridge resources of the bridge to accommodate devices
  369. * behind it.
  370. */
  371. pci_bus_size_bridges(child);
  372. pci_bus_assign_resources(child);
  373. /* Enable resource mapping via command register */
  374. command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
  375. r = child->resource[0];
  376. if(r && r->start) {
  377. command |= PCI_COMMAND_IO;
  378. }
  379. r = child->resource[1];
  380. if(r && r->start) {
  381. command |= PCI_COMMAND_MEMORY;
  382. }
  383. r = child->resource[2];
  384. if(r && r->start) {
  385. command |= PCI_COMMAND_MEMORY;
  386. }
  387. rc = pci_write_config_word(dev, PCI_COMMAND, command);
  388. if(rc) {
  389. err("Error setting command register");
  390. return rc;
  391. }
  392. /* Set bridge control register */
  393. command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA;
  394. rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command);
  395. if(rc) {
  396. err("Error setting bridge control register");
  397. return rc;
  398. }
  399. dbg("%s - exit", __FUNCTION__);
  400. return 0;
  401. }
  402. static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
  403. struct pci_bus_wrapped *wrapped_bus)
  404. {
  405. int rc;
  406. struct pci_dev *dev = wrapped_dev->dev;
  407. struct pci_bus *bus = wrapped_bus->bus;
  408. struct slot* slot;
  409. dbg("%s - enter", __FUNCTION__);
  410. /*
  411. * We need to fix up the hotplug representation with the Linux
  412. * representation.
  413. */
  414. if(wrapped_dev->data) {
  415. slot = (struct slot*) wrapped_dev->data;
  416. slot->dev = dev;
  417. }
  418. /* If it's a bridge, scan behind it for devices */
  419. if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
  420. rc = cpci_configure_bridge(bus, dev);
  421. if(rc)
  422. return rc;
  423. }
  424. /* Actually configure device */
  425. if(dev) {
  426. rc = cpci_configure_dev(bus, dev);
  427. if(rc)
  428. return rc;
  429. }
  430. dbg("%s - exit", __FUNCTION__);
  431. return 0;
  432. }
  433. static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
  434. struct pci_bus_wrapped *wrapped_bus)
  435. {
  436. struct pci_dev *dev = wrapped_dev->dev;
  437. struct slot* slot;
  438. dbg("%s - enter", __FUNCTION__);
  439. if(!dev)
  440. return -ENODEV;
  441. /* Remove the Linux representation */
  442. if(pci_remove_device_safe(dev)) {
  443. err("Could not remove device\n");
  444. return -1;
  445. }
  446. /*
  447. * Now remove the hotplug representation.
  448. */
  449. if(wrapped_dev->data) {
  450. slot = (struct slot*) wrapped_dev->data;
  451. slot->dev = NULL;
  452. } else {
  453. dbg("No hotplug representation for %02x:%02x.%x",
  454. dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
  455. }
  456. dbg("%s - exit", __FUNCTION__);
  457. return 0;
  458. }
  459. static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus,
  460. struct pci_dev_wrapped *wrapped_dev)
  461. {
  462. struct pci_bus *bus = wrapped_bus->bus;
  463. struct pci_bus *parent = bus->self->bus;
  464. dbg("%s - enter", __FUNCTION__);
  465. /* The cleanup code for proc entries regarding buses should be in the kernel... */
  466. if(bus->procdir)
  467. dbg("detach_pci_bus %s", bus->procdir->name);
  468. pci_proc_detach_bus(bus);
  469. /* The cleanup code should live in the kernel... */
  470. bus->self->subordinate = NULL;
  471. /* unlink from parent bus */
  472. list_del(&bus->node);
  473. /* Now, remove */
  474. if(bus)
  475. kfree(bus);
  476. /* Update parent's subordinate field */
  477. if(parent) {
  478. u8 n = pci_bus_max_busnr(parent);
  479. if(n < parent->subordinate) {
  480. parent->subordinate = n;
  481. pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n);
  482. }
  483. }
  484. dbg("%s - exit", __FUNCTION__);
  485. return 0;
  486. }
  487. static struct pci_visit configure_functions = {
  488. .visit_pci_dev = configure_visit_pci_dev,
  489. };
  490. static struct pci_visit unconfigure_functions_phase2 = {
  491. .post_visit_pci_bus = unconfigure_visit_pci_bus_phase2,
  492. .post_visit_pci_dev = unconfigure_visit_pci_dev_phase2
  493. };
  494. int cpci_configure_slot(struct slot* slot)
  495. {
  496. int rc = 0;
  497. dbg("%s - enter", __FUNCTION__);
  498. if(slot->dev == NULL) {
  499. dbg("pci_dev null, finding %02x:%02x:%x",
  500. slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
  501. slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
  502. }
  503. /* Still NULL? Well then scan for it! */
  504. if(slot->dev == NULL) {
  505. int n;
  506. dbg("pci_dev still null");
  507. /*
  508. * This will generate pci_dev structures for all functions, but
  509. * we will only call this case when lookup fails.
  510. */
  511. n = pci_scan_slot(slot->bus, slot->devfn);
  512. dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n);
  513. if(n > 0)
  514. pci_bus_add_devices(slot->bus);
  515. slot->dev = pci_find_slot(slot->bus->number, slot->devfn);
  516. if(slot->dev == NULL) {
  517. err("Could not find PCI device for slot %02x", slot->number);
  518. return 0;
  519. }
  520. }
  521. dbg("slot->dev = %p", slot->dev);
  522. if(slot->dev) {
  523. struct pci_dev *dev;
  524. struct pci_dev_wrapped wrapped_dev;
  525. struct pci_bus_wrapped wrapped_bus;
  526. int i;
  527. memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
  528. memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
  529. for (i = 0; i < 8; i++) {
  530. dev = pci_find_slot(slot->bus->number,
  531. PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i));
  532. if(!dev)
  533. continue;
  534. wrapped_dev.dev = dev;
  535. wrapped_bus.bus = slot->dev->bus;
  536. if(i)
  537. wrapped_dev.data = NULL;
  538. else
  539. wrapped_dev.data = (void*) slot;
  540. rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
  541. }
  542. }
  543. dbg("%s - exit, rc = %d", __FUNCTION__, rc);
  544. return rc;
  545. }
  546. int cpci_unconfigure_slot(struct slot* slot)
  547. {
  548. int rc = 0;
  549. int i;
  550. struct pci_dev_wrapped wrapped_dev;
  551. struct pci_bus_wrapped wrapped_bus;
  552. struct pci_dev *dev;
  553. dbg("%s - enter", __FUNCTION__);
  554. if(!slot->dev) {
  555. err("No device for slot %02x\n", slot->number);
  556. return -ENODEV;
  557. }
  558. memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
  559. memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
  560. for (i = 0; i < 8; i++) {
  561. dev = pci_find_slot(slot->bus->number,
  562. PCI_DEVFN(PCI_SLOT(slot->devfn), i));
  563. if(dev) {
  564. wrapped_dev.dev = dev;
  565. wrapped_bus.bus = dev->bus;
  566. if(i)
  567. wrapped_dev.data = NULL;
  568. else
  569. wrapped_dev.data = (void*) slot;
  570. dbg("%s - unconfigure phase 2", __FUNCTION__);
  571. rc = pci_visit_dev(&unconfigure_functions_phase2,
  572. &wrapped_dev,
  573. &wrapped_bus);
  574. if(rc)
  575. break;
  576. }
  577. }
  578. dbg("%s - exit, rc = %d", __FUNCTION__, rc);
  579. return rc;
  580. }