s390io.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:198k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. pdi->status |= DEVSTAT_DEVICE_OWNED;
  2. if (!ioinfo[i]->ui.flags.unfriendly)
  3. rc = 0; /* found */
  4. else
  5. rc = -EUSERS;
  6. break;
  7. }
  8. }
  9. return (rc);
  10. }
  11. int
  12. get_irq_by_devno (__u16 devno)
  13. {
  14. int i;
  15. int rc = -1;
  16. if (devno <= 0x0000ffff) {
  17. for (i = 0; i <= highest_subchannel; i++) {
  18. if ((ioinfo[i] != INVALID_STORAGE_AREA)
  19.     && (!ioinfo[i]->st)
  20.     && (ioinfo[i]->schib.pmcw.dev == devno)
  21.     && (ioinfo[i]->schib.pmcw.dnv == 1)) {
  22. rc = i;
  23. break;
  24. }
  25. }
  26. }
  27. return (rc);
  28. }
  29. unsigned int
  30. get_devno_by_irq (int irq)
  31. {
  32. if ((irq > highest_subchannel)
  33.     || (irq < 0)
  34.     || (ioinfo[irq] == INVALID_STORAGE_AREA)) {
  35. return -1;
  36. }
  37. if (ioinfo[irq]->st) 
  38. return -1;
  39. /*
  40.  * we don't need to check for the device be operational
  41.  *  as the initial STSCH will always present the device
  42.  *  number defined by the IOCDS regardless of the device
  43.  *  existing or not. However, there could be subchannels
  44.  *  defined who's device number isn't valid ...
  45.  */
  46. if (ioinfo[irq]->schib.pmcw.dnv)
  47. return (ioinfo[irq]->schib.pmcw.dev);
  48. else
  49. return -1;
  50. }
  51. /*
  52.  * s390_device_recognition_irq
  53.  *
  54.  * Used for individual device recognition. Issues the device
  55.  *  independant SenseID command to obtain info the device type.
  56.  *
  57.  */
  58. void
  59. s390_device_recognition_irq (int irq)
  60. {
  61. int ret;
  62. char dbf_txt[15];
  63. sprintf (dbf_txt, "dri%x", irq);
  64. CIO_TRACE_EVENT (4, dbf_txt);
  65. /*
  66.  * We issue the SenseID command on I/O subchannels we think are
  67.  *  operational only.
  68.  */
  69. if ((ioinfo[irq] != INVALID_STORAGE_AREA)
  70.     && (!ioinfo[irq]->st)
  71.     && (ioinfo[irq]->schib.pmcw.st == 0)
  72.     && (ioinfo[irq]->ui.flags.oper == 1)) {
  73. int irq_ret;
  74. devstat_t devstat;
  75. irq_ret = request_irq (irq,
  76.        init_IRQ_handler,
  77.        SA_PROBE, "INIT", &devstat);
  78. if (!irq_ret) {
  79. ret = enable_cpu_sync_isc (irq);
  80. if (!ret) {
  81.   pgid_t pgid;
  82.   /*
  83.    * First thing we should do is a sensePGID in
  84.    * order to find out how we can proceed with
  85.    * the recognition process. 
  86.    * An unfriendly (locked by so else) device 
  87.    * won't take kindly to our attempts at 
  88.    * SetPGID and SenseID...
  89.    */
  90.   
  91.   memcpy(&pgid, global_pgid, sizeof(pgid_t));
  92.   ret = s390_SensePGID(irq, 0xff, &pgid);
  93. if (ret == -EOPNOTSUPP) 
  94. /* 
  95.  * Doesn't prevent us from proceeding
  96.  */
  97. ret = 0;
  98.  
  99.   if (!ret && !ioinfo[irq]->ui.flags.unfriendly) {
  100. ioinfo[irq]->ui.flags.unknown = 0;
  101. memset (&ioinfo[irq]->senseid, '',
  102. sizeof (senseid_t));
  103. if (cio_sid_with_pgid) {
  104. ret = s390_DevicePathVerification(irq,0);
  105. if (ret == -EOPNOTSUPP) 
  106. /* 
  107.  * Doesn't prevent us from proceeding
  108.  */
  109. ret = 0;
  110. }
  111. /*
  112.  * we'll fallthrough here if we don't want
  113.  * to do SPID before SID
  114.  */
  115. if (!ret) {
  116. s390_SenseID (irq, &ioinfo[irq]->senseid, 0xff);
  117. #if 0 /* FIXME */
  118. /*
  119.  * We initially check the configuration data for
  120.  *  those devices with more than a single path
  121.  */
  122. if (ioinfo[irq]->schib.pmcw.pim != 0x80) {
  123. char *prcd;
  124. int lrcd;
  125. ret =
  126.     read_conf_data (irq,
  127.     (void **) &prcd,
  128.     &lrcd, 0);
  129. if (!ret) // on success only ...
  130. {
  131. char buffer[80];
  132. #ifdef CONFIG_DEBUG_IO
  133. sprintf (buffer,
  134.  "RCD for device(%04X)/"
  135.  "subchannel(%04X) returns :n",
  136.  ioinfo[irq]->schib.
  137.  pmcw.dev, irq);
  138. s390_displayhex (buffer, prcd,
  139.  lrcd);
  140. #endif
  141. if (cio_debug_initialized) {
  142. sprintf (buffer,
  143.  "RCD for device(%04X)/"
  144.  "subchannel(%04X) returns :n",
  145.  ioinfo[irq]->
  146.  schib.pmcw.dev,
  147.  irq);
  148. s390_displayhex2
  149.     (buffer, prcd, lrcd,
  150.      2);
  151. }
  152. if (init_IRQ_complete) {
  153. kfree (prcd);
  154. } else {
  155. free_bootmem ((unsigned
  156.        long)
  157.       prcd,
  158.       lrcd);
  159. }
  160. }
  161. }
  162. #endif
  163. }
  164. }
  165. disable_cpu_sync_isc (irq);
  166. }
  167. free_irq (irq, &devstat);
  168. }
  169. }
  170. }
  171. /*
  172.  * s390_device_recognition_all
  173.  *
  174.  * Used for system wide device recognition.
  175.  *
  176.  */
  177. void
  178. s390_device_recognition_all (void)
  179. {
  180. int irq = 0; /* let's start with subchannel 0 ... */
  181. do {
  182. s390_device_recognition_irq (irq);
  183. irq++;
  184. } while (irq <= highest_subchannel);
  185. }
  186. /*
  187.  * Function: s390_redo_validation
  188.  * Look for no longer blacklisted devices
  189.  * FIXME: there must be a better way to do this...
  190.  */
  191. void
  192. s390_redo_validation (void)
  193. {
  194. int irq = 0;
  195. int ret;
  196. CIO_TRACE_EVENT (0, "redoval");
  197. do {
  198. if (ioinfo[irq] == INVALID_STORAGE_AREA) {
  199. ret = s390_validate_subchannel (irq, 0);
  200. if (!ret) {
  201. s390_device_recognition_irq (irq);
  202. if (ioinfo[irq]->ui.flags.oper) {
  203. devreg_t *pdevreg;
  204. pdevreg =
  205.     s390_search_devreg (ioinfo[irq]);
  206. if (pdevreg != NULL) {
  207. if (pdevreg->oper_func != NULL)
  208. pdevreg->oper_func (irq,
  209.     pdevreg);
  210. }
  211. }
  212. #ifdef CONFIG_PROC_FS
  213. if (cio_proc_devinfo)
  214. if (irq < MAX_CIO_PROCFS_ENTRIES) {
  215. cio_procfs_device_create (ioinfo
  216.   [irq]->
  217.   devno);
  218. }
  219. #endif
  220. }
  221. }
  222. irq++;
  223. } while (irq <= highest_subchannel);
  224. }
  225. /*
  226.  * s390_trigger_resense
  227.  *
  228.  * try to re-sense the device on subchannel irq
  229.  * only to be called without interrupt handler
  230.  */
  231. int
  232. s390_trigger_resense(int irq)
  233. {
  234. char dbf_txt[8];
  235. SANITY_CHECK(irq);
  236. CIO_TRACE_EVENT (2, "tsns");
  237. sprintf(dbf_txt, "%x", irq);
  238. CIO_TRACE_EVENT (2, dbf_txt);
  239. if (ioinfo[irq]->ui.flags.ready) {
  240. printk (KERN_WARNING "s390_trigger_resense(%04X): "
  241. "Device is in use!n", irq);
  242. return -EBUSY;
  243. }
  244. s390_device_recognition_irq(irq);
  245. return 0;
  246. }
  247. /*
  248.  * s390_search_devices
  249.  *
  250.  * Determines all subchannels available to the system.
  251.  *
  252.  */
  253. void
  254. s390_process_subchannels (void)
  255. {
  256. int ret;
  257. int irq = 0; /* Evaluate all subchannels starting with 0 ... */
  258. do {
  259. ret = s390_validate_subchannel (irq, 0);
  260. if (ret != -ENXIO)
  261. irq++;
  262. } while ((ret != -ENXIO) && (irq < __MAX_SUBCHANNELS));
  263. highest_subchannel = (--irq);
  264. printk (KERN_INFO "Highest subchannel number detected (hex) : %04Xn",
  265. highest_subchannel);
  266. CIO_MSG_EVENT(0,
  267.       "Highest subchannel number detected "
  268.       "(hex) : %04Xn", highest_subchannel);
  269. }
  270. /*
  271.  * s390_validate_subchannel()
  272.  *
  273.  * Process the subchannel for the requested irq. Returns 1 for valid
  274.  *  subchannels, otherwise 0.
  275.  */
  276. int
  277. s390_validate_subchannel (int irq, int enable)
  278. {
  279. int retry; /* retry count for status pending conditions */
  280. int ccode; /* condition code for stsch() only */
  281. int ccode2; /* condition code for other I/O routines */
  282. schib_t *p_schib;
  283. int ret;
  284. #ifdef CONFIG_CHSC
  285. int      chp = 0;
  286. int      mask;
  287. #endif /* CONFIG_CHSC */
  288. char dbf_txt[15];
  289. sprintf (dbf_txt, "vals%x", irq);
  290. CIO_TRACE_EVENT (4, dbf_txt);
  291. /*
  292.  * The first subchannel that is not-operational (ccode==3)
  293.  *  indicates that there aren't any more devices available.
  294.  */
  295. if ((init_IRQ_complete)
  296.     && (ioinfo[irq] != INVALID_STORAGE_AREA)) {
  297. p_schib = &ioinfo[irq]->schib;
  298. } else {
  299. p_schib = p_init_schib;
  300. }
  301. /*
  302.  * If we knew the device before we assume the worst case ...    
  303.  */
  304. if (ioinfo[irq] != INVALID_STORAGE_AREA) {
  305. ioinfo[irq]->ui.flags.oper = 0;
  306. ioinfo[irq]->ui.flags.dval = 0;
  307. }
  308. ccode = stsch (irq, p_schib);
  309. if (ccode) {
  310. return -ENXIO;
  311. }
  312. /*
  313.  * ... just being curious we check for non I/O subchannels
  314.  */
  315. if (p_schib->pmcw.st) {
  316. if (cio_show_msg) {
  317. printk (KERN_INFO "Subchannel %04X reports "
  318. "non-I/O subchannel type %04Xn",
  319. irq, p_schib->pmcw.st);
  320. }
  321. CIO_MSG_EVENT(0,
  322.       "Subchannel %04X reports "
  323.       "non-I/O subchannel type %04Xn",
  324.       irq, p_schib->pmcw.st);
  325. if (ioinfo[irq] != INVALID_STORAGE_AREA)
  326. ioinfo[irq]->ui.flags.oper = 0;
  327. }
  328. if ((!p_schib->pmcw.dnv) && (!p_schib->pmcw.st)) {
  329. return -ENODEV;
  330. }
  331. if (!p_schib->pmcw.st) {
  332. if (is_blacklisted (p_schib->pmcw.dev)) {
  333. /* 
  334.  * This device must not be known to Linux. So we simply say that 
  335.  * there is no device and return ENODEV.
  336.  */
  337. #ifdef CONFIG_DEBUG_IO
  338. printk (KERN_DEBUG
  339. "Blacklisted device detected at devno %04Xn",
  340. p_schib->pmcw.dev);
  341. #endif
  342. CIO_MSG_EVENT(0,
  343.       "Blacklisted device detected at devno %04Xn",
  344.       p_schib->pmcw.dev);
  345. return -ENODEV;
  346. }
  347. }
  348. if (ioinfo[irq] == INVALID_STORAGE_AREA) {
  349. if (!init_IRQ_complete) {
  350. ioinfo[irq] = (ioinfo_t *)
  351.     alloc_bootmem_low (sizeof (ioinfo_t));
  352. } else {
  353. ioinfo[irq] = (ioinfo_t *)
  354.     kmalloc (sizeof (ioinfo_t), GFP_DMA);
  355. }
  356. memset (ioinfo[irq], '', sizeof (ioinfo_t));
  357. memcpy (&ioinfo[irq]->schib, p_init_schib, sizeof (schib_t));
  358. /*
  359.  * We have to insert the new ioinfo element
  360.  *  into the linked list, either at its head,
  361.  *  its tail or insert it.
  362.  */
  363. if (ioinfo_head == NULL) { /* first element */
  364. ioinfo_head = ioinfo[irq];
  365. ioinfo_tail = ioinfo[irq];
  366. } else if (irq < ioinfo_head->irq) { /* new head */
  367. ioinfo[irq]->next = ioinfo_head;
  368. ioinfo_head->prev = ioinfo[irq];
  369. ioinfo_head = ioinfo[irq];
  370. } else if (irq > ioinfo_tail->irq) { /* new tail */
  371. ioinfo_tail->next = ioinfo[irq];
  372. ioinfo[irq]->prev = ioinfo_tail;
  373. ioinfo_tail = ioinfo[irq];
  374. } else { /* insert element */
  375. ioinfo_t *pi = ioinfo_head;
  376. for (pi = ioinfo_head; pi != NULL; pi = pi->next) {
  377. if (irq < pi->next->irq) {
  378. ioinfo[irq]->next = pi->next;
  379. ioinfo[irq]->prev = pi;
  380. pi->next->prev = ioinfo[irq];
  381. pi->next = ioinfo[irq];
  382. break;
  383. }
  384. }
  385. }
  386. }
  387. /* initialize some values ... */
  388. ioinfo[irq]->irq = irq;
  389. ioinfo[irq]->st = ioinfo[irq]->schib.pmcw.st;
  390. if (ioinfo[irq]->st)
  391. return -ENODEV;
  392. ioinfo[irq]->ui.flags.pgid_supp = 1;
  393. ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim
  394.     & ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pom;
  395. #ifdef CONFIG_CHSC
  396. if (ioinfo[irq]->opm) {
  397. for (chp=0;chp<=7;chp++) {
  398. mask = 0x80 >> chp;
  399. if (ioinfo[irq]->opm & mask) {
  400. if (!test_bit
  401.     (ioinfo[irq]->schib.pmcw.chpid[chp], 
  402.      &chpids_logical)) {
  403. /* disable using this path */
  404. ioinfo[irq]->opm &= ~mask;
  405. }
  406. }
  407. }
  408. }
  409. #endif /* CONFIG_CHSC */
  410. if (cio_show_msg) {
  411. printk (KERN_INFO
  412. "Detected device %04X "
  413. "on subchannel %04X"
  414. " - PIM = %02X, PAM = %02X, POM = %02Xn",
  415. ioinfo[irq]->schib.pmcw.dev,
  416. irq,
  417. ioinfo[irq]->schib.pmcw.pim,
  418. ioinfo[irq]->schib.pmcw.pam,
  419. ioinfo[irq]->schib.pmcw.pom);
  420. }
  421. CIO_MSG_EVENT(0,
  422.       "Detected device %04X "
  423.       "on subchannel %04X"
  424.       " - PIM = %02X, "
  425.       "PAM = %02X, POM = %02Xn",
  426.       ioinfo[irq]->schib.pmcw.dev, 
  427.       irq,
  428.       ioinfo[irq]->schib.pmcw.pim,
  429.       ioinfo[irq]->schib.pmcw.pam, 
  430.       ioinfo[irq]->schib.pmcw.pom);
  431. /*
  432.  * initialize ioinfo structure
  433.  */
  434. if (!ioinfo[irq]->ui.flags.ready) {
  435. ioinfo[irq]->nopfunc = NULL;
  436. ioinfo[irq]->ui.flags.busy = 0;
  437. ioinfo[irq]->ui.flags.dval = 1;
  438. ioinfo[irq]->devstat.intparm = 0;
  439. }
  440. ioinfo[irq]->devstat.devno = ioinfo[irq]->schib.pmcw.dev;
  441. ioinfo[irq]->devno = ioinfo[irq]->schib.pmcw.dev;
  442. /*
  443.  * We should have at least one CHPID ...
  444.  */
  445. if (ioinfo[irq]->opm) {
  446. /*
  447.  * We now have to initially ...
  448.  *  ... set "interruption sublass"
  449.  *  ... enable "concurrent sense"
  450.  *  ... enable "multipath mode" if more than one
  451.  *        CHPID is available. This is done regardless
  452.  *        whether multiple paths are available for us.
  453.  *
  454.  * Note : we don't enable the device here, this is temporarily
  455.  *        done during device sensing below.
  456.  */
  457. ioinfo[irq]->schib.pmcw.isc = 3; /* could be smth. else */
  458. ioinfo[irq]->schib.pmcw.csense = 1; /* concurrent sense */
  459. ioinfo[irq]->schib.pmcw.ena = enable;
  460. ioinfo[irq]->schib.pmcw.intparm = ioinfo[irq]->schib.pmcw.dev;
  461. if ((ioinfo[irq]->opm != 0x80)
  462.     && (ioinfo[irq]->opm != 0x40)
  463.     && (ioinfo[irq]->opm != 0x20)
  464.     && (ioinfo[irq]->opm != 0x10)
  465.     && (ioinfo[irq]->opm != 0x08)
  466.     && (ioinfo[irq]->opm != 0x04)
  467.     && (ioinfo[irq]->opm != 0x02)
  468.     && (ioinfo[irq]->opm != 0x01)) {
  469. ioinfo[irq]->schib.pmcw.mp = 1; /* multipath mode */
  470. }
  471. retry = 5;
  472. do {
  473. ccode2 = msch_err (irq, &ioinfo[irq]->schib);
  474. switch (ccode2) {
  475. case 0:
  476. /*
  477.  * successful completion
  478.  *
  479.  * concurrent sense facility available
  480.  */
  481. ioinfo[irq]->ui.flags.oper = 1;
  482. ioinfo[irq]->ui.flags.consns = 1;
  483. ret = 0;
  484. break;
  485. case 1:
  486. /*
  487.  * status pending
  488.  *
  489.  * How can we have a pending status 
  490.  * as the device is disabled for 
  491.  * interrupts ?
  492.  * Anyway, process it ...
  493.  */
  494. ioinfo[irq]->ui.flags.s_pend = 1;
  495. s390_process_IRQ (irq);
  496. ioinfo[irq]->ui.flags.s_pend = 0;
  497. retry--;
  498. ret = -EIO;
  499. break;
  500. case 2:
  501. /*
  502.  * busy
  503.  *
  504.  * we mark it not-oper as we can't 
  505.  * properly operate it !
  506.  */
  507. ioinfo[irq]->ui.flags.oper = 0;
  508. udelay (100); /* allow for recovery */
  509. retry--;
  510. ret = -EBUSY;
  511. break;
  512. case 3: /* not operational */
  513. ioinfo[irq]->ui.flags.oper = 0;
  514. retry = 0;
  515. ret = -ENODEV;
  516. break;
  517. default:
  518. #define PGMCHK_OPERAND_EXC      0x15
  519. if ((ccode2 & PGMCHK_OPERAND_EXC)
  520.     == PGMCHK_OPERAND_EXC) {
  521. /*
  522.  * re-issue the modify subchannel without trying to
  523.  *  enable the concurrent sense facility
  524.  */
  525. ioinfo[irq]->schib.pmcw.csense = 0;
  526. ccode2 =
  527.     msch_err (irq, &ioinfo[irq]->schib);
  528. if (ccode2 != 0) {
  529. printk (KERN_ERR
  530. " ... msch() (2) failed"
  531. " with CC = %Xn",
  532. ccode2);
  533. CIO_MSG_EVENT(0,
  534.       "msch() (2) failed"
  535.       " with CC=%Xn",
  536.       ccode2);
  537. ioinfo[irq]->ui.flags.oper = 0;
  538. ret = -EIO;
  539. } else {
  540. ioinfo[irq]->ui.flags.oper = 1;
  541. ioinfo[irq]->ui.
  542.     flags.consns = 0;
  543. ret = 0;
  544. }
  545. } else {
  546. printk (KERN_ERR
  547. " ... msch() (1) failed with "
  548. "CC = %Xn", ccode2);
  549. CIO_MSG_EVENT(0,
  550.       "msch() (1) failed with "
  551.       "CC = %Xn", ccode2);
  552. ioinfo[irq]->ui.flags.oper = 0;
  553. ret = -EIO;
  554. }
  555. retry = 0;
  556. break;
  557. }
  558. } while (ccode2 && retry);
  559. if ((ccode2 != 0) && (ccode2 != 3)
  560.     && (!retry)) {
  561. printk (KERN_ERR
  562. " ... msch() retry count for "
  563. "subchannel %04X exceeded, CC = %dn",
  564. irq, ccode2);
  565. CIO_MSG_EVENT(0,
  566.       " ... msch() retry count for "
  567.       "subchannel %04X exceeded, CC = %dn",
  568.       irq, ccode2);
  569. }
  570. } else {
  571. /* no path available ... */
  572. ioinfo[irq]->ui.flags.oper = 0;
  573. ret = -ENODEV;
  574. }
  575. return (ret);
  576. }
  577. /*
  578.  * s390_SenseID
  579.  *
  580.  * Try to obtain the 'control unit'/'device type' information
  581.  *  associated with the subchannel.
  582.  *
  583.  * The function is primarily meant to be called without irq
  584.  *  action handler in place. However, it also allows for
  585.  *  use with an action handler in place. If there is already
  586.  *  an action handler registered assure it can handle the
  587.  *  s390_SenseID() related device interrupts - interruption
  588.  *  parameter used is 0x00E2C9C4 ( SID ).
  589.  */
  590. int
  591. s390_SenseID (int irq, senseid_t * sid, __u8 lpm)
  592. {
  593. ccw1_t *sense_ccw; /* ccw area for SenseID command */
  594. senseid_t isid; /* internal sid */
  595. devstat_t devstat; /* required by request_irq() */
  596. __u8 pathmask; /* calulate path mask */
  597. __u8 domask; /* path mask to use */
  598. int inlreq; /* inline request_irq() */
  599. int irq_ret; /* return code */
  600. devstat_t *pdevstat; /* ptr to devstat in use */
  601. int retry; /* retry count */
  602. int io_retry; /* retry indicator */
  603. senseid_t *psid = sid; /* start with the external buffer */
  604. int sbuffer = 0; /* switch SID data buffer */
  605. char dbf_txt[15];
  606. int i;
  607. int failure = 0; /* nothing went wrong yet */
  608. SANITY_CHECK (irq);
  609. if (ioinfo[irq]->ui.flags.oper == 0) {
  610. return (-ENODEV);
  611. }
  612.   if (ioinfo[irq]->ui.flags.unfriendly) {
  613.   /* don't even try it */
  614.   return -EUSERS;
  615.   }
  616. CIO_TRACE_EVENT (4, "senseID");
  617. sprintf (dbf_txt, "%x", irq);
  618. CIO_TRACE_EVENT (4, dbf_txt);
  619. inlreq = 0; /* to make the compiler quiet... */
  620. if (!ioinfo[irq]->ui.flags.ready) {
  621. pdevstat = &devstat;
  622. /*
  623.  * Perform SENSE ID command processing. We have to request device
  624.  *  ownership and provide a dummy I/O handler. We issue sync. I/O
  625.  *  requests and evaluate the devstat area on return therefore
  626.  *  we don't need a real I/O handler in place.
  627.  */
  628. irq_ret =
  629.     request_irq (irq, init_IRQ_handler, SA_PROBE, "SID",
  630.  &devstat);
  631. if (irq_ret == 0)
  632. inlreq = 1;
  633. } else {
  634. inlreq = 0;
  635. irq_ret = 0;
  636. pdevstat = ioinfo[irq]->irq_desc.dev_id;
  637. }
  638. if (irq_ret) {
  639. return irq_ret;
  640. }
  641. s390irq_spin_lock (irq);
  642. if (init_IRQ_complete) {
  643. sense_ccw = kmalloc (2 * sizeof (ccw1_t), GFP_DMA);
  644. } else {
  645. sense_ccw = alloc_bootmem_low (2 * sizeof (ccw1_t));
  646. }
  647. /* more than one path installed ? */
  648. if (ioinfo[irq]->schib.pmcw.pim != 0x80) {
  649. sense_ccw[0].cmd_code = CCW_CMD_SUSPEND_RECONN;
  650. sense_ccw[0].cda = 0;
  651. sense_ccw[0].count = 0;
  652. sense_ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
  653. sense_ccw[1].cmd_code = CCW_CMD_SENSE_ID;
  654. sense_ccw[1].cda = (__u32) virt_to_phys (sid);
  655. sense_ccw[1].count = sizeof (senseid_t);
  656. sense_ccw[1].flags = CCW_FLAG_SLI;
  657. } else {
  658. sense_ccw[0].cmd_code = CCW_CMD_SENSE_ID;
  659. sense_ccw[0].cda = (__u32) virt_to_phys (sid);
  660. sense_ccw[0].count = sizeof (senseid_t);
  661. sense_ccw[0].flags = CCW_FLAG_SLI;
  662. }
  663. for (i = 0; (i < 8); i++) {
  664. pathmask = 0x80 >> i;
  665. domask = ioinfo[irq]->opm & pathmask;
  666. if (lpm)
  667. domask &= lpm;
  668. if (!domask)
  669. continue;
  670. failure = 0;
  671. memset(psid, 0, sizeof(senseid_t));
  672. psid->cu_type = 0xFFFF; /* initialize fields ... */
  673. retry = 5; /* retry count    */
  674. io_retry = 1; /* enable retries */
  675. /*
  676.  * We now issue a SenseID request. In case of BUSY,
  677.  *  STATUS PENDING or non-CMD_REJECT error conditions
  678.  *  we run simple retries.
  679.  */
  680. do {
  681. memset (pdevstat, '', sizeof (devstat_t));
  682. irq_ret = s390_start_IO (irq, sense_ccw, 0x00E2C9C4, /* == SID */
  683.  domask,
  684.  DOIO_WAIT_FOR_INTERRUPT
  685.  | DOIO_TIMEOUT
  686.  | DOIO_VALID_LPM
  687.  | DOIO_DONT_CALL_INTHDLR);
  688. if ((psid->cu_type != 0xFFFF)
  689.     && (psid->reserved == 0xFF)) {
  690. if (!sbuffer) { /* switch buffers */
  691. /*
  692.  * we report back the
  693.  *  first hit only
  694.  */
  695. psid = &isid;
  696. if (ioinfo[irq]->schib.pmcw.pim != 0x80) {
  697. sense_ccw[1].cda = (__u32)
  698.     virt_to_phys (psid);
  699. } else {
  700. sense_ccw[0].cda = (__u32)
  701.     virt_to_phys (psid);
  702. }
  703. /*
  704.  * if just the very first
  705.  *  was requested to be
  706.  *  sensed disable further
  707.  *  scans.
  708.  */
  709. if (!lpm)
  710. lpm = domask;
  711. sbuffer = 1;
  712. }
  713. if (pdevstat->rescnt < (sizeof (senseid_t) - 8)) {
  714. ioinfo[irq]->ui.flags.esid = 1;
  715. }
  716. io_retry = 0;
  717. break;
  718. }
  719. failure = 1;
  720. if (pdevstat->flag & DEVSTAT_STATUS_PENDING) {
  721. #ifdef CONFIG_DEBUG_IO
  722. printk (KERN_DEBUG
  723. "SenseID : device %04X on "
  724. "Subchannel %04X "
  725. "reports pending status, "
  726. "retry : %dn",
  727. ioinfo[irq]->schib.pmcw.dev, irq,
  728. retry);
  729. #endif
  730. CIO_MSG_EVENT(2,
  731.       "SenseID : device %04X on "
  732.       "Subchannel %04X "
  733.       "reports pending status, "
  734.       "retry : %dn",
  735.       ioinfo
  736.       [irq]->schib.pmcw.dev, irq, retry);
  737. }
  738. else if (pdevstat->flag & DEVSTAT_FLAG_SENSE_AVAIL) {
  739. /*
  740.  * if the device doesn't support the SenseID
  741.  *  command further retries wouldn't help ...
  742.  */
  743. if (pdevstat->ii.sense.data[0]
  744.     & (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)) {
  745. #ifdef CONFIG_DEBUG_IO
  746. printk (KERN_ERR
  747. "SenseID : device %04X on "
  748. "Subchannel %04X "
  749. "reports cmd reject or "
  750. "intervention requiredn",
  751. ioinfo[irq]->schib.pmcw.dev,
  752. irq);
  753. #endif
  754. CIO_MSG_EVENT(2,
  755.       "SenseID : device %04X on "
  756.       "Subchannel %04X "
  757.       "reports cmd reject or "
  758.       "intervention requiredn",
  759.       ioinfo[irq]->schib.pmcw.dev, 
  760.       irq);
  761. io_retry = 0;
  762. } else {
  763. #ifdef CONFIG_DEBUG_IO
  764. printk
  765.     (KERN_WARNING
  766.      "SenseID : UC on "
  767.      "dev %04X, "
  768.      "retry %d, "
  769.      "lpum %02X, "
  770.      "cnt %02d, "
  771.      "sns :"
  772.      " %02X%02X%02X%02X "
  773.      "%02X%02X%02X%02X ...n",
  774.      ioinfo[irq]->schib.pmcw.dev,
  775.      retry,
  776.      pdevstat->lpum,
  777.      pdevstat->scnt,
  778.      pdevstat->ii.sense.data[0],
  779.      pdevstat->ii.sense.data[1],
  780.      pdevstat->ii.sense.data[2],
  781.      pdevstat->ii.sense.data[3],
  782.      pdevstat->ii.sense.data[4],
  783.      pdevstat->ii.sense.data[5],
  784.      pdevstat->ii.sense.data[6],
  785.      pdevstat->ii.sense.data[7]);
  786. #endif
  787. CIO_MSG_EVENT(2,
  788.       "SenseID : UC on "
  789.       "dev %04X, "
  790.       "retry %d, "
  791.       "lpum %02X, "
  792.       "cnt %02d, "
  793.       "sns :"
  794.       " %02X%02X%02X%02X "
  795.       "%02X%02X%02X%02X ...n",
  796.       ioinfo[irq]->
  797.       schib.pmcw.dev,
  798.       retry,
  799.       pdevstat->lpum,
  800.       pdevstat->scnt,
  801.       pdevstat->
  802.       ii.sense.data[0],
  803.       pdevstat->
  804.       ii.sense.data[1],
  805.       pdevstat->
  806.       ii.sense.data[2],
  807.       pdevstat->
  808.       ii.sense.data[3],
  809.       pdevstat->
  810.       ii.sense.data[4],
  811.       pdevstat->
  812.       ii.sense.data[5],
  813.       pdevstat->
  814.       ii.sense.data[6],
  815.       pdevstat->
  816.       ii.sense.data[7]);
  817. }
  818. } else if ((pdevstat->flag & DEVSTAT_NOT_OPER)
  819.    || (irq_ret == -ENODEV)) {
  820. #ifdef CONFIG_DEBUG_IO
  821. printk (KERN_ERR
  822. "SenseID : path %02X for "
  823. "device %04X on "
  824. "subchannel %04X "
  825. "is 'not operational'n",
  826. domask,
  827. ioinfo[irq]->schib.pmcw.dev, irq);
  828. #endif
  829. CIO_MSG_EVENT(2,
  830.       "SenseID : path %02X for "
  831.       "device %04X on "
  832.       "subchannel %04X "
  833.       "is 'not operational'n",
  834.       domask,
  835.       ioinfo[irq]->schib.pmcw.dev, irq);
  836. io_retry = 0;
  837. ioinfo[irq]->opm &= ~domask;
  838. } else {
  839. #ifdef CONFIG_DEBUG_IO
  840. printk (KERN_INFO
  841. "SenseID : start_IO() for "
  842. "device %04X on "
  843. "subchannel %04X "
  844. "returns %d, retry %d, "
  845. "status %04Xn",
  846. ioinfo[irq]->schib.pmcw.dev,
  847. irq, irq_ret, retry, pdevstat->flag);
  848. #endif
  849. CIO_MSG_EVENT(2,
  850.      "SenseID : start_IO() for "
  851.      "device %04X on "
  852.      "subchannel %04X "
  853.      "returns %d, retry %d, "
  854.      "status %04Xn",
  855.      ioinfo[irq]->schib.pmcw.dev, irq,
  856.      irq_ret, retry, pdevstat->flag);
  857. if (irq_ret == -ETIMEDOUT) {
  858. int xret;
  859. /*
  860.  * Seems we need to cancel the first ssch sometimes...
  861.  * On the next try, the ssch will usually be fine.
  862.  */
  863. xret = cancel_IO (irq);
  864. if (!xret)
  865. CIO_MSG_EVENT(2,
  866.       "SenseID: sch canceled "
  867.       "successfully for irq %xn",
  868.       irq);
  869. }
  870. }
  871. if (io_retry) {
  872. retry--;
  873. if (retry == 0) {
  874. io_retry = 0;
  875. }
  876. }
  877. if ((failure) && (io_retry)) {
  878. /* reset fields... */
  879. failure = 0;
  880. memset(psid, 0, sizeof(senseid_t));
  881. psid->cu_type = 0xFFFF;
  882. }
  883. } while ((io_retry));
  884. }
  885. if (init_IRQ_complete) {
  886. kfree (sense_ccw);
  887. } else {
  888. free_bootmem ((unsigned long) sense_ccw, 2 * sizeof (ccw1_t));
  889. }
  890. s390irq_spin_unlock (irq);
  891. /*
  892.  * If we installed the irq action handler we have to
  893.  *  release it too.
  894.  */
  895. if (inlreq)
  896. free_irq (irq, pdevstat);
  897. /*
  898.  * if running under VM check there ... perhaps we should do
  899.  *  only if we suffered a command reject, but it doesn't harm
  900.  */
  901. if ((sid->cu_type == 0xFFFF)
  902.     && (MACHINE_IS_VM)) {
  903. VM_virtual_device_info (ioinfo[irq]->schib.pmcw.dev, sid);
  904. }
  905. if (sid->cu_type == 0xFFFF) {
  906. /*
  907.  * SenseID CU-type of 0xffff indicates that no device
  908.  *  information could be retrieved (pre-init value).
  909.  *
  910.  * If we can't couldn't identify the device type we
  911.  *  consider the device "not operational".
  912.  */
  913. #ifdef CONFIG_DEBUG_IO
  914. printk (KERN_WARNING
  915. "SenseID : unknown device %04X on subchannel %04Xn",
  916. ioinfo[irq]->schib.pmcw.dev, irq);
  917. #endif
  918. CIO_MSG_EVENT(2,
  919.       "SenseID : unknown device %04X on subchannel %04Xn",
  920.       ioinfo[irq]->schib.pmcw.dev, irq);
  921. ioinfo[irq]->ui.flags.unknown = 1;
  922. }
  923. /*
  924.  * Issue device info message if unit was operational .
  925.  */
  926. if (!ioinfo[irq]->ui.flags.unknown) {
  927. if (sid->dev_type != 0) {
  928. if (cio_show_msg)
  929. printk (KERN_INFO
  930. "SenseID : device %04X reports: "
  931. "CU  Type/Mod = %04X/%02X,"
  932. " Dev Type/Mod = %04X/%02Xn",
  933. ioinfo[irq]->schib.pmcw.dev,
  934. sid->cu_type, sid->cu_model,
  935. sid->dev_type, sid->dev_model);
  936. CIO_MSG_EVENT(2,
  937.       "SenseID : device %04X reports: "
  938.       "CU  Type/Mod = %04X/%02X,"
  939.       " Dev Type/Mod = %04X/%02Xn",
  940.       ioinfo[irq]->schib.
  941.       pmcw.dev,
  942.       sid->cu_type,
  943.       sid->cu_model,
  944.       sid->dev_type,
  945.       sid->dev_model);
  946. } else {
  947. if (cio_show_msg)
  948. printk (KERN_INFO
  949. "SenseID : device %04X reports:"
  950. " Dev Type/Mod = %04X/%02Xn",
  951. ioinfo[irq]->schib.pmcw.dev,
  952. sid->cu_type, sid->cu_model);
  953. CIO_MSG_EVENT(2,
  954.       "SenseID : device %04X reports:"
  955.       " Dev Type/Mod = %04X/%02Xn",
  956.       ioinfo[irq]->schib.
  957.       pmcw.dev,
  958.       sid->cu_type,
  959.       sid->cu_model);
  960. }
  961. }
  962. if (!ioinfo[irq]->ui.flags.unknown)
  963. irq_ret = 0;
  964. else
  965. irq_ret = -ENODEV;
  966. return (irq_ret);
  967. }
  968. static int __inline__
  969. s390_SetMultiPath (int irq)
  970. {
  971. int cc;
  972. cc = stsch (irq, &ioinfo[irq]->schib);
  973. if (!cc) {
  974. ioinfo[irq]->schib.pmcw.mp = 1; /* multipath mode */
  975. cc = msch (irq, &ioinfo[irq]->schib);
  976. }
  977. return (cc);
  978. }
  979. /*
  980.  * Device Path Verification
  981.  *
  982.  * Path verification is accomplished by checking which paths (CHPIDs) are
  983.  *  available. Further, a path group ID is set, if possible in multipath
  984.  *  mode, otherwise in single path mode.
  985.  *
  986.  * Note : This function must not be called during normal device recognition,
  987.  *         but during device driver initiated request_irq() processing only.
  988.  */
  989. int
  990. s390_DevicePathVerification (int irq, __u8 usermask)
  991. {
  992. int ccode;
  993. __u8 pathmask;
  994. __u8 domask;
  995. #ifdef CONFIG_CHSC
  996. int chp;
  997. int mask;
  998. int old_opm = 0;
  999. #endif /* CONFIG_CHSC */
  1000. int ret = 0;
  1001. int i;
  1002. pgid_t pgid;
  1003. __u8 dev_path;
  1004. int first = 1;
  1005. char dbf_txt[15];
  1006. sprintf (dbf_txt, "dpvf%x", irq);
  1007. CIO_TRACE_EVENT (4, dbf_txt);
  1008. if (ioinfo[irq]->st) 
  1009. return -ENODEV;
  1010. #ifdef CONFIG_CHSC
  1011. old_opm = ioinfo[irq]->opm;
  1012. #endif /* CONFIG_CHSC */
  1013. ccode = stsch (irq, &(ioinfo[irq]->schib));
  1014. if (ccode) {
  1015. return -ENODEV;
  1016. }
  1017. if (ioinfo[irq]->schib.pmcw.pim == 0x80) {
  1018. /*
  1019.  * no error, just not required for single path only devices
  1020.  */
  1021. ioinfo[irq]->ui.flags.pgid_supp = 0;
  1022. ret = 0;
  1023. #ifdef CONFIG_CHSC
  1024. /*
  1025.  * disable if chpid is logically offline
  1026.  */
  1027. if (!test_bit(ioinfo[irq]->schib.pmcw.chpid[0], 
  1028.       &chpids_logical)) {
  1029. not_oper_handler_func_t nopfunc=ioinfo[irq]->nopfunc;
  1030. int was_oper = ioinfo[irq]->ui.flags.oper;
  1031. ioinfo[irq]->opm = 0;
  1032. ioinfo[irq]->ui.flags.oper = 0;
  1033. printk(KERN_WARNING 
  1034.        "No logical path for sch %d...n",
  1035.        irq);
  1036. if (old_opm && 
  1037.     was_oper && 
  1038.     ioinfo[irq]->ui.flags.ready) {
  1039. #ifdef CONFIG_PROC_FS
  1040. if (cio_proc_devinfo)
  1041. cio_procfs_device_remove
  1042. (ioinfo[irq]->devno);
  1043. #endif /* CONFIG_PROC_FS */
  1044. free_irq( irq, ioinfo[irq]->irq_desc.dev_id);
  1045. if (nopfunc)
  1046. nopfunc( irq, DEVSTAT_DEVICE_GONE);
  1047. }
  1048. ret = -ENODEV;
  1049. } else if (!old_opm) {
  1050. /*
  1051.  * check for opm...
  1052.  */
  1053. ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim
  1054. & ioinfo[irq]->schib.pmcw.pam
  1055. & ioinfo[irq]->schib.pmcw.pom;
  1056. if (ioinfo[irq]->opm) {
  1057. devreg_t *pdevreg;
  1058. ioinfo[irq]->ui.flags.oper = 1;
  1059. pdevreg = s390_search_devreg( ioinfo[irq] );
  1060. if (pdevreg) 
  1061. if (pdevreg->oper_func)
  1062. pdevreg->oper_func
  1063. ( irq, pdevreg);
  1064. #ifdef CONFIG_PROC_FS
  1065. if (cio_proc_devinfo) 
  1066. if (highest_subchannel 
  1067.     < MAX_CIO_PROCFS_ENTRIES) {
  1068. cio_procfs_device_create
  1069. (ioinfo[irq]->devno);
  1070. }
  1071. #endif /* CONFIG_PROC_FS */
  1072. }
  1073. ret = 0;
  1074. } else {
  1075. ret = 0;
  1076. }
  1077. #endif /* CONFIG_CHSC */
  1078. return ret;
  1079. }
  1080. ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim
  1081.     & ioinfo[irq]->schib.pmcw.pam & ioinfo[irq]->schib.pmcw.pom;
  1082. #ifdef CONFIG_CHSC
  1083. if (ioinfo[irq]->opm) {
  1084. for (chp=0;chp<=7;chp++) {
  1085. mask = 0x80 >> chp;
  1086. if (ioinfo[irq]->opm & mask) {
  1087. if (!test_bit
  1088.     (ioinfo[irq]->schib.pmcw.chpid[chp], 
  1089.      &chpids_logical)) {
  1090. /* disable using this path */
  1091. ioinfo[irq]->opm &= ~mask;
  1092. }
  1093. }
  1094. }
  1095. }
  1096. if ((ioinfo[irq]->opm == 0) && (old_opm)) {
  1097. not_oper_handler_func_t nopfunc=ioinfo[irq]->nopfunc;
  1098. int was_oper = ioinfo[irq]->ui.flags.ready;
  1099. ioinfo[irq]->ui.flags.oper = 0;
  1100. printk(KERN_WARNING "No logical path for sch %d...n",irq);
  1101. if (was_oper && ioinfo[irq]->ui.flags.oper) {
  1102. #ifdef CONFIG_PROC_FS
  1103. if (cio_proc_devinfo)
  1104. cio_procfs_device_remove(ioinfo[irq]->devno);
  1105. #endif /* CONFIG_PROC_FS */
  1106. free_irq( irq, ioinfo[irq]->irq_desc.dev_id);
  1107. if (nopfunc)
  1108. nopfunc( irq, DEVSTAT_DEVICE_GONE);
  1109. }
  1110. return -ENODEV;
  1111. }
  1112. if (!old_opm) {
  1113. /* Hey, we have a new logical path... */
  1114. devreg_t *pdevreg;
  1115. ioinfo[irq]->ui.flags.oper = 1;
  1116. pdevreg = s390_search_devreg( ioinfo[irq] );
  1117. if (pdevreg) 
  1118. if (pdevreg->oper_func)
  1119. pdevreg->oper_func( irq, pdevreg);
  1120. #ifdef CONFIG_PROC_FS
  1121. if (cio_proc_devinfo) 
  1122. if (highest_subchannel < MAX_CIO_PROCFS_ENTRIES) {
  1123. cio_procfs_device_create(ioinfo[irq]->devno);
  1124. }
  1125. #endif /* CONFIG_PROC_FS */
  1126. }
  1127. #endif /* CONFIG_CHSC */
  1128. if ( ioinfo[irq]->ui.flags.pgid_supp == 0 )
  1129. return( 0); /* just exit ... */
  1130. if (usermask) {
  1131. dev_path = usermask;
  1132. } else {
  1133. dev_path = ioinfo[irq]->opm;
  1134. }
  1135. if (ioinfo[irq]->ui.flags.pgid == 0) {
  1136. memcpy (&ioinfo[irq]->pgid, global_pgid, sizeof (pgid_t));
  1137. ioinfo[irq]->ui.flags.pgid = 1;
  1138. }
  1139. for (i = 0; i < 8 && !ret; i++) {
  1140. pathmask = 0x80 >> i;
  1141. domask = dev_path & pathmask;
  1142. if (domask) {
  1143. ret = s390_SetPGID (irq, domask);
  1144. /*
  1145.  * For the *first* path we are prepared
  1146.  *  for recovery
  1147.  *
  1148.  *  - If we fail setting the PGID we assume its
  1149.  *     using  a different PGID already (VM) we
  1150.  *     try to sense.
  1151.  */
  1152. if (ret == -EOPNOTSUPP && first) {
  1153. *(int *) &pgid = 0;
  1154. ret = s390_SensePGID (irq, domask, &pgid);
  1155. first = 0;
  1156. if (ret == 0) {
  1157. /*
  1158.  * Check whether we retrieved
  1159.  *  a reasonable PGID ...
  1160.  */
  1161. if (pgid.inf.ps.state1 ==
  1162.     SNID_STATE1_GROUPED) {
  1163. memcpy (&ioinfo[irq]->pgid,
  1164. &pgid, sizeof (pgid_t));
  1165. } else { /* ungrouped or garbage ... */
  1166. ret = -EOPNOTSUPP;
  1167. }
  1168. } else {
  1169. ioinfo[irq]->ui.flags.pgid_supp = 0;
  1170. #ifdef CONFIG_DEBUG_IO
  1171. printk (KERN_WARNING
  1172. "PathVerification(%04X) "
  1173. "- Device %04X doesn't "
  1174. " support path groupingn",
  1175. irq,
  1176. ioinfo[irq]->schib.pmcw.dev);
  1177. #endif
  1178. CIO_MSG_EVENT(2,
  1179.       "PathVerification(%04X) "
  1180.       "- Device %04X doesn't "
  1181.       " support path groupingn",
  1182.       irq,
  1183.       ioinfo[irq]->schib.
  1184.       pmcw.dev);
  1185. }
  1186. } else if (ret == -EIO) {
  1187. #ifdef CONFIG_DEBUG_IO
  1188. printk (KERN_ERR
  1189. "PathVerification(%04X) - I/O error "
  1190. "on device %04Xn", irq,
  1191. ioinfo[irq]->schib.pmcw.dev);
  1192. #endif
  1193. CIO_MSG_EVENT(2,
  1194.       "PathVerification(%04X) - I/O error "
  1195.       "on device %04Xn", irq,
  1196.       ioinfo[irq]->schib.pmcw.dev);
  1197. ioinfo[irq]->ui.flags.pgid_supp = 0;
  1198. } else if (ret == -ETIMEDOUT) {
  1199. #ifdef CONFIG_DEBUG_IO
  1200. printk (KERN_ERR
  1201. "PathVerification(%04X) - I/O timed "
  1202. "out on device %04Xn", 
  1203. irq,
  1204. ioinfo[irq]->schib.pmcw.dev);
  1205. #endif
  1206. CIO_MSG_EVENT(2,
  1207.       "PathVerification(%04X) - I/O timed "
  1208.       "out on device %04Xn", irq,
  1209.       ioinfo[irq]->schib.pmcw.dev);
  1210. ioinfo[irq]->ui.flags.pgid_supp = 0;
  1211. } else if (ret == -EAGAIN) {
  1212. ret = 0;
  1213. } else if (ret == -EUSERS) {
  1214. #ifdef CONFIG_DEBUG_IO
  1215. printk (KERN_ERR 
  1216. "PathVerification(%04X) "
  1217. "- Device is locked by someone else!n",
  1218. irq);
  1219. #endif
  1220. CIO_MSG_EVENT(2,
  1221.       "PathVerification(%04X) "
  1222.       "- Device is locked by someone else!n",
  1223.       irq);
  1224. } else if (ret == -ENODEV) {
  1225. #ifdef CONFIG_DEBUG_IO
  1226. printk (KERN_ERR 
  1227. "PathVerification(%04X) "
  1228. "- Device %04X is no longer there?!?n",
  1229. irq, ioinfo[irq]->schib.pmcw.dev);
  1230. #endif
  1231. CIO_MSG_EVENT(2,
  1232.       "PathVerification(%04X) "
  1233.       "- Device %04X is no longer there?!?n",
  1234.       irq, ioinfo[irq]->schib.pmcw.dev);
  1235. } else if (ret) {
  1236. #ifdef CONFIG_DEBUG_IO
  1237. printk (KERN_ERR
  1238. "PathVerification(%04X) "
  1239. "- Unexpected error %d on device %04Xn",
  1240. irq, ret, ioinfo[irq]->schib.pmcw.dev);
  1241. #endif
  1242. CIO_MSG_EVENT(2,
  1243.       "PathVerification(%04X) - "
  1244.       "Unexpected error %d on device %04Xn",
  1245.       irq, ret, ioinfo[irq]->schib.pmcw.dev);
  1246. ioinfo[irq]->ui.flags.pgid_supp = 0;
  1247. }
  1248. }
  1249. }
  1250. return ret;
  1251. }
  1252. /*
  1253.  * s390_SetPGID
  1254.  *
  1255.  * Set Path Group ID
  1256.  *
  1257.  */
  1258. int
  1259. s390_SetPGID (int irq, __u8 lpm)
  1260. {
  1261. ccw1_t *spid_ccw; /* ccw area for SPID command */
  1262. devstat_t devstat; /* required by request_irq() */
  1263. devstat_t *pdevstat = &devstat;
  1264. unsigned long flags;
  1265. char dbf_txt[15];
  1266. int irq_ret = 0; /* return code */
  1267. int retry = 5; /* retry count */
  1268. int inlreq = 0; /* inline request_irq() */
  1269. int mpath = 1; /* try multi-path first */
  1270. SANITY_CHECK (irq);
  1271. if (ioinfo[irq]->ui.flags.oper == 0) {
  1272. return (-ENODEV);
  1273. }
  1274.   if (ioinfo[irq]->ui.flags.unfriendly) {
  1275.   /* don't even try it */
  1276.   return -EUSERS;
  1277.   }
  1278. sprintf (dbf_txt, "SPID%x", irq);
  1279. CIO_TRACE_EVENT (4, dbf_txt);
  1280. if (!ioinfo[irq]->ui.flags.ready) {
  1281. /*
  1282.  * Perform SetPGID command processing. We have to request device
  1283.  *  ownership and provide a dummy I/O handler. We issue sync. I/O
  1284.  *  requests and evaluate the devstat area on return therefore
  1285.  *  we don't need a real I/O handler in place.
  1286.  */
  1287. irq_ret = request_irq (irq,
  1288.        init_IRQ_handler,
  1289.        SA_PROBE, "SPID", pdevstat);
  1290. if (irq_ret == 0)
  1291. inlreq = 1;
  1292. } else {
  1293. pdevstat = ioinfo[irq]->irq_desc.dev_id;
  1294. }
  1295. if (irq_ret) {
  1296. return irq_ret;
  1297. }
  1298. s390irq_spin_lock_irqsave (irq, flags);
  1299. if (init_IRQ_complete) {
  1300. spid_ccw = kmalloc (2 * sizeof (ccw1_t), GFP_DMA);
  1301. } else {
  1302. spid_ccw = alloc_bootmem_low (2 * sizeof (ccw1_t));
  1303. }
  1304. spid_ccw[0].cmd_code = CCW_CMD_SUSPEND_RECONN;
  1305. spid_ccw[0].cda = 0;
  1306. spid_ccw[0].count = 0;
  1307. spid_ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
  1308. spid_ccw[1].cmd_code = CCW_CMD_SET_PGID;
  1309. spid_ccw[1].cda = (__u32) virt_to_phys (&ioinfo[irq]->pgid);
  1310. spid_ccw[1].count = sizeof (pgid_t);
  1311. spid_ccw[1].flags = CCW_FLAG_SLI;
  1312. ioinfo[irq]->pgid.inf.fc = SPID_FUNC_MULTI_PATH | SPID_FUNC_ESTABLISH;
  1313. /*
  1314.  * We now issue a SetPGID request. In case of BUSY
  1315.  *  or STATUS PENDING conditions we retry 5 times.
  1316.  */
  1317. do {
  1318. memset (pdevstat, '', sizeof (devstat_t));
  1319. irq_ret = s390_start_IO (irq, spid_ccw, 0xE2D7C9C4, /* == SPID */
  1320.  lpm, /* n/a */
  1321.  DOIO_WAIT_FOR_INTERRUPT
  1322.  | DOIO_VALID_LPM
  1323.  | DOIO_DONT_CALL_INTHDLR
  1324.  | DOIO_TIMEOUT);
  1325. if (!irq_ret) {
  1326. if (pdevstat->flag & DEVSTAT_STATUS_PENDING) {
  1327. #ifdef CONFIG_DEBUG_IO
  1328. printk (KERN_DEBUG "SPID - Device %04X "
  1329. "on Subchannel %04X "
  1330. "reports pending status, "
  1331. "retry : %dn",
  1332. ioinfo[irq]->schib.pmcw.dev,
  1333. irq, retry);
  1334. #endif
  1335. CIO_MSG_EVENT(2,
  1336.       "SPID - Device %04X "
  1337.       "on Subchannel %04X "
  1338.       "reports pending status, "
  1339.       "retry : %dn",
  1340.       ioinfo[irq]->schib.pmcw.
  1341.       dev, irq, retry);
  1342. retry--;
  1343. irq_ret = -EIO;
  1344. }
  1345. if (pdevstat->flag == (DEVSTAT_START_FUNCTION
  1346.        | DEVSTAT_FINAL_STATUS)) {
  1347. retry = 0; /* successfully set ... */
  1348. irq_ret = 0;
  1349. } else if (pdevstat->flag & DEVSTAT_FLAG_SENSE_AVAIL) {
  1350. /*
  1351.  * If the device doesn't support the
  1352.  *  Sense Path Group ID command
  1353.  *  further retries wouldn't help ...
  1354.  */
  1355. if (pdevstat->ii.sense.
  1356.     data[0] & SNS0_CMD_REJECT) {
  1357. if (mpath) {
  1358. /*
  1359.  * We now try single path mode.
  1360.  * Note we must not issue the suspend
  1361.  * multipath reconnect, or we will get
  1362.  * a command reject by tapes.
  1363.  */
  1364. spid_ccw[0].cmd_code =
  1365.     CCW_CMD_SET_PGID;
  1366. spid_ccw[0].cda = (__u32)
  1367.     virt_to_phys (&ioinfo[irq]->pgid);
  1368. spid_ccw[0].count =
  1369.     sizeof (pgid_t);
  1370. spid_ccw[0].flags =
  1371.     CCW_FLAG_SLI;
  1372. ioinfo[irq]->pgid.inf.fc =
  1373.     SPID_FUNC_SINGLE_PATH
  1374.     | SPID_FUNC_ESTABLISH;
  1375. mpath = 0;
  1376. retry--;
  1377. irq_ret = -EIO;
  1378. } else {
  1379. irq_ret = -EOPNOTSUPP;
  1380. retry = 0;
  1381. }
  1382. } else {
  1383. #ifdef CONFIG_DEBUG_IO
  1384. printk (KERN_WARNING
  1385. "SPID - device %04X,"
  1386. " unit check,"
  1387. " retry %d, cnt %02d,"
  1388. " sns :"
  1389. " %02X%02X%02X%02X %02X%02X%02X%02X ...n",
  1390. ioinfo[irq]->schib.pmcw.
  1391. dev, retry,
  1392. pdevstat->scnt,
  1393. pdevstat->ii.sense.
  1394. data[0],
  1395. pdevstat->ii.sense.
  1396. data[1],
  1397. pdevstat->ii.sense.
  1398. data[2],
  1399. pdevstat->ii.sense.
  1400. data[3],
  1401. pdevstat->ii.sense.
  1402. data[4],
  1403. pdevstat->ii.sense.
  1404. data[5],
  1405. pdevstat->ii.sense.
  1406. data[6],
  1407. pdevstat->ii.sense.data[7]);
  1408. #endif
  1409. CIO_MSG_EVENT(2,
  1410.      "SPID - device %04X,"
  1411.      " unit check,"
  1412.      " retry %d, cnt %02d,"
  1413.      " sns :"
  1414.      " %02X%02X%02X%02X %02X%02X%02X%02X ...n",
  1415.      ioinfo[irq]->schib.
  1416.      pmcw.dev, retry,
  1417.      pdevstat->scnt,
  1418.      pdevstat->ii.sense.
  1419.      data[0],
  1420.      pdevstat->ii.sense.
  1421.      data[1],
  1422.      pdevstat->ii.sense.
  1423.      data[2],
  1424.      pdevstat->ii.sense.
  1425.      data[3],
  1426.      pdevstat->ii.sense.
  1427.      data[4],
  1428.      pdevstat->ii.sense.
  1429.      data[5],
  1430.      pdevstat->ii.sense.
  1431.      data[6],
  1432.      pdevstat->ii.sense.
  1433.      data[7]);
  1434. retry--;
  1435. irq_ret = -EIO;
  1436. }
  1437. } else if (pdevstat->flag & DEVSTAT_NOT_OPER) {
  1438. /* don't issue warnings during startup unless requested */
  1439. if (init_IRQ_complete || cio_notoper_msg) {
  1440. printk (KERN_WARNING
  1441. "SPID - Device %04X "
  1442. "on Subchannel %04X, "
  1443. "lpm %02X, "
  1444. "became 'not operational'n",
  1445. ioinfo[irq]->schib.pmcw.
  1446. dev, irq,
  1447. lpm);
  1448. CIO_MSG_EVENT(2,
  1449.      "SPID - Device %04X "
  1450.      "on Subchannel %04X, "
  1451.       "lpm %02X, "
  1452.      "became 'not operational'n",
  1453.      ioinfo[irq]->schib.
  1454.      pmcw.dev, irq,
  1455.      lpm);
  1456. }
  1457. retry = 0;
  1458. ioinfo[irq]->opm &= ~lpm;
  1459. irq_ret = -EAGAIN;
  1460. }
  1461. } else if (irq_ret == -ETIMEDOUT) {
  1462. /* 
  1463.  * SetPGID timed out, so we cancel it before
  1464.  * we retry
  1465.  */
  1466. int xret;
  1467. xret = cancel_IO(irq);
  1468. if (!xret) 
  1469. CIO_MSG_EVENT(2,
  1470.       "SetPGID: sch canceled "
  1471.       "successfully for irq %xn",
  1472.       irq);
  1473. retry--;
  1474. } else if (irq_ret != -ENODEV) {
  1475. retry--;
  1476. irq_ret = -EIO;
  1477. } else {
  1478. retry = 0;
  1479. irq_ret = -ENODEV;
  1480. }
  1481. } while (retry > 0);
  1482. if (init_IRQ_complete) {
  1483. kfree (spid_ccw);
  1484. } else {
  1485. free_bootmem ((unsigned long) spid_ccw, 2 * sizeof (ccw1_t));
  1486. }
  1487. s390irq_spin_unlock_irqrestore (irq, flags);
  1488. /*
  1489.  * If we installed the irq action handler we have to
  1490.  *  release it too.
  1491.  */
  1492. if (inlreq)
  1493. free_irq (irq, pdevstat);
  1494. return (irq_ret);
  1495. }
  1496. /*
  1497.  * s390_SensePGID
  1498.  *
  1499.  * Sense Path Group ID
  1500.  *
  1501.  */
  1502. int
  1503. s390_SensePGID (int irq, __u8 lpm, pgid_t * pgid)
  1504. {
  1505. ccw1_t *snid_ccw; /* ccw area for SNID command */
  1506. devstat_t devstat; /* required by request_irq() */
  1507. devstat_t *pdevstat = &devstat;
  1508. char dbf_txt[15];
  1509. pgid_t * tmp_pgid;
  1510. int irq_ret = 0; /* return code */
  1511. int retry = 5; /* retry count */
  1512. int inlreq = 0; /* inline request_irq() */
  1513. unsigned long flags;
  1514. SANITY_CHECK (irq);
  1515. if (ioinfo[irq]->ui.flags.oper == 0) {
  1516. return (-ENODEV);
  1517. }
  1518. sprintf (dbf_txt, "SNID%x", irq);
  1519. CIO_TRACE_EVENT (4, dbf_txt);
  1520. if (!ioinfo[irq]->ui.flags.ready) {
  1521. /*
  1522.  * Perform SENSE PGID command processing. We have to request device
  1523.  *  ownership and provide a dummy I/O handler. We issue sync. I/O
  1524.  *  requests and evaluate the devstat area on return therefore
  1525.  *  we don't need a real I/O handler in place.
  1526.  */
  1527. irq_ret = request_irq (irq,
  1528.        init_IRQ_handler,
  1529.        SA_PROBE, "SNID", pdevstat);
  1530. if (irq_ret == 0)
  1531. inlreq = 1;
  1532. } else {
  1533. pdevstat = ioinfo[irq]->irq_desc.dev_id;
  1534. }
  1535. if (irq_ret) {
  1536. return irq_ret;
  1537. }
  1538. s390irq_spin_lock_irqsave (irq, flags);
  1539. ioinfo[irq]->ui.flags.unfriendly = 0; /* assume it's friendly... */
  1540. if (init_IRQ_complete) {
  1541. snid_ccw = kmalloc (sizeof (ccw1_t), GFP_DMA);
  1542. tmp_pgid = kmalloc (sizeof (pgid_t), GFP_DMA);
  1543. } else {
  1544. snid_ccw = alloc_bootmem_low (sizeof (ccw1_t));
  1545. tmp_pgid = alloc_bootmem_low (sizeof (pgid_t));
  1546. }
  1547. snid_ccw->cmd_code = CCW_CMD_SENSE_PGID;
  1548. snid_ccw->cda = (__u32) virt_to_phys (tmp_pgid);
  1549. snid_ccw->count = sizeof (pgid_t);
  1550. snid_ccw->flags = CCW_FLAG_SLI;
  1551. /*
  1552.  * We now issue a SensePGID request. In case of BUSY
  1553.  *  or STATUS PENDING conditions we retry 5 times.
  1554.  */
  1555. do {
  1556. memset (pdevstat, '', sizeof (devstat_t));
  1557. irq_ret = s390_start_IO (irq, snid_ccw, 0xE2D5C9C4, /* == SNID */
  1558.  lpm, /* n/a */
  1559.  DOIO_WAIT_FOR_INTERRUPT
  1560.    | DOIO_TIMEOUT
  1561.  | DOIO_VALID_LPM
  1562.  | DOIO_DONT_CALL_INTHDLR);
  1563. if (irq_ret == 0) {
  1564. if (pdevstat->flag & DEVSTAT_FLAG_SENSE_AVAIL) {
  1565. /*
  1566.  * If the device doesn't support the
  1567.  *  Sense Path Group ID command
  1568.  *  further retries wouldn't help ...
  1569.  */
  1570. if (pdevstat->ii.sense.data[0] & 
  1571.     (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ)) {
  1572. retry = 0;
  1573. irq_ret = -EOPNOTSUPP;
  1574. } else {
  1575. #ifdef CONFIG_DEBUG_IO
  1576. printk (KERN_WARNING
  1577. "SNID - device %04X,"
  1578. " unit check,"
  1579. " flag %04X, "
  1580. " retry %d, cnt %02d,"
  1581. " sns :"
  1582. " %02X%02X%02X%02X %02X%02X%02X%02X ...n",
  1583. ioinfo[irq]->schib.pmcw.
  1584. dev, pdevstat->flag,
  1585. retry, pdevstat->scnt,
  1586. pdevstat->ii.sense.
  1587. data[0],
  1588. pdevstat->ii.sense.
  1589. data[1],
  1590. pdevstat->ii.sense.
  1591. data[2],
  1592. pdevstat->ii.sense.
  1593. data[3],
  1594. pdevstat->ii.sense.
  1595. data[4],
  1596. pdevstat->ii.sense.
  1597. data[5],
  1598. pdevstat->ii.sense.
  1599. data[6],
  1600. pdevstat->ii.sense.data[7]);
  1601. #endif
  1602. CIO_MSG_EVENT(2,
  1603.      "SNID - device %04X,"
  1604.      " unit check,"
  1605.      " flag %04X, "
  1606.      " retry %d, cnt %02d,"
  1607.      " sns :"
  1608.      " %02X%02X%02X%02X %02X%02X%02X%02X ...n",
  1609.      ioinfo[irq]->schib.
  1610.      pmcw.dev,
  1611.      pdevstat->flag,
  1612.      retry,
  1613.      pdevstat->scnt,
  1614.      pdevstat->ii.sense.
  1615.      data[0],
  1616.      pdevstat->ii.sense.
  1617.      data[1],
  1618.      pdevstat->ii.sense.
  1619.      data[2],
  1620.      pdevstat->ii.sense.
  1621.      data[3],
  1622.      pdevstat->ii.sense.
  1623.      data[4],
  1624.      pdevstat->ii.sense.
  1625.      data[5],
  1626.      pdevstat->ii.sense.
  1627.      data[6],
  1628.      pdevstat->ii.sense.
  1629.      data[7]);
  1630. retry--;
  1631. irq_ret = -EIO;
  1632. }
  1633. } else if (pdevstat->flag & DEVSTAT_NOT_OPER) {
  1634. /* don't issue warnings during startup unless requested */
  1635. if (init_IRQ_complete || cio_notoper_msg) {
  1636. printk (KERN_WARNING
  1637. "SNID - Device %04X "
  1638. "on Subchannel %04X, "
  1639. "lpm %02X, "
  1640. "became 'not operational'n",
  1641. ioinfo[irq]->schib.pmcw.
  1642. dev, irq,
  1643. lpm);
  1644. CIO_MSG_EVENT(2,
  1645.      "SNID - Device %04X "
  1646.      "on Subchannel %04X, "
  1647.      "lpm %02X, "
  1648.      "became 'not operational'n",
  1649.      ioinfo[irq]->schib.
  1650.      pmcw.dev, irq,
  1651.      lpm);
  1652. }
  1653. retry = 0;
  1654. irq_ret = -EIO;
  1655. } else {
  1656. retry = 0; /* success ... */
  1657. irq_ret = 0;
  1658.   /*
  1659.    * Check if device is locked by someone else
  1660.    * -- we'll fail other commands if that is
  1661.    * the case
  1662.    */
  1663.   if (pgid->inf.ps.state2 ==
  1664.       SNID_STATE2_RESVD_ELSE) {
  1665.   printk (KERN_WARNING 
  1666.   "SNID - Device %04X "
  1667.   "on Subchannel %04X "
  1668.   "is reserved by "
  1669.   "someone elsen",
  1670.   ioinfo[irq]->schib.pmcw.dev,
  1671.   irq);
  1672.   CIO_MSG_EVENT(2,
  1673.         "SNID - Device %04X "
  1674.         "on Subchannel %04X "
  1675.         "is reserved by "
  1676.         "someone elsen",
  1677.         ioinfo[irq]->schib.
  1678.         pmcw.dev,
  1679.         irq);
  1680.  
  1681.   ioinfo[irq]->ui.flags.unfriendly = 1;
  1682.   } else {
  1683.   /*
  1684.    * device is friendly to us :)
  1685.    */
  1686.   ioinfo[irq]->ui.flags.unfriendly = 0;
  1687.   }
  1688. memcpy(pgid, tmp_pgid, sizeof(pgid_t));
  1689. }
  1690.   } else if (irq_ret == -ETIMEDOUT) {
  1691. #ifdef CONFIG_DEBUG_IO
  1692.   printk(KERN_INFO "SNID - Operation timed out "
  1693.          "on Device %04X, Subchannel %04X... "
  1694.          "cancelling IOn",
  1695.          ioinfo[irq]->schib.pmcw.dev,
  1696.          irq);
  1697. #endif /* CONFIG_DEBUG_IO */
  1698.   CIO_MSG_EVENT(2,
  1699.         "SNID - Operation timed out "
  1700.         "on Device %04X, Subchannel %04X... "
  1701.         "cancelling IOn",
  1702.         ioinfo[irq]->schib.pmcw.dev,
  1703.         irq);
  1704.   cancel_IO(irq);
  1705.   retry--;
  1706. } else if (irq_ret != -ENODEV) { /* -EIO, or -EBUSY */
  1707. if (pdevstat->flag & DEVSTAT_STATUS_PENDING) {
  1708. #ifdef CONFIG_DEBUG_IO
  1709. printk (KERN_INFO "SNID - Device %04X "
  1710. "on Subchannel %04X "
  1711. "reports pending status, "
  1712. "retry : %dn",
  1713. ioinfo[irq]->schib.pmcw.dev,
  1714. irq, retry);
  1715. #endif
  1716. CIO_MSG_EVENT(2,
  1717.      "SNID - Device %04X "
  1718.      "on Subchannel %04X "
  1719.      "reports pending status, "
  1720.      "retry : %dn",
  1721.      ioinfo[irq]->schib.pmcw.
  1722.      dev, irq, retry);
  1723. }
  1724. printk (KERN_WARNING "SNID - device %04X,"
  1725. " start_io() reports rc : %d, retrying ...n",
  1726. ioinfo[irq]->schib.pmcw.dev, irq_ret);
  1727. CIO_MSG_EVENT(2,
  1728.       "SNID - device %04X,"
  1729.       " start_io() reports rc : %d,"
  1730.       " retrying ...n",
  1731.       ioinfo[irq]->schib.pmcw.dev, irq_ret);
  1732. retry--;
  1733. irq_ret = -EIO;
  1734. } else { /* -ENODEV ... */
  1735. retry = 0;
  1736. irq_ret = -ENODEV;
  1737. }
  1738. } while (retry > 0);
  1739. if (init_IRQ_complete) {
  1740. kfree (snid_ccw);
  1741. kfree (tmp_pgid);
  1742. } else {
  1743. free_bootmem ((unsigned long) snid_ccw, sizeof (ccw1_t));
  1744. free_bootmem ((unsigned long) tmp_pgid, sizeof (pgid_t));
  1745. }
  1746. s390irq_spin_unlock_irqrestore (irq, flags);
  1747. /*
  1748.  * If we installed the irq action handler we have to
  1749.  *  release it too.
  1750.  */
  1751. if (inlreq)
  1752. free_irq (irq, pdevstat);
  1753. return (irq_ret);
  1754. }
  1755. void
  1756. s390_process_subchannel_source (int irq)
  1757. {
  1758. int dev_oper = 0;
  1759. int dev_no = -1;
  1760. int lock = 0;
  1761. int is_owned = 0;
  1762. /*
  1763.  * If the device isn't known yet
  1764.  *   we can't lock it ...
  1765.  */
  1766. if (ioinfo[irq] != INVALID_STORAGE_AREA) {
  1767. s390irq_spin_lock (irq);
  1768. lock = 1;
  1769. if (!ioinfo[irq]->st) {
  1770. dev_oper = ioinfo[irq]->ui.flags.oper;
  1771. if (ioinfo[irq]->ui.flags.dval)
  1772. dev_no = ioinfo[irq]->devno;
  1773. is_owned = ioinfo[irq]->ui.flags.ready;
  1774. }
  1775. }
  1776. #ifdef CONFIG_DEBUG_CRW
  1777. printk (KERN_DEBUG
  1778. "do_crw_pending : subchannel validation - start ...n");
  1779. #endif
  1780. CIO_CRW_EVENT(4, "subchannel validation - startn");
  1781. s390_validate_subchannel (irq, is_owned);
  1782. if (irq > highest_subchannel)
  1783. highest_subchannel = irq;
  1784. #ifdef CONFIG_DEBUG_CRW
  1785. printk (KERN_DEBUG "do_crw_pending : subchannel validation - donen");
  1786. #endif
  1787. CIO_CRW_EVENT(4, "subchannel validation - donen");
  1788. /*
  1789.  * After the validate processing
  1790.  *   the ioinfo control block
  1791.  *   should be allocated ...
  1792.  */
  1793. if (lock) {
  1794. s390irq_spin_unlock (irq);
  1795. }
  1796. if (ioinfo[irq] != INVALID_STORAGE_AREA) {
  1797. #ifdef CONFIG_DEBUG_CRW
  1798. printk (KERN_DEBUG "do_crw_pending : ioinfo at "
  1799. #ifdef CONFIG_ARCH_S390X
  1800. "%08lXn", (unsigned long) ioinfo[irq]
  1801. #else /* CONFIG_ARCH_S390X */
  1802. "%08Xn", (unsigned) ioinfo[irq]
  1803. #endif /* CONFIG_ARCH_S390X */
  1804. );
  1805. #endif
  1806. #ifdef CONFIG_ARCH_S390X
  1807. CIO_CRW_EVENT(4, "ioinfo at %08lXn", 
  1808.       (unsigned long)ioinfo[irq]);
  1809. #else /* CONFIG_ARCH_S390X */
  1810. CIO_CRW_EVENT(4, "ioinfo at %08Xn", 
  1811.       (unsigned)ioinfo[irq]);
  1812. #endif /* CONFIG_ARCH_S390X */
  1813. if (ioinfo[irq]->st)
  1814. return;
  1815. if (ioinfo[irq]->ui.flags.oper == 0) {
  1816. not_oper_handler_func_t nopfunc = ioinfo[irq]->nopfunc;
  1817. #ifdef CONFIG_PROC_FS
  1818. /* remove procfs entry */
  1819. if (cio_proc_devinfo)
  1820. cio_procfs_device_remove (dev_no);
  1821. #endif
  1822. /*
  1823.  * If the device has gone
  1824.  *  call not oper handler               
  1825.  */
  1826. if ((dev_oper == 1)
  1827.     && (nopfunc != NULL)) {
  1828. free_irq (irq, ioinfo[irq]->irq_desc.dev_id);
  1829. nopfunc (irq, DEVSTAT_DEVICE_GONE);
  1830. }
  1831. } else {
  1832. #ifdef CONFIG_DEBUG_CRW
  1833. printk (KERN_DEBUG
  1834. "do_crw_pending : device "
  1835. "recognition - start ...n");
  1836. #endif
  1837. CIO_CRW_EVENT( 4,
  1838.        "device recognition - startn");
  1839. s390_device_recognition_irq (irq);
  1840. #ifdef CONFIG_DEBUG_CRW
  1841. printk (KERN_DEBUG
  1842. "do_crw_pending : device "
  1843. "recognition - donen");
  1844. #endif
  1845. CIO_CRW_EVENT( 4,
  1846.        "device recognition - donen");
  1847. /*
  1848.  * the device became operational
  1849.  */
  1850. if (dev_oper == 0) {
  1851. devreg_t *pdevreg;
  1852. pdevreg = s390_search_devreg (ioinfo[irq]);
  1853. if (pdevreg != NULL) {
  1854. if (pdevreg->oper_func != NULL)
  1855. pdevreg->
  1856.     oper_func (irq, pdevreg);
  1857. }
  1858. #ifdef CONFIG_PROC_FS
  1859. /* add new procfs entry */
  1860. if (cio_proc_devinfo)
  1861. if (highest_subchannel <
  1862.     MAX_CIO_PROCFS_ENTRIES) {
  1863. cio_procfs_device_create
  1864.     (ioinfo[irq]->devno);
  1865. }
  1866. #endif
  1867. }
  1868. /*
  1869.  * ... it is and was operational, but
  1870.  *      the devno may have changed
  1871.  */
  1872. else if ((ioinfo[irq]->devno != dev_no)
  1873.  && (ioinfo[irq]->nopfunc != NULL)) {
  1874. #ifdef CONFIG_PROC_FS
  1875. int devno_old = ioinfo[irq]->devno;
  1876. #endif
  1877. ioinfo[irq]->nopfunc (irq, DEVSTAT_REVALIDATE);
  1878. #ifdef CONFIG_PROC_FS
  1879. /* remove old entry, add new */
  1880. if (cio_proc_devinfo) {
  1881. cio_procfs_device_remove (devno_old);
  1882. cio_procfs_device_create
  1883.     (ioinfo[irq]->devno);
  1884. }
  1885. #endif
  1886. }
  1887. }
  1888. #ifdef CONFIG_PROC_FS
  1889. /* get rid of dead procfs entries */
  1890. if (cio_proc_devinfo)
  1891. cio_procfs_device_purge ();
  1892. #endif
  1893. }
  1894. }
  1895. #ifdef CONFIG_CHSC
  1896. static int 
  1897. chsc_get_sch_desc_irq(int irq)
  1898. {
  1899. int j = 0;
  1900. int ccode;
  1901. spin_lock(&chsc_lock_ssd);
  1902. if (!chsc_area_ssd)
  1903. chsc_area_ssd = kmalloc(sizeof(chsc_area_t),GFP_KERNEL);
  1904. if (!chsc_area_ssd) {
  1905. printk( KERN_CRIT "No memory to determine sch descriptions...n");
  1906. spin_unlock(&chsc_lock_ssd);
  1907. return -ENOMEM;
  1908. }
  1909. memset(chsc_area_ssd, 0, sizeof(chsc_area_t));
  1910. chsc_area_ssd->request_block.command_code1=0x0010;
  1911. chsc_area_ssd->request_block.command_code2=0x0004;
  1912. chsc_area_ssd->request_block.request_block_data.ssd_req.f_sch=irq;
  1913. chsc_area_ssd->request_block.request_block_data.ssd_req.l_sch=irq;
  1914. ccode = chsc(chsc_area_ssd);
  1915. #ifdef CONFIG_DEBUG_CHSC
  1916. if (ccode)
  1917. printk( KERN_DEBUG "chsc returned with ccode = %dn",ccode);
  1918. #endif /* CONFIG_DEBUG_CHSC */
  1919. if (!ccode) {
  1920. if (chsc_area_ssd->response_block.response_code == 0x0003) {
  1921. #ifdef CONFIG_DEBUG_CHSC
  1922. printk( KERN_WARNING "Error in chsc request block!n");
  1923. #endif /* CONFIG_DEBUG_CHSC */
  1924. CIO_CRW_EVENT( 2, "Error in chsc request block!n");
  1925. spin_unlock(&chsc_lock_ssd);
  1926. return -EINVAL;
  1927. } else if (chsc_area_ssd->response_block.response_code == 0x0004) {
  1928. #ifdef CONFIG_DEBUG_CHSC
  1929. printk( KERN_WARNING "Model does not provide ssdn");
  1930. #endif /* CONFIG_DEBUG_CHSC */
  1931. CIO_CRW_EVENT( 2, "Model does not provide ssdn");
  1932. spin_unlock(&chsc_lock_ssd);
  1933. return -EOPNOTSUPP;
  1934. } else if (chsc_area_ssd->response_block.response_code == 0x0002) {
  1935. #ifdef CONFIG_DEBUG_CHSC
  1936. printk( KERN_WARNING "chsc: Invalid command!n");
  1937. #endif /* CONFIG_DEBUG_CHSC */
  1938. CIO_CRW_EVENT( 2,
  1939.        "chsc: Invalid command!n");
  1940. return -EINVAL;
  1941. } else if (chsc_area_ssd->response_block.response_code == 0x0001) {
  1942. /* everything ok */
  1943. switch (chsc_area_ssd->response_block.response_block_data.ssd_res.st) {
  1944. case 0:  /* I/O subchannel */
  1945. /* 
  1946.  * All fields have meaning
  1947.  */
  1948. #ifdef CONFIG_DEBUG_CHSC
  1949. if (cio_show_msg) 
  1950. printk( KERN_DEBUG 
  1951. "ssd: sch %x is I/O subchanneln",
  1952. irq);
  1953. #endif /* CONFIG_DEBUG_CHSC */
  1954. CIO_CRW_EVENT( 6,
  1955.        "ssd: sch %x is I/O subchanneln",
  1956.        irq);
  1957. if (ioinfo[irq] == INVALID_STORAGE_AREA)
  1958. /* FIXME: we should do device rec. here... */
  1959. break;
  1960. ioinfo[irq]->ssd_info.valid = 1;
  1961. ioinfo[irq]->ssd_info.type = 0;
  1962. for (j=0;j<8;j++) {
  1963. if ((0x80 >> j) & 
  1964.     chsc_area_ssd->response_block.
  1965.     response_block_data.ssd_res.path_mask & 
  1966.     chsc_area_ssd->response_block.
  1967.     response_block_data.ssd_res.fla_valid_mask) {
  1968. if (chsc_area_ssd->response_block.
  1969.     response_block_data.ssd_res.chpid[j]) 
  1970. if (!test_and_set_bit
  1971.     (chsc_area_ssd->response_block.
  1972.      response_block_data.
  1973.      ssd_res.chpid[j],
  1974.      &chpids_known)) 
  1975. if (test_bit
  1976.     (chsc_area_ssd->response_block.
  1977.      response_block_data.
  1978.      ssd_res.chpid[j],
  1979.      &chpids_logical))
  1980. set_bit(chsc_area_ssd->response_block.
  1981. response_block_data.
  1982. ssd_res.chpid[j],
  1983. &chpids);
  1984. ioinfo[irq]->ssd_info.chpid[j] = 
  1985. chsc_area_ssd->response_block.
  1986. response_block_data.ssd_res.chpid[j];
  1987. ioinfo[irq]->ssd_info.fla[j] = 
  1988. chsc_area_ssd->response_block.
  1989. response_block_data.ssd_res.fla[j];
  1990. }
  1991. }
  1992. break;
  1993. case 1:  /* CHSC subchannel */
  1994. /*
  1995.  * Only sch_val, st and sch have meaning
  1996.  */
  1997. #ifdef CONFIG_DEBUG_CHSC
  1998. if (cio_show_msg)
  1999. printk( KERN_DEBUG 
  2000. "ssd: sch %x is chsc subchanneln",
  2001. irq);
  2002. #endif /* CONFIG_DEBUG_CHSC */
  2003. CIO_CRW_EVENT( 6,
  2004.        "ssd: sch %x is chsc subchanneln",
  2005.        irq);
  2006. if (ioinfo[irq] == INVALID_STORAGE_AREA)
  2007. /* FIXME: we should do device rec. here... */
  2008. break;
  2009. ioinfo[irq]->ssd_info.valid = 1;
  2010. ioinfo[irq]->ssd_info.type = 1;
  2011. break;
  2012. case 2: /* Message subchannel */
  2013. /*
  2014.  * All fields except unit_addr have meaning
  2015.  */
  2016. #ifdef CONFIG_DEBUG_CHSC
  2017. if (cio_show_msg)
  2018. printk( KERN_DEBUG 
  2019. "ssd: sch %x is message subchanneln",
  2020. irq);
  2021. #endif
  2022. CIO_CRW_EVENT( 6,
  2023.        "ssd: sch %x is message subchanneln",
  2024.        irq);
  2025. if (ioinfo[irq] == INVALID_STORAGE_AREA)
  2026. /* FIXME: we should do device rec. here... */
  2027. break;
  2028. ioinfo[irq]->ssd_info.valid = 1;
  2029. ioinfo[irq]->ssd_info.type = 2;
  2030. for (j=0;j<8;j++) {
  2031. if ((0x80 >> j) & 
  2032.     chsc_area_ssd->response_block.
  2033.     response_block_data.ssd_res.path_mask & 
  2034.     chsc_area_ssd->response_block.
  2035.     response_block_data.ssd_res.fla_valid_mask) {
  2036. if (chsc_area_ssd->response_block.
  2037.     response_block_data.ssd_res.chpid[j])
  2038. if (!test_and_set_bit
  2039.     (chsc_area_ssd->response_block.
  2040.      response_block_data.
  2041.      ssd_res.chpid[j],
  2042.      &chpids_known)) 
  2043. if (test_bit
  2044.     (chsc_area_ssd->response_block.
  2045.      response_block_data.
  2046.      ssd_res.chpid[j],
  2047.      &chpids_logical))
  2048. set_bit(chsc_area_ssd->response_block.
  2049. response_block_data.
  2050. ssd_res.chpid[j],
  2051. &chpids);
  2052. ioinfo[irq]->ssd_info.chpid[j] = 
  2053. chsc_area_ssd->response_block.
  2054. response_block_data.ssd_res.chpid[j];
  2055. ioinfo[irq]->ssd_info.fla[j] = 
  2056. chsc_area_ssd->response_block.
  2057. response_block_data.ssd_res.fla[j];
  2058. }
  2059. }
  2060. break;
  2061. case 3: /* ADM subchannel */
  2062. /*
  2063.  * Only sch_val, st and sch have meaning
  2064.  */
  2065. #ifdef CONFIG_DEBUG_CHSC
  2066. if (cio_show_msg) 
  2067. printk( KERN_DEBUG 
  2068. "ssd: sch %x is ADM subchanneln",
  2069. irq);
  2070. #endif /* CONFIG_DEBUG_CHSC */
  2071. CIO_CRW_EVENT( 6,
  2072.        "ssd: sch %x is ADM subchanneln",
  2073.        irq);
  2074. if (ioinfo[irq] == INVALID_STORAGE_AREA)
  2075. /* FIXME: we should do device rec. here... */
  2076. break;
  2077. ioinfo[irq]->ssd_info.valid = 1;
  2078. ioinfo[irq]->ssd_info.type = 3;
  2079. break;
  2080. default: /* uhm, that looks strange... */
  2081. #ifdef CONFIG_DEBUG_CHSC
  2082. if (cio_show_msg) 
  2083. printk( KERN_DEBUG 
  2084. "Strange subchannel type %d for sch %xn", 
  2085. chsc_area_ssd->response_block.
  2086. response_block_data.ssd_res.st,
  2087. irq);
  2088. #endif /* CONFIG_DEBUG_CHSC */
  2089. CIO_CRW_EVENT( 0, 
  2090.        "Strange subchannel type %d for "
  2091.        "sch %xn", 
  2092.        chsc_area_ssd->response_block.
  2093.        response_block_data.ssd_res.st,
  2094.        irq);
  2095. }
  2096. spin_unlock(&chsc_lock_ssd);
  2097. return 0;
  2098. }
  2099. } else {
  2100. spin_unlock(&chsc_lock_ssd);
  2101. if (ccode == 3)
  2102. return -ENODEV;
  2103. return -EBUSY;
  2104. }
  2105. return -EIO;
  2106. }
  2107. static int 
  2108. chsc_get_sch_descriptions( void )
  2109. {
  2110. int irq = 0;
  2111. int err = 0;
  2112. CIO_TRACE_EVENT( 4, "gsdesc");
  2113. /*
  2114.  * get information about chpids and link addresses 
  2115.  * by executing the chsc command 'store subchannel description'
  2116.  */
  2117. if (init_IRQ_complete) {
  2118. for (irq=0; irq<=highest_subchannel; irq++) {
  2119. /*
  2120.  * retrieve information for each sch
  2121.  */
  2122. err = chsc_get_sch_desc_irq(irq);
  2123. if (err) {
  2124. if (!cio_chsc_err_msg) {
  2125. printk( KERN_ERR
  2126. "chsc_get_sch_descriptions:"
  2127. " Error %d while doing chsc; "
  2128. "processing "
  2129. "some machine checks may "
  2130. "not workn", 
  2131. err);
  2132. cio_chsc_err_msg=1;
  2133. }
  2134. return err;
  2135. }
  2136. }
  2137. cio_chsc_desc_avail = 1;
  2138. return 0;
  2139. } else {
  2140. /* Paranoia... */
  2141. printk( KERN_ERR 
  2142. "Error: chsc_get_sch_descriptions called before "
  2143.        "initialization completen");
  2144. return -EINVAL;
  2145. }
  2146. }
  2147. __initcall(chsc_get_sch_descriptions);
  2148. void 
  2149. s390_do_chpid_processing( __u8 chpid)
  2150. {
  2151. int irq;
  2152. int j;
  2153. int mask;
  2154. char dbf_txt[15];
  2155. int ccode;
  2156. int was_oper;
  2157. int chp = 0;
  2158. int mask2;
  2159. int ret = 0;
  2160. sprintf(dbf_txt, "chpr%x", chpid);
  2161. CIO_TRACE_EVENT( 2, dbf_txt);
  2162. /* 
  2163.  * TODO: the chpid may be not the chpid with the link incident,
  2164.  * but the chpid the report came in through. How to handle???
  2165.  */
  2166. clear_bit(chpid, &chpids);
  2167. if (!test_and_clear_bit(chpid, &chpids_known))
  2168. return;  /* we didn't know the chpid anyway */
  2169. for (irq=0;irq<=highest_subchannel;irq++) {
  2170. if (ioinfo[irq] == INVALID_STORAGE_AREA) 
  2171. continue;  /* we don't know the device anyway */
  2172. if (ioinfo[irq]->st)
  2173. continue; /* non-io subchannel */
  2174. for (j=0; j<8;j++) {
  2175. if (ioinfo[irq]->schib.pmcw.chpid[j] == chpid) {
  2176. /*
  2177.  * Send nops down each path to find out
  2178.  * which path is gone (ssch will yield cc=3 
  2179.  * and the path will be switched off in the opm)
  2180.  */
  2181. /* 
  2182.  * Note: irq spinlock is grabbed several times
  2183.  * in here
  2184.  */
  2185. for (chp=0;chp<=7;chp++) {
  2186. mask2 = 0x80 >> chp;
  2187. if (mask2 & ioinfo[irq]->opm)
  2188. ret = s390_send_nop (irq, mask2);
  2189. }
  2190. s390irq_spin_lock(irq);
  2191. /*
  2192.  * FIXME: is this neccessary?
  2193.  */
  2194. ccode = stsch(irq, &ioinfo[irq]->schib);
  2195. if (ccode) {
  2196. #ifdef CONFIG_DEBUG_CRW
  2197. printk( KERN_WARNING 
  2198. "do_crw_pending: device on "
  2199. "sch %x is not operationaln",
  2200. irq);
  2201. #endif /* CONFIG_DEBUG_CRW */
  2202. CIO_CRW_EVENT( 2,
  2203.        "device on sch %x is "
  2204.        "not operationaln",
  2205.        irq);
  2206. ioinfo[irq]->ui.flags.oper = 0;
  2207. break;
  2208. }
  2209. ioinfo[irq]->opm = ioinfo[irq]->schib.pmcw.pim &
  2210. ioinfo[irq]->schib.pmcw.pam &
  2211. ioinfo[irq]->schib.pmcw.pom;
  2212. if (ioinfo[irq]->opm) {
  2213. for (chp=0;chp<=7;chp++) {
  2214. mask2 = 0x80 >> chp;
  2215. if (ioinfo[irq]->opm & mask2) {
  2216. if (!test_bit
  2217.     (ioinfo[irq]->
  2218.      schib.pmcw.chpid[chp], 
  2219.      &chpids_logical)) {
  2220. /* disable using this path */
  2221. ioinfo[irq]->opm 
  2222. &= ~mask2;
  2223. }
  2224. }
  2225. }
  2226. }
  2227. if (!ioinfo[irq]->opm) {
  2228. /*
  2229.  * sh*t, our last path has gone...
  2230.  * Set the device status to not operational
  2231.  * and eventually notify the device driver
  2232.  */
  2233. #ifdef CONFIG_DEBUG_CRW
  2234. printk( KERN_WARNING 
  2235. "do_crw_pending: Last path gone for "
  2236. "device %x, sch %xn",
  2237. ioinfo[irq]->devno, irq);
  2238. #endif /* CONFIG_DEBUG_CRW */
  2239. CIO_CRW_EVENT( 2,
  2240.        "Last path gone for "
  2241.        "device %x, sch %xn",
  2242.        ioinfo[irq]->devno,
  2243.        irq);
  2244. was_oper = ioinfo[irq]->ui.flags.oper;
  2245. ioinfo[irq]->ui.flags.oper = 0;
  2246. if (was_oper && ioinfo[irq]->ui.flags.ready) {
  2247. not_oper_handler_func_t nopfunc = 
  2248. ioinfo[irq]->nopfunc;
  2249. #ifdef CONFIG_PROC_FS
  2250. if (cio_proc_devinfo)
  2251. cio_procfs_device_remove
  2252. (ioinfo[irq]->devno);
  2253. #endif /* CONFIG_PROC_FS */
  2254. free_irq(irq, 
  2255.  ioinfo[irq]->irq_desc.dev_id);
  2256. if (nopfunc)
  2257. nopfunc(irq, 
  2258. DEVSTAT_DEVICE_GONE);
  2259. }
  2260. } else if (ioinfo[irq]->ui.flags.ready) {
  2261. /* 
  2262.  * Re-do path verification for the chpid in question
  2263.  * FIXME: is this neccessary?
  2264.  */
  2265. mask = 0x80 >> j;
  2266. if (!s390_DevicePathVerification(irq,mask)) {
  2267. #ifdef CONFIG_DEBUG_CRW
  2268. printk( KERN_DEBUG 
  2269. "DevicePathVerification "
  2270. "successful for"
  2271. " Subchannel %x, "
  2272. "chpid %xn",
  2273. irq, chpid);
  2274. #endif /* CONFIG_DEBUG_CRW */
  2275. CIO_CRW_EVENT( 2,
  2276.        "DevicePathVerification "
  2277.        "successful for"
  2278.        " Subchannel %x, "
  2279.        "chpid %xn",
  2280.        irq, chpid);
  2281. }
  2282. }
  2283. j=8;
  2284. s390irq_spin_unlock(irq);
  2285. }
  2286. }
  2287. }
  2288. }
  2289. void 
  2290. s390_do_res_acc_processing( __u8 chpid, __u16 fla, int info)
  2291. {
  2292. char dbf_txt[15];
  2293. int irq = 0;
  2294. int ccode;
  2295. __u32 fla_mask = 0xffff;
  2296. int chp;
  2297. int mask, mask2;
  2298. int ret;
  2299. sprintf(dbf_txt, "accp%x", chpid);
  2300. CIO_TRACE_EVENT( 2, dbf_txt);
  2301. if (info != CHSC_SEI_ACC_CHPID) {
  2302. sprintf(dbf_txt, "fla%x", fla);
  2303. CIO_TRACE_EVENT( 2, dbf_txt);
  2304. }
  2305. sprintf(dbf_txt, "info:%d", info);
  2306. CIO_TRACE_EVENT( 2, dbf_txt);
  2307. /*
  2308.  * I/O resources may have become accessible.
  2309.  * Scan through all subchannels that may be concerned and
  2310.  * do a validation on those.
  2311.  * The more information we have (info), the less scanning
  2312.  * will we have to do.
  2313.  */
  2314. if (!cio_chsc_desc_avail) 
  2315. chsc_get_sch_descriptions();
  2316. if (!cio_chsc_desc_avail) {
  2317. /*
  2318.  * Something went wrong...
  2319.  */
  2320. #ifdef CONFIG_DEBUG_CRW
  2321. printk( KERN_WARNING 
  2322. "Error: Could not retrieve subchannel descriptions, "
  2323.        "will not process css machine check...n");
  2324. #endif /* CONFIG_DEBUG_CRW */
  2325. CIO_CRW_EVENT( 0,
  2326.        "Error: Could not retrieve subchannel descriptions, "
  2327.        "will not process css machine check...n");
  2328. return;
  2329. if (!test_bit(chpid, &chpids_logical))
  2330. return; /* no need to do the rest */
  2331. switch (info) {
  2332. case CHSC_SEI_ACC_CHPID: /*
  2333.   * worst case, we only know about the chpid
  2334.   * the devices are attached to
  2335.   */
  2336. #ifdef CONFIG_DEBUG_CHSC
  2337. printk( KERN_DEBUG "Looking at chpid %x...n", chpid);
  2338. #endif /* CONFIG_DEBUG_CHSC */
  2339. for (irq=0; irq<=__MAX_SUBCHANNELS; irq++) {
  2340. if((ioinfo[irq] != INVALID_STORAGE_AREA) 
  2341.    && (!ioinfo[irq]->st)) {
  2342. /*
  2343.  * Send nops down each path to find out
  2344.  * which path is there 
  2345.  */
  2346. for (chp=0;chp<=7;chp++) {
  2347. mask = 0x80 >> chp;
  2348. /*
  2349.  * check if chpid is in information
  2350.  * updated by ssd
  2351.  */
  2352. if ((ioinfo[irq]->ssd_info.valid) &&
  2353.     (ioinfo[irq]->ssd_info.chpid[chp]
  2354.      == chpid))
  2355. ret = s390_send_nop (irq, mask);
  2356. }
  2357. ccode = stsch(irq, &ioinfo[irq]->schib);
  2358. if (!ccode) {
  2359. ioinfo[irq]->opm = 
  2360. ioinfo[irq]->schib.pmcw.pim &
  2361. ioinfo[irq]->schib.pmcw.pam &
  2362. ioinfo[irq]->schib.pmcw.pom;
  2363. if (ioinfo[irq]->opm) {
  2364. for (chp=0;chp<=7;chp++) {
  2365. mask = 0x80 >> chp;
  2366. if (ioinfo[irq]->opm 
  2367.     & mask) {
  2368. if (!test_bit
  2369.     (ioinfo[irq]->
  2370.      schib.pmcw.chpid[chp], 
  2371.      &chpids_logical)) {
  2372. /* disable using this path */
  2373. ioinfo[irq]->opm 
  2374. &= ~mask;
  2375. }
  2376. }
  2377. }
  2378. }
  2379. if ((ioinfo[irq]->ui.flags.ready) 
  2380.     && (chpid & ioinfo[irq]->opm))
  2381. s390_DevicePathVerification(irq, chpid);
  2382. } else {
  2383. ioinfo[irq]->ui.flags.oper = 0;
  2384. }
  2385. } else if (ioinfo[irq] == INVALID_STORAGE_AREA) {
  2386. /*
  2387.  * We don't know the device yet, but since a path
  2388.  * may be available now to the device we'll have
  2389.  * to do recognition again.
  2390.  * Since we don't have any idea about which chpid
  2391.  * that beast may be on we'll have to do a stsch
  2392.  * on all devices, grr...
  2393.  */
  2394. int valret = 0;
  2395. valret = s390_validate_subchannel(irq,0);
  2396. if (valret == -ENXIO) {
  2397. /* We're through */
  2398. return;
  2399. }
  2400. if (irq > highest_subchannel)
  2401. highest_subchannel = irq;
  2402. if (valret == 0)
  2403. s390_device_recognition_irq(irq);
  2404. }
  2405. }
  2406. break;
  2407. case CHSC_SEI_ACC_LINKADDR: /*
  2408.      * better, we know the link determined by
  2409.      * the link address and the chpid
  2410.      */
  2411. fla_mask = 0xff00;
  2412. /* fallthrough */
  2413. case CHSC_SEI_ACC_FULLLINKADDR: /*
  2414.  * best case, we know the CU image
  2415.  * by chpid and full link address
  2416.  */
  2417. #ifdef CONFIG_DEBUG_CHSC
  2418. printk( KERN_DEBUG "Looking at chpid %x, link addr %x...n", 
  2419. chpid, fla);
  2420. #endif /* CONFIG_DEBUG_CHSC */
  2421. for (irq=0; irq<=__MAX_SUBCHANNELS; irq++) {
  2422. /*
  2423.  * Walk through all subchannels and
  2424.  * look if our chpid and our (masked) link 
  2425.  * address are in somewhere
  2426.  * Do a stsch for the found subchannels and
  2427.  * perform path grouping  
  2428.  */
  2429. if ((ioinfo[irq] != INVALID_STORAGE_AREA) 
  2430.     && (!ioinfo[irq]->st)) {
  2431. int j;
  2432. /* Update our ssd_info */
  2433. if (chsc_get_sch_desc_irq(irq)) 
  2434. break;
  2435. for (j=0;j<8;j++) {
  2436. if ((ioinfo[irq]->ssd_info.chpid[j] == chpid) &&
  2437.     ((ioinfo[irq]->ssd_info.fla[j]&fla_mask) == fla)) {
  2438. mask2 = 0x80 >> j;
  2439. ret = s390_send_nop (irq, mask2);
  2440. ccode = stsch(irq,&ioinfo[irq]->schib);
  2441. if (!ccode) {
  2442. ioinfo[irq]->opm = 
  2443. ioinfo[irq]->schib.pmcw.pim &
  2444. ioinfo[irq]->schib.pmcw.pam &
  2445. ioinfo[irq]->schib.pmcw.pom;
  2446. if (ioinfo[irq]->opm) {
  2447. for (chp=0;chp<=7;chp++) {
  2448. mask = 0x80 >> chp;
  2449. if (ioinfo[irq]->opm 
  2450.     & mask) {
  2451. if (!test_bit
  2452.     (ioinfo[irq]->
  2453.      schib.pmcw.chpid[chp], 
  2454.      &chpids_logical)) {
  2455. /* disable using this path */
  2456. ioinfo[irq]->opm 
  2457. &= ~mask;
  2458. }
  2459. }
  2460. }
  2461. }
  2462. if (ioinfo[irq]->ui.flags.ready)
  2463. s390_DevicePathVerification(irq, chpid);
  2464. }
  2465. break;
  2466. }
  2467. }
  2468. } else if (ioinfo[irq] == INVALID_STORAGE_AREA) {
  2469. /* The full program again (see above), grr... */
  2470. int valret = 0;
  2471. valret = s390_validate_subchannel(irq,0);
  2472. if (valret == -ENXIO) {
  2473. /* We're done */
  2474. return;
  2475. }
  2476. if (irq > highest_subchannel)
  2477. highest_subchannel = irq;
  2478. if (valret == 0)
  2479. s390_device_recognition_irq(irq);
  2480. }
  2481. }
  2482. break;
  2483. default: BUG();
  2484. }
  2485. }
  2486. void 
  2487. s390_process_css( void ) 
  2488. {
  2489. int ccode;
  2490. CIO_TRACE_EVENT( 2, "prcss");
  2491. spin_lock(&chsc_lock_sei);
  2492. if (!chsc_area_sei) {
  2493. if (init_IRQ_complete) 
  2494. chsc_area_sei = kmalloc(sizeof(chsc_area_t),GFP_KERNEL);
  2495. else
  2496. chsc_area_sei = alloc_bootmem(sizeof(chsc_area_t));
  2497. }
  2498. if (!chsc_area_sei) {
  2499. printk( KERN_CRIT 
  2500. "No memory to store event information...n");
  2501. spin_unlock(&chsc_lock_sei);
  2502. return;
  2503. }
  2504. /* 
  2505.  * build the chsc request block for store event information 
  2506.  * and do the call 
  2507.  */
  2508. memset(chsc_area_sei,0,sizeof(chsc_area_t));
  2509. chsc_area_sei->request_block.command_code1=0x0010;
  2510. chsc_area_sei->request_block.command_code2=0x000E;
  2511. ccode = chsc(chsc_area_sei);
  2512. if (!ccode) {
  2513. /* for debug purposes, check for problems */
  2514. if (chsc_area_sei->response_block.response_code == 0x0003) {
  2515. #ifdef CONFIG_DEBUG_CHSC
  2516. printk( KERN_WARNING 
  2517. "s390_process_css: error in chsc request block!n");
  2518. #endif /* CONFIG_DEBUG_CHSC */
  2519. CIO_CRW_EVENT( 2, 
  2520.        "s390_process_css: "
  2521.        "error in chsc request block!n");
  2522. } else if (chsc_area_sei->response_block.response_code == 0x0005) {
  2523. #ifdef CONFIG_DEBUG_CHSC
  2524. printk( KERN_WARNING 
  2525. "s390_process_css: no event information storedn");
  2526. #endif /* CONFIG_DEBUG_CHSC */
  2527. CIO_CRW_EVENT( 2, 
  2528.        "s390_process_css: "
  2529.        "no event information storedn");
  2530. } else if (chsc_area_sei->response_block.response_code == 0x0002) {
  2531. #ifdef CONFIG_DEBUG_CHSC
  2532. printk( KERN_WARNING
  2533. "s390_process_css: invalid command!n");
  2534. #endif /* CONFIG_DEBUG_CHSC */
  2535. CIO_CRW_EVENT( 2,
  2536.        "s390_process_css: "
  2537.        "invalid command!n");
  2538. } else if (chsc_area_sei->response_block.response_code == 0x0001) {
  2539. /* everything ok */
  2540. #ifdef CONFIG_DEBUG_CHSC
  2541. printk( KERN_DEBUG 
  2542. "s390_process_css: "
  2543. "event information successfully storedn");
  2544. #endif /* CONFIG_DEBUG_CHSC */
  2545. CIO_CRW_EVENT( 4, 
  2546.        "s390_process_css: "
  2547.        "event information successfully storedn");
  2548. if (chsc_area_sei->response_block.
  2549.     response_block_data.sei_res.rs != 4) {
  2550. #ifdef CONFIG_DEBUG_CHSC
  2551. printk( KERN_ERR
  2552. "s390_process_css: "
  2553. "reporting source (%04X) isn't a chpid!"
  2554. "Aborting processing of machine check...n",
  2555. chsc_area_sei->response_block.
  2556. response_block_data.sei_res.rsid);
  2557. #endif /* CONFIG_DEBUG_CHSC */
  2558. CIO_CRW_EVENT( 2,
  2559.        "s390_process_css: "
  2560.        "reporting source (%04X) isn't a chpid!"
  2561.        "Aborting processing of machine check...n",
  2562.        chsc_area_sei->response_block.
  2563.        response_block_data.sei_res.rsid);
  2564. return;
  2565. }
  2566. /* which kind of information was stored? */
  2567. switch (chsc_area_sei->response_block.
  2568. response_block_data.sei_res.cc) {
  2569. case 1: /* link incident*/
  2570. #ifdef CONFIG_DEBUG_CHSC
  2571. printk( KERN_DEBUG 
  2572. "s390_process_css: "
  2573. "channel subsystem reports link incident,"
  2574. " source is chpid %xn", 
  2575. chsc_area_sei->response_block.
  2576. response_block_data.sei_res.rsid);
  2577. #endif /* CONFIG_DEBUG_CHSC */
  2578. CIO_CRW_EVENT( 4,
  2579.        "s390_process_css: "
  2580.        "channel subsystem reports "
  2581.        "link incident, "
  2582.        "source is chpid %xn", 
  2583.        chsc_area_sei->response_block.
  2584.        response_block_data.sei_res.rsid);
  2585. s390_do_chpid_processing(chsc_area_sei->response_block.
  2586.  response_block_data.sei_res.rsid);
  2587.     
  2588. break;
  2589. case 2: /* i/o resource accessibiliy */
  2590. #ifdef CONFIG_DEBUG_CHSC
  2591. printk( KERN_DEBUG 
  2592. "s390_process_css: channel subsystem "
  2593. "reports some I/O devices "
  2594. "may have become accessablen");
  2595. #endif /* CONFIG_DEBUG_CHSC */
  2596. CIO_CRW_EVENT( 4,
  2597.        "s390_process_css: "
  2598.        "channel subsystem reports "
  2599.        "some I/O devices "
  2600.        "may have become accessablen");
  2601. #ifdef CONFIG_DEBUG_CHSC
  2602. printk( KERN_DEBUG 
  2603. "Data received after sei: n");
  2604. printk( KERN_DEBUG 
  2605. "Validity flags: %xn", 
  2606.        chsc_area_sei->response_block.
  2607. response_block_data.sei_res.vf);
  2608. #endif /* CONFIG_DEBUG_CHSC */
  2609. if ((chsc_area_sei->response_block.
  2610.     response_block_data.sei_res.vf&0x80)
  2611.     == 0) {
  2612. #ifdef CONFIG_DEBUG_CHSC
  2613. printk( KERN_DEBUG "chpid: %xn",
  2614. chsc_area_sei->response_block.
  2615. response_block_data.sei_res.rsid);
  2616. #endif /* CONFIG_DEBUG_CHSC */
  2617. s390_do_res_acc_processing
  2618. (chsc_area_sei->response_block.
  2619.  response_block_data.sei_res.rsid,
  2620.  0,
  2621.  CHSC_SEI_ACC_CHPID);
  2622. } else if ((chsc_area_sei->response_block.
  2623.    response_block_data.sei_res.vf&0xc0)
  2624.    == 0x80) {
  2625. #ifdef CONFIG_DEBUG_CHSC
  2626. printk( KERN_DEBUG 
  2627. "chpid: %x  link addr: %xn",
  2628. chsc_area_sei->response_block.
  2629. response_block_data.sei_res.rsid,
  2630. chsc_area_sei->response_block.
  2631. response_block_data.sei_res.fla);
  2632. #endif /* CONFIG_DEBUG_CHSC */
  2633. s390_do_res_acc_processing
  2634. (chsc_area_sei->response_block.
  2635.  response_block_data.sei_res.rsid, 
  2636.  chsc_area_sei->response_block.
  2637.  response_block_data.sei_res.fla,
  2638.  CHSC_SEI_ACC_LINKADDR);
  2639. } else if ((chsc_area_sei->response_block.
  2640.     response_block_data.sei_res.vf & 0xc0)
  2641.    == 0xc0) {
  2642. #ifdef CONFIG_DEBUG_CHSC
  2643. printk( KERN_DEBUG 
  2644. "chpid: %x  "
  2645. "full link addr: %xn",
  2646. chsc_area_sei->response_block.
  2647. response_block_data.sei_res.rsid,
  2648. chsc_area_sei->response_block.
  2649. response_block_data.sei_res.fla);
  2650. #endif /* CONFIG_DEBUG_CHSC */
  2651. s390_do_res_acc_processing
  2652. (chsc_area_sei->response_block.
  2653.  response_block_data.sei_res.rsid, 
  2654.  chsc_area_sei->response_block.
  2655.  response_block_data.sei_res.fla,
  2656.  CHSC_SEI_ACC_FULLLINKADDR);
  2657. }
  2658. #ifdef CONFIG_DEBUG_CHSC
  2659. printk( KERN_DEBUG "n");
  2660. #endif /* CONFIG_DEBUG_CHSC */
  2661. break;
  2662. default: /* other stuff */
  2663. #ifdef CONFIG_DEBUG_CHSC
  2664. printk( KERN_DEBUG 
  2665. "s390_process_css: event %dn",
  2666. chsc_area_sei->response_block.
  2667. response_block_data.sei_res.cc);
  2668. #endif /* CONFIG_DEBUG_CHSC */
  2669. CIO_CRW_EVENT( 4, 
  2670.        "s390_process_css: event %dn",
  2671.        chsc_area_sei->response_block.
  2672.        response_block_data.sei_res.cc);
  2673. break;
  2674. }
  2675. }
  2676. }
  2677. spin_unlock(&chsc_lock_sei);
  2678. }
  2679. #endif
  2680. /*
  2681.  * s390_do_crw_pending
  2682.  *
  2683.  * Called by the machine check handler to process CRW pending
  2684.  *  conditions. It may be a single CRW, or CRWs may be chained.
  2685.  *
  2686.  * Note : we currently process CRWs for subchannel source only
  2687.  */
  2688. void
  2689. s390_do_crw_pending (crwe_t * pcrwe)
  2690. {
  2691. int irq;
  2692. int chpid;
  2693. #ifdef CONFIG_DEBUG_CRW
  2694. printk (KERN_DEBUG "do_crw_pending : starting ...n");
  2695. #endif
  2696. CIO_CRW_EVENT( 2, "do_crw_pending: startingn");
  2697. while (pcrwe != NULL) {
  2698. switch (pcrwe->crw.rsc) {
  2699. case CRW_RSC_SCH:
  2700. irq = pcrwe->crw.rsid;
  2701. #ifdef CONFIG_DEBUG_CRW
  2702. printk (KERN_NOTICE "do_crw_pending : source is "
  2703. "subchannel %04Xn", irq);
  2704. #endif
  2705. CIO_CRW_EVENT(2, "source is subchannel %04Xn",
  2706.       irq);
  2707. s390_process_subchannel_source (irq);
  2708. break;
  2709. case CRW_RSC_MONITOR:
  2710. #ifdef CONFIG_DEBUG_CRW
  2711. printk (KERN_NOTICE "do_crw_pending : source is "
  2712. "monitoring facilityn");
  2713. #endif
  2714. CIO_CRW_EVENT(2, "source is monitoring facilityn");
  2715. break;
  2716. case CRW_RSC_CPATH:
  2717. chpid = pcrwe->crw.rsid;
  2718. #ifdef CONFIG_DEBUG_CRW
  2719. printk (KERN_NOTICE "do_crw_pending : source is "
  2720. "channel path %02Xn", chpid);
  2721. #endif
  2722. CIO_CRW_EVENT(2, "source is channel path %02Xn");
  2723. break;
  2724. case CRW_RSC_CONFIG:
  2725. #ifdef CONFIG_DEBUG_CRW
  2726. printk (KERN_NOTICE "do_crw_pending : source is "
  2727. "configuration-alert facilityn");
  2728. #endif
  2729. CIO_CRW_EVENT(2, "source is configuration-alert facilityn");
  2730. break;
  2731. case CRW_RSC_CSS:
  2732. #ifdef CONFIG_DEBUG_CRW
  2733. printk (KERN_NOTICE "do_crw_pending : source is "
  2734. "channel subsystemn");
  2735. #endif
  2736. CIO_CRW_EVENT(2, "source is channel subsystemn");
  2737. #ifdef CONFIG_CHSC
  2738. s390_process_css();
  2739. #endif
  2740. break;
  2741. default:
  2742. #ifdef CONFIG_DEBUG_CRW
  2743. printk (KERN_NOTICE
  2744. "do_crw_pending : unknown sourcen");
  2745. #endif
  2746. CIO_CRW_EVENT( 2, "unknown sourcen");
  2747. break;
  2748. }
  2749. pcrwe = pcrwe->crwe_next;
  2750. }
  2751. #ifdef CONFIG_DEBUG_CRW
  2752. printk (KERN_DEBUG "do_crw_pending : donen");
  2753. #endif
  2754. CIO_CRW_EVENT(2, "do_crw_pending: donen");
  2755. return;
  2756. }
  2757. /* added by Holger Smolinski for reipl support in reipl.S */
  2758. extern void do_reipl (int);
  2759. void
  2760. reipl (int sch)
  2761. {
  2762. int i;
  2763. s390_dev_info_t dev_info;
  2764. for (i = 0; i <= highest_subchannel; i++) {
  2765. if (get_dev_info_by_irq (i, &dev_info) == 0
  2766.     && (dev_info.status & DEVSTAT_DEVICE_OWNED)) {
  2767. free_irq (i, ioinfo[i]->irq_desc.dev_id);
  2768. }
  2769. }
  2770. if (MACHINE_IS_VM)
  2771. cpcmd ("IPL", NULL, 0);
  2772. else
  2773. do_reipl (0x10000 | sch);
  2774. }
  2775. /*
  2776.  * Function: cio_debug_init
  2777.  * Initializes three debug logs (under /proc/s390dbf) for common I/O:
  2778.  * - cio_msg logs the messages which are printk'ed when CONFIG_DEBUG_IO is on
  2779.  * - cio_trace logs the calling of different functions
  2780.  * - cio_crw logs the messages which are printk'ed when CONFIG_DEBUG_CRW is on
  2781.  * debug levels depend on CONFIG_DEBUG_IO resp. CONFIG_DEBUG_CRW
  2782.  */
  2783. int
  2784. cio_debug_init (void)
  2785. {
  2786. int ret = 0;
  2787. cio_debug_msg_id = debug_register ("cio_msg", 4, 4, 16 * sizeof (long));
  2788. if (cio_debug_msg_id != NULL) {
  2789. debug_register_view (cio_debug_msg_id, &debug_sprintf_view);
  2790. debug_set_level (cio_debug_msg_id, 6);
  2791. } else {
  2792. ret = -1;
  2793. }
  2794. cio_debug_trace_id = debug_register ("cio_trace", 4, 4, 8);
  2795. if (cio_debug_trace_id != NULL) {
  2796. debug_register_view (cio_debug_trace_id, &debug_hex_ascii_view);
  2797. debug_set_level (cio_debug_trace_id, 6);
  2798. } else {
  2799. ret = -1;
  2800. }
  2801. cio_debug_crw_id = debug_register ("cio_crw", 2, 4, 16 * sizeof (long));
  2802. if (cio_debug_crw_id != NULL) {
  2803. debug_register_view (cio_debug_crw_id, &debug_sprintf_view);
  2804. debug_set_level (cio_debug_crw_id, 6);
  2805. } else {
  2806. ret = -1;
  2807. }
  2808. if (ret)
  2809. return ret;
  2810. cio_debug_initialized = 1;
  2811. return 0;
  2812. }
  2813. __initcall (cio_debug_init);
  2814. #ifdef CONFIG_PROC_FS
  2815. #ifdef CONFIG_CHSC
  2816. /*
  2817.  * Function: cio_parse_chpids_proc_parameters
  2818.  * parse the stuff piped to /proc/chpids
  2819.  */
  2820. void 
  2821. cio_parse_chpids_proc_parameters(char* buf)
  2822. {
  2823. int i;
  2824. int cp;
  2825. int ret;
  2826. if (strstr(buf, "on ")) {
  2827. for (i=0; i<3; i++) {
  2828. buf++;
  2829. }
  2830. cp = blacklist_strtoul(buf, &buf);
  2831. chsc_get_sch_descriptions();
  2832. if (!cio_chsc_desc_avail) {
  2833. printk(KERN_ERR "Could not get chpid status, "
  2834.        "vary on/off not availablen");
  2835. return;
  2836. }
  2837.  
  2838. if (!test_bit(cp, &chpids)) {
  2839. ret = s390_vary_chpid(cp, 1);
  2840. if (ret == -EINVAL) {
  2841. #ifdef CONFIG_DEBUG_CHSC
  2842. printk(KERN_ERR "/proc/chpids: "
  2843.        "Invalid chpid specifiedn");
  2844. #else /* CONFIG_DEBUG_CHSC */
  2845. printk(KERN_DEBUG "/proc/chpids: "
  2846.        "Invalid chpid specifiedn");
  2847. #endif /* CONFIG_DEBUG_CHSC */
  2848. } else if (ret == 0) {
  2849. printk(KERN_INFO "/proc/chpids: "
  2850.        "Varied chpid %x logically onlinen",
  2851.        cp);
  2852. }
  2853. } else {
  2854. printk(KERN_ERR "/proc/chpids: chpid %x is "
  2855.        "already onlinen",
  2856.        cp);
  2857. }
  2858. } else if (strstr(buf, "off ")) {
  2859. for (i=0; i<4; i++) {
  2860. buf++;
  2861. }
  2862. cp = blacklist_strtoul(buf, &buf);
  2863. chsc_get_sch_descriptions();
  2864. if (!cio_chsc_desc_avail) {
  2865. printk(KERN_ERR "Could not get chpid status, "
  2866.        "vary on/off not availablen");
  2867. return;
  2868. }
  2869. if (test_bit(cp, &chpids)) {
  2870. ret = s390_vary_chpid(cp, 0);
  2871. if (ret == -EINVAL) {
  2872. #ifdef CONFIG_DEBUG_CHSC
  2873. printk(KERN_ERR "/proc/chpids: "
  2874.        "Invalid chpid specifiedn");
  2875. #else /* CONFIG_DEBUG_CHSC */
  2876. printk(KERN_DEBUG "/proc/chpids: "
  2877.        "Invalid chpid specifiedn");
  2878. #endif /* CONFIG_DEBUG_CHSC */
  2879. } else if (ret == 0) {
  2880. printk(KERN_INFO "/proc/chpids: "
  2881.        "Varied chpid %x logically offlinen",
  2882.        cp);
  2883. }
  2884. } else { 
  2885. printk(KERN_ERR "/proc/chpids: "
  2886.        "chpid %x is already offlinen",
  2887.        cp);
  2888. }
  2889. } else {
  2890. printk(KERN_ERR "/proc/chpids: Parse error; "
  2891.        "try using '{on,off} <chpid>'n");
  2892. }
  2893. }
  2894. /*
  2895.  * Function: s390_vary_chpid
  2896.  * Varies the specified chpid online or offline
  2897.  */
  2898. int 
  2899. s390_vary_chpid( __u8 chpid, int on) 
  2900. {
  2901. char dbf_text[15];
  2902. int irq;
  2903. if ((chpid <=0) || (chpid >= NR_CHPIDS))
  2904. return -EINVAL;
  2905. sprintf(dbf_text, on?"varyon%x":"varyoff%x", chpid);
  2906. CIO_TRACE_EVENT( 2, dbf_text);
  2907. if (!test_bit(chpid, &chpids_known)) {
  2908. printk(KERN_ERR "Can't vary unknown chpid %02Xn", chpid);
  2909. return -EINVAL;
  2910. }
  2911. if (on && test_bit(chpid, &chpids_logical)) {
  2912. printk(KERN_ERR "chpid %02X already logically onlinen", 
  2913.        chpid);
  2914. return -EINVAL;
  2915. }
  2916. if (!on && !test_bit(chpid, &chpids_logical)) {
  2917. printk(KERN_ERR "chpid %02X already logically offlinen", 
  2918.        chpid);
  2919. return -EINVAL;
  2920. }
  2921. if (on) {
  2922. set_bit(chpid, &chpids_logical);
  2923. set_bit(chpid, &chpids);
  2924. } else {
  2925. clear_bit(chpid, &chpids_logical);
  2926. clear_bit(chpid, &chpids);
  2927. }
  2928. /*
  2929.  * Redo PathVerification on the devices the chpid connects to 
  2930.  */
  2931. for (irq=0;irq<=highest_subchannel;irq++) {
  2932. /* 
  2933.  * We don't need to adjust the opm, as this will be done in
  2934.  * DevicePathVerification...
  2935.  */
  2936. if (ioinfo[irq] == INVALID_STORAGE_AREA)
  2937. continue;
  2938. if (ioinfo[irq]->st)
  2939. continue;
  2940. if (ioinfo[irq]->ssd_info.valid) {
  2941. if ((ioinfo[irq]->ssd_info.chpid[0] == chpid) ||
  2942.     (ioinfo[irq]->ssd_info.chpid[1] == chpid) ||
  2943.     (ioinfo[irq]->ssd_info.chpid[2] == chpid) ||
  2944.     (ioinfo[irq]->ssd_info.chpid[3] == chpid) ||
  2945.     (ioinfo[irq]->ssd_info.chpid[4] == chpid) ||
  2946.     (ioinfo[irq]->ssd_info.chpid[5] == chpid) ||
  2947.     (ioinfo[irq]->ssd_info.chpid[6] == chpid) ||
  2948.     (ioinfo[irq]->ssd_info.chpid[7] == chpid)) {
  2949. #ifdef CONFIG_DEBUG_CHSC
  2950. printk(KERN_DEBUG "Calling "
  2951.        "DevicePathVerification for irq %dn", 
  2952.        irq);
  2953. #endif /* CONFIG_DEBUG_CHSC */
  2954. s390_DevicePathVerification(irq, 0);
  2955. }
  2956. }
  2957. }
  2958. return 0;
  2959. }
  2960. #endif /* CONFIG_CHSC */
  2961. /* 
  2962.  * Display info on subchannels in /proc/subchannels. 
  2963.  * Adapted from procfs stuff in dasd.c by Cornelia Huck, 02/28/01.      
  2964.  */
  2965. typedef struct {
  2966. char *data;
  2967. int len;
  2968. } tempinfo_t;
  2969. #define MIN(a,b) ((a)<(b)?(a):(b))
  2970. static struct proc_dir_entry *chan_subch_entry;
  2971. static int
  2972. chan_subch_open (struct inode *inode, struct file *file)
  2973. {
  2974. int rc = 0;
  2975. int size = 1;
  2976. int len = 0;
  2977. int i = 0;
  2978. int j = 0;
  2979. tempinfo_t *info;
  2980. info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
  2981. if (info == NULL) {
  2982. printk (KERN_WARNING "No memory available for datan");
  2983. return -ENOMEM;
  2984. } else {
  2985. file->private_data = (void *) info;
  2986. }
  2987. size += (highest_subchannel + 1) * 128;
  2988. info->data = (char *) vmalloc (size);
  2989. if (size && info->data == NULL) {
  2990. printk (KERN_WARNING "No memory available for datan");
  2991. vfree (info);
  2992. return -ENOMEM;
  2993. }
  2994. len += sprintf (info->data + len,
  2995. "Device sch.  Dev Type/Model CU  in use  PIM PAM POM CHPIDsn");
  2996. len += sprintf (info->data + len,
  2997. "---------------------------------------------------------------------n");
  2998. for (i = 0; i <= highest_subchannel; i++) {
  2999. if (!((ioinfo[i] == NULL) || (ioinfo[i] == INVALID_STORAGE_AREA)
  3000.       || (ioinfo[i]->st )|| !(ioinfo[i]->ui.flags.oper))) {
  3001. len +=
  3002.     sprintf (info->data + len, "%04X   %04X  ",
  3003.      ioinfo[i]->schib.pmcw.dev, i);
  3004. if (ioinfo[i]->senseid.dev_type != 0) {
  3005. len += sprintf (info->data + len,
  3006. "%04X/%02X   %04X/%02X",
  3007. ioinfo[i]->senseid.dev_type,
  3008. ioinfo[i]->senseid.dev_model,
  3009. ioinfo[i]->senseid.cu_type,
  3010. ioinfo[i]->senseid.cu_model);
  3011. } else {
  3012. len += sprintf (info->data + len,
  3013. "          %04X/%02X",
  3014. ioinfo[i]->senseid.cu_type,
  3015. ioinfo[i]->senseid.cu_model);
  3016. }
  3017. if (ioinfo[i]->ui.flags.ready) {
  3018. len += sprintf (info->data + len, "  yes ");
  3019. } else {
  3020. len += sprintf (info->data + len, "      ");
  3021. }
  3022. len += sprintf (info->data + len,
  3023. "    %02X  %02X  %02X  ",
  3024. ioinfo[i]->schib.pmcw.pim,
  3025. ioinfo[i]->schib.pmcw.pam,
  3026. ioinfo[i]->schib.pmcw.pom);
  3027. for (j = 0; j < 8; j++) {
  3028. len += sprintf (info->data + len,
  3029. "%02X",
  3030. ioinfo[i]->schib.pmcw.chpid[j]);
  3031. if (j == 3) {
  3032. len += sprintf (info->data + len, " ");
  3033. }
  3034. }
  3035. len += sprintf (info->data + len, "n");
  3036. }
  3037. }
  3038. info->len = len;
  3039. return rc;
  3040. }
  3041. static int
  3042. chan_subch_close (struct inode *inode, struct file *file)
  3043. {
  3044. int rc = 0;
  3045. tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  3046. if (p_info) {
  3047. if (p_info->data)
  3048. vfree (p_info->data);
  3049. vfree (p_info);
  3050. }
  3051. return rc;
  3052. }
  3053. static ssize_t
  3054. chan_subch_read (struct file *file, char *user_buf, size_t user_len,
  3055.  loff_t * offset)
  3056. {
  3057. loff_t len;
  3058. tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  3059. if (*offset >= p_info->len) {
  3060. return 0;
  3061. } else {
  3062. len = MIN (user_len, (p_info->len - *offset));
  3063. if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
  3064. return -EFAULT;
  3065. (*offset) += len;
  3066. return len;
  3067. }
  3068. }
  3069. static struct file_operations chan_subch_file_ops = {
  3070. read:chan_subch_read, open:chan_subch_open, release:chan_subch_close,
  3071. };
  3072. static int
  3073. chan_proc_init (void)
  3074. {
  3075. chan_subch_entry =
  3076.     create_proc_entry ("subchannels", S_IFREG | S_IRUGO, &proc_root);
  3077. chan_subch_entry->proc_fops = &chan_subch_file_ops;
  3078. return 1;
  3079. }
  3080. __initcall (chan_proc_init);
  3081. void
  3082. chan_proc_cleanup (void)
  3083. {
  3084. remove_proc_entry ("subchannels", &proc_root);
  3085. }
  3086. /* 
  3087.  * Display device specific information under /proc/deviceinfo/<devno>
  3088.  */ static struct proc_dir_entry *cio_procfs_deviceinfo_root = NULL;
  3089. /* 
  3090.  * cio_procfs_device_list holds all devno-specific procfs directories
  3091.  */
  3092. typedef struct {
  3093. int devno;
  3094. struct proc_dir_entry *cio_device_entry;
  3095. struct proc_dir_entry *cio_sensedata_entry;
  3096. struct proc_dir_entry *cio_in_use_entry;
  3097. struct proc_dir_entry *cio_chpid_entry;
  3098. } cio_procfs_entry_t;
  3099. typedef struct _cio_procfs_device {
  3100. struct _cio_procfs_device *next;
  3101. cio_procfs_entry_t *entry;
  3102. } cio_procfs_device_t;
  3103. cio_procfs_device_t *cio_procfs_device_list = NULL;
  3104. /*
  3105.  * File operations
  3106.  */
  3107. static int
  3108. cio_device_entry_close (struct inode *inode, struct file *file)
  3109. {
  3110. int rc = 0;
  3111. tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  3112. if (p_info) {
  3113. if (p_info->data)
  3114. vfree (p_info->data);
  3115. vfree (p_info);
  3116. }
  3117. return rc;
  3118. }
  3119. static ssize_t
  3120. cio_device_entry_read (struct file *file, char *user_buf, size_t user_len,
  3121.        loff_t * offset)
  3122. {
  3123. loff_t len;
  3124. tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  3125. if (*offset >= p_info->len) {
  3126. return 0;
  3127. } else {
  3128. len = MIN (user_len, (p_info->len - *offset));
  3129. if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
  3130. return -EFAULT;
  3131. (*offset) += len;
  3132. return len;
  3133. }
  3134. }
  3135. static int
  3136. cio_sensedata_entry_open (struct inode *inode, struct file *file)
  3137. {
  3138. int rc = 0;
  3139. int size = 1;
  3140. int len = 0;
  3141. tempinfo_t *info;
  3142. int irq;
  3143. int devno;
  3144. char *devno_str;
  3145. info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
  3146. if (info == NULL) {
  3147. printk (KERN_WARNING "No memory available for datan");
  3148. rc = -ENOMEM;
  3149. } else {
  3150. file->private_data = (void *) info;
  3151. size += 2 * 32;
  3152. info->data = (char *) vmalloc (size);
  3153. if (size && info->data == NULL) {
  3154. printk (KERN_WARNING "No memory available for datan");
  3155. vfree (info);
  3156. rc = -ENOMEM;
  3157. } else {
  3158. devno_str = kmalloc (6 * sizeof (char), GFP_KERNEL);
  3159. memset (devno_str, 0, 6 * sizeof (char));
  3160. memcpy (devno_str,
  3161. file->f_dentry->d_parent->d_name.name,
  3162. strlen (file->f_dentry->d_parent->d_name.name) +
  3163. 1);
  3164. devno = simple_strtoul (devno_str, &devno_str, 16);
  3165. irq = get_irq_by_devno (devno);
  3166. if (irq != -1) {
  3167. len +=
  3168.     sprintf (info->data + len,
  3169.      "Dev Type/Mod: ");
  3170. if (ioinfo[irq]->senseid.dev_type == 0) {
  3171. len +=
  3172.     sprintf (info->data + len,
  3173.      "%04X/%02Xn",
  3174.      ioinfo[irq]->senseid.
  3175.      cu_type,
  3176.      ioinfo[irq]->senseid.
  3177.      cu_model);
  3178. } else {
  3179. len +=
  3180.     sprintf (info->data + len,
  3181.      "%04X/%02Xn",
  3182.      ioinfo[irq]->senseid.
  3183.      dev_type,
  3184.      ioinfo[irq]->senseid.
  3185.      dev_model);
  3186. len +=
  3187.     sprintf (info->data + len,
  3188.      "CU Type/Mod:  %04X/%02Xn",
  3189.      ioinfo[irq]->senseid.
  3190.      cu_type,
  3191.      ioinfo[irq]->senseid.
  3192.      cu_model);
  3193. }
  3194. }
  3195. info->len = len;
  3196. }
  3197. }
  3198. return rc;
  3199. }
  3200. static int
  3201. cio_in_use_entry_open (struct inode *inode, struct file *file)
  3202. {
  3203. int rc = 0;
  3204. int size = 1;
  3205. int len = 0;
  3206. tempinfo_t *info;
  3207. int irq;
  3208. int devno;
  3209. char *devno_str;
  3210. info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
  3211. if (info == NULL) {
  3212. printk (KERN_WARNING "No memory available for datan");
  3213. rc = -ENOMEM;
  3214. } else {
  3215. file->private_data = (void *) info;
  3216. size += 8;
  3217. info->data = (char *) vmalloc (size);
  3218. if (size && info->data == NULL) {
  3219. printk (KERN_WARNING "No memory available for datan");
  3220. vfree (info);
  3221. rc = -ENOMEM;
  3222. } else {
  3223. devno_str = kmalloc (6 * sizeof (char), GFP_KERNEL);
  3224. memset (devno_str, 0, 6 * sizeof (char));
  3225. memcpy (devno_str,
  3226. file->f_dentry->d_parent->d_name.name,
  3227. strlen (file->f_dentry->d_parent->d_name.name) +
  3228. 1);
  3229. devno = simple_strtoul (devno_str, &devno_str, 16);
  3230. irq = get_irq_by_devno (devno);
  3231. if (irq != -1) {
  3232. len +=
  3233.     sprintf (info->data + len, "%sn",
  3234.      ioinfo[irq]->ui.flags.
  3235.      ready ? "yes" : "no");
  3236. }
  3237. info->len = len;
  3238. }
  3239. }
  3240. return rc;
  3241. }
  3242. static int
  3243. cio_chpid_entry_open (struct inode *inode, struct file *file)
  3244. {
  3245. int rc = 0;
  3246. int size = 1;
  3247. int len = 0;
  3248. tempinfo_t *info;
  3249. int irq;
  3250. int devno;
  3251. int i;
  3252. char *devno_str;
  3253. info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
  3254. if (info == NULL) {
  3255. printk (KERN_WARNING "No memory available for datan");
  3256. rc = -ENOMEM;
  3257. } else {
  3258. file->private_data = (void *) info;
  3259. size += 8 * 16;
  3260. info->data = (char *) vmalloc (size);
  3261. if (size && info->data == NULL) {
  3262. printk (KERN_WARNING "No memory available for datan");
  3263. vfree (info);
  3264. rc = -ENOMEM;
  3265. } else {
  3266. devno_str = kmalloc (6 * sizeof (char), GFP_KERNEL);
  3267. memset (devno_str, 0, 6 * sizeof (char));
  3268. memcpy (devno_str,
  3269. file->f_dentry->d_parent->d_name.name,
  3270. strlen (file->f_dentry->d_parent->d_name.name) +
  3271. 1);
  3272. devno = simple_strtoul (devno_str, &devno_str, 16);
  3273. irq = get_irq_by_devno (devno);
  3274. if (irq != -1) {
  3275. for (i = 0; i < 8; i++) {
  3276. len +=
  3277.     sprintf (info->data + len,
  3278.      "CHPID[%d]: ", i);
  3279. len +=
  3280.     sprintf (info->data + len, "%02Xn",
  3281.      ioinfo[irq]->schib.pmcw.
  3282.      chpid[i]);
  3283. }
  3284. }
  3285. info->len = len;
  3286. }
  3287. }
  3288. return rc;
  3289. }
  3290. static struct file_operations cio_sensedata_entry_file_ops = {
  3291. read:cio_device_entry_read, open:cio_sensedata_entry_open,
  3292. release:cio_device_entry_close,
  3293. };
  3294. static struct file_operations cio_in_use_entry_file_ops = {
  3295. read:cio_device_entry_read, open:cio_in_use_entry_open,
  3296. release:cio_device_entry_close,
  3297. };
  3298. static struct file_operations cio_chpid_entry_file_ops = {
  3299. read:cio_device_entry_read, open:cio_chpid_entry_open,
  3300. release:cio_device_entry_close,
  3301. };
  3302. /*
  3303.  * Function: cio_procfs_device_create
  3304.  * create procfs entry for given device number
  3305.  * and insert it into list
  3306.  */
  3307. int
  3308. cio_procfs_device_create (int devno)
  3309. {
  3310. cio_procfs_entry_t *entry;
  3311. cio_procfs_device_t *tmp;
  3312. cio_procfs_device_t *where;
  3313. char buf[8];
  3314. int i;
  3315. int rc = 0;
  3316. /* create the directory entry */
  3317. entry =
  3318.     (cio_procfs_entry_t *) kmalloc (sizeof (cio_procfs_entry_t),
  3319.     GFP_KERNEL);
  3320. if (entry) {
  3321. entry->devno = devno;
  3322. sprintf (buf, "%x", devno);
  3323. entry->cio_device_entry =
  3324.     proc_mkdir (buf, cio_procfs_deviceinfo_root);
  3325. if (entry->cio_device_entry) {
  3326. tmp = (cio_procfs_device_t *)
  3327.     kmalloc (sizeof (cio_procfs_device_t), GFP_KERNEL);
  3328. if (tmp) {
  3329. tmp->entry = entry;
  3330. if (cio_procfs_device_list == NULL) {
  3331. cio_procfs_device_list = tmp;
  3332. tmp->next = NULL;
  3333. } else {
  3334. where = cio_procfs_device_list;
  3335. i = where->entry->devno;
  3336. while ((devno > i)
  3337.        && (where->next != NULL)) {
  3338. where = where->next;
  3339. i = where->entry->devno;
  3340. }
  3341. if (where->next == NULL) {
  3342. where->next = tmp;
  3343. tmp->next = NULL;
  3344. } else {
  3345. tmp->next = where->next;
  3346. where->next = tmp;
  3347. }
  3348. }
  3349. /* create the different entries */
  3350. entry->cio_sensedata_entry =
  3351.     create_proc_entry ("sensedata",
  3352.        S_IFREG | S_IRUGO,
  3353.        entry->cio_device_entry);
  3354. entry->cio_sensedata_entry->proc_fops =
  3355.     &cio_sensedata_entry_file_ops;
  3356. entry->cio_in_use_entry =
  3357.     create_proc_entry ("in_use",
  3358.        S_IFREG | S_IRUGO,
  3359.        entry->cio_device_entry);
  3360. entry->cio_in_use_entry->proc_fops =
  3361.     &cio_in_use_entry_file_ops;
  3362. entry->cio_chpid_entry =
  3363.     create_proc_entry ("chpids",
  3364.        S_IFREG | S_IRUGO,
  3365.        entry->cio_device_entry);
  3366. entry->cio_chpid_entry->proc_fops =
  3367.     &cio_chpid_entry_file_ops;
  3368. } else {
  3369. printk (KERN_WARNING
  3370. "Error, could not allocate procfs structure!n");
  3371. remove_proc_entry (buf,
  3372.    cio_procfs_deviceinfo_root);
  3373. kfree (entry);
  3374. rc = -ENOMEM;
  3375. }
  3376. } else {
  3377. printk (KERN_WARNING
  3378. "Error, could not allocate procfs structure!n");
  3379. kfree (entry);
  3380. rc = -ENOMEM;
  3381. }
  3382. } else {
  3383. printk (KERN_WARNING
  3384. "Error, could not allocate procfs structure!n");
  3385. rc = -ENOMEM;
  3386. }
  3387. return rc;
  3388. }
  3389. /*
  3390.  * Function: cio_procfs_device_remove
  3391.  * remove procfs entry for given device number
  3392.  */
  3393. int
  3394. cio_procfs_device_remove (int devno)
  3395. {
  3396. int rc = 0;
  3397. cio_procfs_device_t *tmp;
  3398. cio_procfs_device_t *prev = NULL;
  3399. tmp = cio_procfs_device_list;
  3400. while (tmp) {
  3401. if (tmp->entry->devno == devno)
  3402. break;
  3403. prev = tmp;
  3404. tmp = tmp->next;
  3405. }
  3406. if (tmp) {
  3407. char buf[8];
  3408. remove_proc_entry ("sensedata", tmp->entry->cio_device_entry);
  3409. remove_proc_entry ("in_use", tmp->entry->cio_device_entry);
  3410. remove_proc_entry ("chpid", tmp->entry->cio_device_entry);
  3411. sprintf (buf, "%x", devno);
  3412. remove_proc_entry (buf, cio_procfs_deviceinfo_root);
  3413. if (tmp == cio_procfs_device_list) {
  3414. cio_procfs_device_list = tmp->next;
  3415. } else {
  3416. prev->next = tmp->next;
  3417. }
  3418. kfree (tmp->entry);
  3419. kfree (tmp);
  3420. } else {
  3421. rc = -ENODEV;
  3422. }
  3423. return rc;
  3424. }
  3425. /*
  3426.  * Function: cio_procfs_purge
  3427.  * purge /proc/deviceinfo of entries for gone devices
  3428.  */
  3429. int
  3430. cio_procfs_device_purge (void)
  3431. {
  3432. int i;
  3433. for (i = 0; i <= highest_subchannel; i++) {
  3434. if (ioinfo[i] != INVALID_STORAGE_AREA) {
  3435. if (!ioinfo[i]->ui.flags.oper)
  3436. cio_procfs_device_remove (ioinfo[i]->devno);
  3437. }
  3438. }
  3439. return 0;
  3440. }
  3441. /*
  3442.  * Function: cio_procfs_create
  3443.  * create /proc/deviceinfo/ and subdirs for the devices
  3444.  */
  3445. static int
  3446. cio_procfs_create (void)
  3447. {
  3448. int irq;
  3449. if (cio_proc_devinfo) {
  3450. cio_procfs_deviceinfo_root =
  3451.     proc_mkdir ("deviceinfo", &proc_root);
  3452. if (highest_subchannel >= MAX_CIO_PROCFS_ENTRIES) {
  3453. printk (KERN_ALERT
  3454. "Warning: Not enough inodes for creating all "
  3455. "entries under /proc/deviceinfo/. "
  3456. "Not every device will get an entry.n");
  3457. }
  3458. for (irq = 0; irq <= highest_subchannel; irq++) {
  3459. if (irq >= MAX_CIO_PROCFS_ENTRIES)
  3460. break;
  3461. if (ioinfo[irq] != INVALID_STORAGE_AREA) {
  3462. if (ioinfo[irq]->ui.flags.oper)
  3463. if (cio_procfs_device_create
  3464.     (ioinfo[irq]->devno) == -ENOMEM) {
  3465. printk (KERN_CRIT
  3466. "Out of memory while creating "
  3467. "entries in /proc/deviceinfo/, "
  3468. "not all devices might show upn");
  3469. break;
  3470. }
  3471. }
  3472. }
  3473. }
  3474. return 1;
  3475. }
  3476. __initcall (cio_procfs_create);
  3477. /*
  3478.  * Entry /proc/cio_ignore to display blacklisted ranges of devices.
  3479.  * un-ignore devices by piping to /proc/cio_ignore:
  3480.  * free all frees all blacklisted devices, free <range>,<range>,...
  3481.  * frees specified ranges of devnos
  3482.  * add <range>,<range>,... will add a range of devices to blacklist -
  3483.  * but only for devices not already known
  3484.  */
  3485. static struct proc_dir_entry *cio_ignore_proc_entry;
  3486. static int
  3487. cio_ignore_proc_open (struct inode *inode, struct file *file)
  3488. {
  3489. int rc = 0;
  3490. int size = 1;
  3491. int len = 0;
  3492. tempinfo_t *info;
  3493. long flags;
  3494. int i, j;
  3495. info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
  3496. if (info == NULL) {
  3497. printk (KERN_WARNING "No memory available for datan");
  3498. rc = -ENOMEM;
  3499. } else {
  3500. file->private_data = (void *) info;
  3501. size += nr_ignored * 6;
  3502. info->data = (char *) vmalloc (size);
  3503. if (size && info->data == NULL) {
  3504. printk (KERN_WARNING "No memory available for datan");
  3505. vfree (info);
  3506. rc = -ENOMEM;
  3507. } else {
  3508. spin_lock_irqsave (&blacklist_lock, flags);
  3509. for (i = 0; i <= highest_ignored; i++)
  3510. if (test_bit (i, &bl_dev)) {
  3511. len +=
  3512.     sprintf (info->data + len, "%04x ",
  3513.      i);
  3514. for (j = i; (j <= highest_ignored)
  3515.      && (test_bit (j, &bl_dev)); j++) ;
  3516. j--;
  3517. if (i != j)
  3518. len +=
  3519.     sprintf (info->data + len,
  3520.      "- %04x", j);
  3521. len += sprintf (info->data + len, "n");
  3522. i = j;
  3523. }
  3524. spin_unlock_irqrestore (&blacklist_lock, flags);
  3525. info->len = len;
  3526. }
  3527. }
  3528. return rc;
  3529. }
  3530. static int
  3531. cio_ignore_proc_close (struct inode *inode, struct file *file)
  3532. {
  3533. int rc = 0;
  3534. tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  3535. if (p_info) {
  3536. if (p_info->data)
  3537. vfree (p_info->data);
  3538. vfree (p_info);
  3539. }
  3540. return rc;
  3541. }
  3542. static ssize_t
  3543. cio_ignore_proc_read (struct file *file, char *user_buf, size_t user_len,
  3544.       loff_t * offset)
  3545. {
  3546. loff_t len;
  3547. tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  3548. if (*offset >= p_info->len) {
  3549. return 0;
  3550. } else {
  3551. len = MIN (user_len, (p_info->len - *offset));
  3552. if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
  3553. return -EFAULT;
  3554. (*offset) += len;
  3555. return len;
  3556. }
  3557. }
  3558. static ssize_t
  3559. cio_ignore_proc_write (struct file *file, const char *user_buf,
  3560.        size_t user_len, loff_t * offset)
  3561. {
  3562. char *buffer
  3563. if(user_len > 65536)
  3564. user_len = 65536;
  3565. buffer = vmalloc (user_len + 1);
  3566. if (buffer == NULL)
  3567. return -ENOMEM;
  3568. if (copy_from_user (buffer, user_buf, user_len)) {
  3569. vfree (buffer);
  3570. return -EFAULT;
  3571. }
  3572. buffer[user_len] = '';
  3573. #ifdef CONFIG_DEBUG_IO
  3574. printk (KERN_DEBUG "/proc/cio_ignore: '%s'n", buffer);
  3575. #endif /* CONFIG_DEBUG_IO */
  3576. if (cio_debug_initialized)
  3577. debug_sprintf_event (cio_debug_msg_id, 2,
  3578.      "/proc/cio_ignore: '%s'n", buffer);
  3579. blacklist_parse_proc_parameters (buffer);
  3580. vfree (buffer);
  3581. return user_len;
  3582. }
  3583. static struct file_operations cio_ignore_proc_file_ops = {
  3584. read:cio_ignore_proc_read, open:cio_ignore_proc_open,
  3585. write:cio_ignore_proc_write, release:cio_ignore_proc_close,
  3586. };
  3587. static int
  3588. cio_ignore_proc_init (void)
  3589. {
  3590. cio_ignore_proc_entry =
  3591.     create_proc_entry ("cio_ignore", S_IFREG | S_IRUGO | S_IWUSR,
  3592.        &proc_root);
  3593. cio_ignore_proc_entry->proc_fops = &cio_ignore_proc_file_ops;
  3594. return 1;
  3595. }
  3596. __initcall (cio_ignore_proc_init);
  3597. /*
  3598.  * Entry /proc/irq_count
  3599.  * display how many irqs have occured per cpu...
  3600.  */
  3601. static struct proc_dir_entry *cio_irq_proc_entry;
  3602. static int
  3603. cio_irq_proc_open (struct inode *inode, struct file *file)
  3604. {
  3605. int rc = 0;
  3606. int size = 1;
  3607. int len = 0;
  3608. tempinfo_t *info;
  3609. int i;
  3610. info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
  3611. if (info == NULL) {
  3612. printk (KERN_WARNING "No memory available for datan");
  3613. rc = -ENOMEM;
  3614. } else {
  3615. file->private_data = (void *) info;
  3616. size += NR_CPUS * 16;
  3617. info->data = (char *) vmalloc (size);
  3618. if (size && info->data == NULL) {
  3619. printk (KERN_WARNING "No memory available for datan");
  3620. vfree (info);
  3621. rc = -ENOMEM;
  3622. } else {
  3623. for (i = 0; i < NR_CPUS; i++) {
  3624. if (s390_irq_count[i] != 0)
  3625. len +=
  3626.     sprintf (info->data + len, "%lxn",
  3627.      s390_irq_count[i]);
  3628. }
  3629. info->len = len;
  3630. }
  3631. }
  3632. return rc;
  3633. }
  3634. static int
  3635. cio_irq_proc_close (struct inode *inode, struct file *file)
  3636. {
  3637. int rc = 0;
  3638. tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  3639. if (p_info) {
  3640. if (p_info->data)
  3641. vfree (p_info->data);
  3642. vfree (p_info);
  3643. }
  3644. return rc;
  3645. }
  3646. static ssize_t
  3647. cio_irq_proc_read (struct file *file, char *user_buf, size_t user_len,
  3648.    loff_t * offset)
  3649. {
  3650. loff_t len;
  3651. tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  3652. if (*offset >= p_info->len) {
  3653. return 0;
  3654. } else {
  3655. len = MIN (user_len, (p_info->len - *offset));
  3656. if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
  3657. return -EFAULT;
  3658. (*offset) += len;
  3659. return len;
  3660. }
  3661. }
  3662. static struct file_operations cio_irq_proc_file_ops = {
  3663. read:cio_irq_proc_read, open:cio_irq_proc_open,
  3664. release:cio_irq_proc_close,
  3665. };
  3666. static int
  3667. cio_irq_proc_init (void)
  3668. {
  3669. int i;
  3670. if (cio_count_irqs) {
  3671. for (i = 0; i < NR_CPUS; i++)
  3672. s390_irq_count[i] = 0;
  3673. cio_irq_proc_entry =
  3674.     create_proc_entry ("irq_count", S_IFREG | S_IRUGO,
  3675.        &proc_root);
  3676. cio_irq_proc_entry->proc_fops = &cio_irq_proc_file_ops;
  3677. }
  3678. return 1;
  3679. }
  3680. __initcall (cio_irq_proc_init);
  3681. #ifdef CONFIG_CHSC
  3682. /*
  3683.  * /proc/chpids to display available chpids
  3684.  * vary chpids on/off by piping to it
  3685.  */
  3686. static struct proc_dir_entry *cio_chpids_proc_entry;
  3687. static int 
  3688. cio_chpids_proc_open(struct inode *inode, struct file *file)
  3689. {
  3690. int rc = 0;
  3691. int size = 1;
  3692. int len = 0;
  3693. tempinfo_t *info;
  3694. int i;
  3695. if (!cio_chsc_desc_avail) {
  3696. /* 
  3697.  * We have not yet retrieved the link addresses,
  3698.  * so we do it now.
  3699.  */
  3700. chsc_get_sch_descriptions();
  3701. }
  3702. info = (tempinfo_t *) vmalloc(sizeof(tempinfo_t));
  3703. if (info == NULL) {
  3704. printk( KERN_WARNING "No memory available for datan");
  3705. rc = -ENOMEM;
  3706. } else {
  3707. file->private_data = (void *) info;
  3708. size += NR_CHPIDS * 16;
  3709. info->data = (char *) vmalloc(size);
  3710. if ( size && info->data == NULL) {
  3711. printk( KERN_WARNING "No memory available for datan");
  3712. vfree (info);
  3713. rc = -ENOMEM;
  3714. } else {
  3715. /* update our stuff */
  3716. chsc_get_sch_descriptions();
  3717. if (!cio_chsc_desc_avail) {
  3718. len += sprintf(info->data+len, "no info availablen");
  3719. } else {
  3720. for (i=0;i<NR_CHPIDS;i++) {
  3721. if ((test_bit(i, &chpids)) && 
  3722.     test_bit(i, &chpids_logical))
  3723. len += sprintf(info->data+len, 
  3724.        "%02X onlinen", 
  3725.        i);
  3726. else if (test_bit(i, &chpids_known))
  3727. len += sprintf(info->data+len, 
  3728.        "%02X logically offlinen", 
  3729.        i);
  3730. }
  3731. }
  3732. info->len = len;
  3733. }
  3734. }
  3735. return rc;
  3736. }
  3737. static int 
  3738. cio_chpids_proc_close(struct inode *inode, struct file *file)
  3739. {
  3740. int rc = 0;
  3741. tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  3742.      if (p_info) {
  3743.   if (p_info->data)
  3744.        vfree( p_info->data );
  3745.   vfree( p_info );
  3746.      }
  3747.      
  3748.      return rc;
  3749. }
  3750. static ssize_t 
  3751. cio_chpids_proc_read( struct file *file, char *user_buf, size_t user_len, loff_t * offset)
  3752. {
  3753.      loff_t len;
  3754.      tempinfo_t *p_info = (tempinfo_t *) file->private_data;
  3755.      
  3756.      if ( *offset>=p_info->len) {
  3757.   return 0;
  3758.      } else {
  3759.   len = MIN(user_len, (p_info->len - *offset));
  3760.   if (copy_to_user( user_buf, &(p_info->data[*offset]), len))
  3761.        return -EFAULT; 
  3762.   (* offset) += len;
  3763.   return len;
  3764.      }
  3765. }
  3766. static ssize_t 
  3767. cio_chpids_proc_write (struct file *file, const char *user_buf,
  3768.        size_t user_len, loff_t * offset)
  3769. {
  3770. char *buffer;
  3771. if(user_len > 65536)
  3772. user_len = 65536;
  3773. buffer = vmalloc (user_len + 1);
  3774. if (buffer == NULL)
  3775. return -ENOMEM;
  3776. if (copy_from_user (buffer, user_buf, user_len)) {
  3777. vfree (buffer);
  3778. return -EFAULT;
  3779. }
  3780. buffer[user_len]='';
  3781. #ifdef CIO_DEBUG_IO
  3782. printk("/proc/chpids: '%s'n", buffer);
  3783. #endif /* CIO_DEBUG_IO */
  3784. CIO_MSG_EVENT( 2, "/proc/chpids: '%s'n", buffer);
  3785. cio_parse_chpids_proc_parameters(buffer);
  3786. vfree (buffer);
  3787. return user_len;
  3788. }
  3789. static struct file_operations cio_chpids_proc_file_ops =
  3790. {
  3791. read:cio_chpids_proc_read,
  3792. open:cio_chpids_proc_open,
  3793. write:cio_chpids_proc_write,
  3794. release:cio_chpids_proc_close,
  3795. };
  3796. static int 
  3797. cio_chpids_proc_init(void)
  3798. {
  3799. cio_chpids_proc_entry = create_proc_entry("chpids", S_IFREG|S_IRUGO|S_IWUSR, &proc_root);
  3800. cio_chpids_proc_entry->proc_fops = &cio_chpids_proc_file_ops;
  3801. return 1;
  3802. }
  3803. __initcall(cio_chpids_proc_init);
  3804. #endif
  3805. /* end of procfs stuff */
  3806. #endif
  3807. schib_t *
  3808. s390_get_schib (int irq)
  3809. {
  3810. if ((irq > highest_subchannel) || (irq < 0))
  3811. return NULL;
  3812. if (ioinfo[irq] == INVALID_STORAGE_AREA)
  3813. return NULL;
  3814. if (ioinfo[irq]->st)
  3815. return NULL;
  3816. return &ioinfo[irq]->schib;
  3817. }
  3818. int
  3819. s390_set_private_data(int irq, void *data)
  3820. {
  3821. SANITY_CHECK(irq);
  3822. ioinfo[irq]->private_data = data;
  3823. return 0;
  3824. }
  3825. void *
  3826. s390_get_private_data(int irq)
  3827. {
  3828. if ((irq > highest_subchannel) || (irq < 0))
  3829. return NULL;
  3830. if (ioinfo[irq] == INVALID_STORAGE_AREA)
  3831. return NULL;
  3832. if (ioinfo[irq]->st)
  3833. return NULL;
  3834. return ioinfo[irq]->private_data;
  3835. }
  3836. EXPORT_SYMBOL (halt_IO);
  3837. EXPORT_SYMBOL (clear_IO);
  3838. EXPORT_SYMBOL (do_IO);
  3839. EXPORT_SYMBOL (resume_IO);
  3840. EXPORT_SYMBOL (ioinfo);
  3841. EXPORT_SYMBOL (get_dev_info_by_irq);
  3842. EXPORT_SYMBOL (get_dev_info_by_devno);
  3843. EXPORT_SYMBOL (get_irq_by_devno);
  3844. EXPORT_SYMBOL (get_devno_by_irq);
  3845. EXPORT_SYMBOL (get_irq_first);
  3846. EXPORT_SYMBOL (get_irq_next);
  3847. EXPORT_SYMBOL (read_conf_data);
  3848. EXPORT_SYMBOL (read_dev_chars);
  3849. EXPORT_SYMBOL (s390_request_irq_special);
  3850. EXPORT_SYMBOL (s390_get_schib);
  3851. EXPORT_SYMBOL (s390_register_adapter_interrupt);
  3852. EXPORT_SYMBOL (s390_unregister_adapter_interrupt);
  3853. EXPORT_SYMBOL (s390_set_private_data);
  3854. EXPORT_SYMBOL (s390_get_private_data);
  3855. EXPORT_SYMBOL (s390_trigger_resense);