device_ops.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742
  1. /*
  2. * Copyright IBM Corp. 2002, 2009
  3. *
  4. * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
  5. * Cornelia Huck (cornelia.huck@de.ibm.com)
  6. */
  7. #include <linux/module.h>
  8. #include <linux/init.h>
  9. #include <linux/errno.h>
  10. #include <linux/slab.h>
  11. #include <linux/list.h>
  12. #include <linux/device.h>
  13. #include <linux/delay.h>
  14. #include <asm/ccwdev.h>
  15. #include <asm/idals.h>
  16. #include <asm/chpid.h>
  17. #include <asm/fcx.h>
  18. #include "cio.h"
  19. #include "cio_debug.h"
  20. #include "css.h"
  21. #include "chsc.h"
  22. #include "device.h"
  23. #include "chp.h"
  24. /**
  25. * ccw_device_set_options_mask() - set some options and unset the rest
  26. * @cdev: device for which the options are to be set
  27. * @flags: options to be set
  28. *
  29. * All flags specified in @flags are set, all flags not specified in @flags
  30. * are cleared.
  31. * Returns:
  32. * %0 on success, -%EINVAL on an invalid flag combination.
  33. */
  34. int ccw_device_set_options_mask(struct ccw_device *cdev, unsigned long flags)
  35. {
  36. /*
  37. * The flag usage is mutal exclusive ...
  38. */
  39. if ((flags & CCWDEV_EARLY_NOTIFICATION) &&
  40. (flags & CCWDEV_REPORT_ALL))
  41. return -EINVAL;
  42. cdev->private->options.fast = (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
  43. cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0;
  44. cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0;
  45. cdev->private->options.force = (flags & CCWDEV_ALLOW_FORCE) != 0;
  46. cdev->private->options.mpath = (flags & CCWDEV_DO_MULTIPATH) != 0;
  47. return 0;
  48. }
  49. /**
  50. * ccw_device_set_options() - set some options
  51. * @cdev: device for which the options are to be set
  52. * @flags: options to be set
  53. *
  54. * All flags specified in @flags are set, the remainder is left untouched.
  55. * Returns:
  56. * %0 on success, -%EINVAL if an invalid flag combination would ensue.
  57. */
  58. int ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)
  59. {
  60. /*
  61. * The flag usage is mutal exclusive ...
  62. */
  63. if (((flags & CCWDEV_EARLY_NOTIFICATION) &&
  64. (flags & CCWDEV_REPORT_ALL)) ||
  65. ((flags & CCWDEV_EARLY_NOTIFICATION) &&
  66. cdev->private->options.repall) ||
  67. ((flags & CCWDEV_REPORT_ALL) &&
  68. cdev->private->options.fast))
  69. return -EINVAL;
  70. cdev->private->options.fast |= (flags & CCWDEV_EARLY_NOTIFICATION) != 0;
  71. cdev->private->options.repall |= (flags & CCWDEV_REPORT_ALL) != 0;
  72. cdev->private->options.pgroup |= (flags & CCWDEV_DO_PATHGROUP) != 0;
  73. cdev->private->options.force |= (flags & CCWDEV_ALLOW_FORCE) != 0;
  74. cdev->private->options.mpath |= (flags & CCWDEV_DO_MULTIPATH) != 0;
  75. return 0;
  76. }
  77. /**
  78. * ccw_device_clear_options() - clear some options
  79. * @cdev: device for which the options are to be cleared
  80. * @flags: options to be cleared
  81. *
  82. * All flags specified in @flags are cleared, the remainder is left untouched.
  83. */
  84. void ccw_device_clear_options(struct ccw_device *cdev, unsigned long flags)
  85. {
  86. cdev->private->options.fast &= (flags & CCWDEV_EARLY_NOTIFICATION) == 0;
  87. cdev->private->options.repall &= (flags & CCWDEV_REPORT_ALL) == 0;
  88. cdev->private->options.pgroup &= (flags & CCWDEV_DO_PATHGROUP) == 0;
  89. cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0;
  90. cdev->private->options.mpath &= (flags & CCWDEV_DO_MULTIPATH) == 0;
  91. }
  92. /**
  93. * ccw_device_is_pathgroup - determine if paths to this device are grouped
  94. * @cdev: ccw device
  95. *
  96. * Return non-zero if there is a path group, zero otherwise.
  97. */
  98. int ccw_device_is_pathgroup(struct ccw_device *cdev)
  99. {
  100. return cdev->private->flags.pgroup;
  101. }
  102. EXPORT_SYMBOL(ccw_device_is_pathgroup);
  103. /**
  104. * ccw_device_is_multipath - determine if device is operating in multipath mode
  105. * @cdev: ccw device
  106. *
  107. * Return non-zero if device is operating in multipath mode, zero otherwise.
  108. */
  109. int ccw_device_is_multipath(struct ccw_device *cdev)
  110. {
  111. return cdev->private->flags.mpath;
  112. }
  113. EXPORT_SYMBOL(ccw_device_is_multipath);
  114. /**
  115. * ccw_device_clear() - terminate I/O request processing
  116. * @cdev: target ccw device
  117. * @intparm: interruption parameter; value is only used if no I/O is
  118. * outstanding, otherwise the intparm associated with the I/O request
  119. * is returned
  120. *
  121. * ccw_device_clear() calls csch on @cdev's subchannel.
  122. * Returns:
  123. * %0 on success,
  124. * -%ENODEV on device not operational,
  125. * -%EINVAL on invalid device state.
  126. * Context:
  127. * Interrupts disabled, ccw device lock held
  128. */
  129. int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
  130. {
  131. struct subchannel *sch;
  132. int ret;
  133. if (!cdev || !cdev->dev.parent)
  134. return -ENODEV;
  135. sch = to_subchannel(cdev->dev.parent);
  136. if (!sch->schib.pmcw.ena)
  137. return -EINVAL;
  138. if (cdev->private->state == DEV_STATE_NOT_OPER)
  139. return -ENODEV;
  140. if (cdev->private->state != DEV_STATE_ONLINE &&
  141. cdev->private->state != DEV_STATE_W4SENSE)
  142. return -EINVAL;
  143. ret = cio_clear(sch);
  144. if (ret == 0)
  145. cdev->private->intparm = intparm;
  146. return ret;
  147. }
  148. /**
  149. * ccw_device_start_key() - start a s390 channel program with key
  150. * @cdev: target ccw device
  151. * @cpa: logical start address of channel program
  152. * @intparm: user specific interruption parameter; will be presented back to
  153. * @cdev's interrupt handler. Allows a device driver to associate
  154. * the interrupt with a particular I/O request.
  155. * @lpm: defines the channel path to be used for a specific I/O request. A
  156. * value of 0 will make cio use the opm.
  157. * @key: storage key to be used for the I/O
  158. * @flags: additional flags; defines the action to be performed for I/O
  159. * processing.
  160. *
  161. * Start a S/390 channel program. When the interrupt arrives, the
  162. * IRQ handler is called, either immediately, delayed (dev-end missing,
  163. * or sense required) or never (no IRQ handler registered).
  164. * Returns:
  165. * %0, if the operation was successful;
  166. * -%EBUSY, if the device is busy, or status pending;
  167. * -%EACCES, if no path specified in @lpm is operational;
  168. * -%ENODEV, if the device is not operational.
  169. * Context:
  170. * Interrupts disabled, ccw device lock held
  171. */
  172. int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
  173. unsigned long intparm, __u8 lpm, __u8 key,
  174. unsigned long flags)
  175. {
  176. struct subchannel *sch;
  177. int ret;
  178. if (!cdev || !cdev->dev.parent)
  179. return -ENODEV;
  180. sch = to_subchannel(cdev->dev.parent);
  181. if (!sch->schib.pmcw.ena)
  182. return -EINVAL;
  183. if (cdev->private->state == DEV_STATE_NOT_OPER)
  184. return -ENODEV;
  185. if (cdev->private->state == DEV_STATE_VERIFY) {
  186. /* Remember to fake irb when finished. */
  187. if (!cdev->private->flags.fake_irb) {
  188. cdev->private->flags.fake_irb = 1;
  189. cdev->private->intparm = intparm;
  190. return 0;
  191. } else
  192. /* There's already a fake I/O around. */
  193. return -EBUSY;
  194. }
  195. if (cdev->private->state != DEV_STATE_ONLINE ||
  196. ((sch->schib.scsw.cmd.stctl & SCSW_STCTL_PRIM_STATUS) &&
  197. !(sch->schib.scsw.cmd.stctl & SCSW_STCTL_SEC_STATUS)) ||
  198. cdev->private->flags.doverify)
  199. return -EBUSY;
  200. ret = cio_set_options (sch, flags);
  201. if (ret)
  202. return ret;
  203. /* Adjust requested path mask to excluded varied off paths. */
  204. if (lpm) {
  205. lpm &= sch->opm;
  206. if (lpm == 0)
  207. return -EACCES;
  208. }
  209. ret = cio_start_key (sch, cpa, lpm, key);
  210. switch (ret) {
  211. case 0:
  212. cdev->private->intparm = intparm;
  213. break;
  214. case -EACCES:
  215. case -ENODEV:
  216. dev_fsm_event(cdev, DEV_EVENT_VERIFY);
  217. break;
  218. }
  219. return ret;
  220. }
  221. /**
  222. * ccw_device_start_timeout_key() - start a s390 channel program with timeout and key
  223. * @cdev: target ccw device
  224. * @cpa: logical start address of channel program
  225. * @intparm: user specific interruption parameter; will be presented back to
  226. * @cdev's interrupt handler. Allows a device driver to associate
  227. * the interrupt with a particular I/O request.
  228. * @lpm: defines the channel path to be used for a specific I/O request. A
  229. * value of 0 will make cio use the opm.
  230. * @key: storage key to be used for the I/O
  231. * @flags: additional flags; defines the action to be performed for I/O
  232. * processing.
  233. * @expires: timeout value in jiffies
  234. *
  235. * Start a S/390 channel program. When the interrupt arrives, the
  236. * IRQ handler is called, either immediately, delayed (dev-end missing,
  237. * or sense required) or never (no IRQ handler registered).
  238. * This function notifies the device driver if the channel program has not
  239. * completed during the time specified by @expires. If a timeout occurs, the
  240. * channel program is terminated via xsch, hsch or csch, and the device's
  241. * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT).
  242. * Returns:
  243. * %0, if the operation was successful;
  244. * -%EBUSY, if the device is busy, or status pending;
  245. * -%EACCES, if no path specified in @lpm is operational;
  246. * -%ENODEV, if the device is not operational.
  247. * Context:
  248. * Interrupts disabled, ccw device lock held
  249. */
  250. int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa,
  251. unsigned long intparm, __u8 lpm, __u8 key,
  252. unsigned long flags, int expires)
  253. {
  254. int ret;
  255. if (!cdev)
  256. return -ENODEV;
  257. ccw_device_set_timeout(cdev, expires);
  258. ret = ccw_device_start_key(cdev, cpa, intparm, lpm, key, flags);
  259. if (ret != 0)
  260. ccw_device_set_timeout(cdev, 0);
  261. return ret;
  262. }
  263. /**
  264. * ccw_device_start() - start a s390 channel program
  265. * @cdev: target ccw device
  266. * @cpa: logical start address of channel program
  267. * @intparm: user specific interruption parameter; will be presented back to
  268. * @cdev's interrupt handler. Allows a device driver to associate
  269. * the interrupt with a particular I/O request.
  270. * @lpm: defines the channel path to be used for a specific I/O request. A
  271. * value of 0 will make cio use the opm.
  272. * @flags: additional flags; defines the action to be performed for I/O
  273. * processing.
  274. *
  275. * Start a S/390 channel program. When the interrupt arrives, the
  276. * IRQ handler is called, either immediately, delayed (dev-end missing,
  277. * or sense required) or never (no IRQ handler registered).
  278. * Returns:
  279. * %0, if the operation was successful;
  280. * -%EBUSY, if the device is busy, or status pending;
  281. * -%EACCES, if no path specified in @lpm is operational;
  282. * -%ENODEV, if the device is not operational.
  283. * Context:
  284. * Interrupts disabled, ccw device lock held
  285. */
  286. int ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa,
  287. unsigned long intparm, __u8 lpm, unsigned long flags)
  288. {
  289. return ccw_device_start_key(cdev, cpa, intparm, lpm,
  290. PAGE_DEFAULT_KEY, flags);
  291. }
  292. /**
  293. * ccw_device_start_timeout() - start a s390 channel program with timeout
  294. * @cdev: target ccw device
  295. * @cpa: logical start address of channel program
  296. * @intparm: user specific interruption parameter; will be presented back to
  297. * @cdev's interrupt handler. Allows a device driver to associate
  298. * the interrupt with a particular I/O request.
  299. * @lpm: defines the channel path to be used for a specific I/O request. A
  300. * value of 0 will make cio use the opm.
  301. * @flags: additional flags; defines the action to be performed for I/O
  302. * processing.
  303. * @expires: timeout value in jiffies
  304. *
  305. * Start a S/390 channel program. When the interrupt arrives, the
  306. * IRQ handler is called, either immediately, delayed (dev-end missing,
  307. * or sense required) or never (no IRQ handler registered).
  308. * This function notifies the device driver if the channel program has not
  309. * completed during the time specified by @expires. If a timeout occurs, the
  310. * channel program is terminated via xsch, hsch or csch, and the device's
  311. * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT).
  312. * Returns:
  313. * %0, if the operation was successful;
  314. * -%EBUSY, if the device is busy, or status pending;
  315. * -%EACCES, if no path specified in @lpm is operational;
  316. * -%ENODEV, if the device is not operational.
  317. * Context:
  318. * Interrupts disabled, ccw device lock held
  319. */
  320. int ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa,
  321. unsigned long intparm, __u8 lpm,
  322. unsigned long flags, int expires)
  323. {
  324. return ccw_device_start_timeout_key(cdev, cpa, intparm, lpm,
  325. PAGE_DEFAULT_KEY, flags,
  326. expires);
  327. }
  328. /**
  329. * ccw_device_halt() - halt I/O request processing
  330. * @cdev: target ccw device
  331. * @intparm: interruption parameter; value is only used if no I/O is
  332. * outstanding, otherwise the intparm associated with the I/O request
  333. * is returned
  334. *
  335. * ccw_device_halt() calls hsch on @cdev's subchannel.
  336. * Returns:
  337. * %0 on success,
  338. * -%ENODEV on device not operational,
  339. * -%EINVAL on invalid device state,
  340. * -%EBUSY on device busy or interrupt pending.
  341. * Context:
  342. * Interrupts disabled, ccw device lock held
  343. */
  344. int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
  345. {
  346. struct subchannel *sch;
  347. int ret;
  348. if (!cdev || !cdev->dev.parent)
  349. return -ENODEV;
  350. sch = to_subchannel(cdev->dev.parent);
  351. if (!sch->schib.pmcw.ena)
  352. return -EINVAL;
  353. if (cdev->private->state == DEV_STATE_NOT_OPER)
  354. return -ENODEV;
  355. if (cdev->private->state != DEV_STATE_ONLINE &&
  356. cdev->private->state != DEV_STATE_W4SENSE)
  357. return -EINVAL;
  358. ret = cio_halt(sch);
  359. if (ret == 0)
  360. cdev->private->intparm = intparm;
  361. return ret;
  362. }
  363. /**
  364. * ccw_device_resume() - resume channel program execution
  365. * @cdev: target ccw device
  366. *
  367. * ccw_device_resume() calls rsch on @cdev's subchannel.
  368. * Returns:
  369. * %0 on success,
  370. * -%ENODEV on device not operational,
  371. * -%EINVAL on invalid device state,
  372. * -%EBUSY on device busy or interrupt pending.
  373. * Context:
  374. * Interrupts disabled, ccw device lock held
  375. */
  376. int ccw_device_resume(struct ccw_device *cdev)
  377. {
  378. struct subchannel *sch;
  379. if (!cdev || !cdev->dev.parent)
  380. return -ENODEV;
  381. sch = to_subchannel(cdev->dev.parent);
  382. if (!sch->schib.pmcw.ena)
  383. return -EINVAL;
  384. if (cdev->private->state == DEV_STATE_NOT_OPER)
  385. return -ENODEV;
  386. if (cdev->private->state != DEV_STATE_ONLINE ||
  387. !(sch->schib.scsw.cmd.actl & SCSW_ACTL_SUSPENDED))
  388. return -EINVAL;
  389. return cio_resume(sch);
  390. }
  391. /*
  392. * Pass interrupt to device driver.
  393. */
  394. int
  395. ccw_device_call_handler(struct ccw_device *cdev)
  396. {
  397. struct subchannel *sch;
  398. unsigned int stctl;
  399. int ending_status;
  400. sch = to_subchannel(cdev->dev.parent);
  401. /*
  402. * we allow for the device action handler if .
  403. * - we received ending status
  404. * - the action handler requested to see all interrupts
  405. * - we received an intermediate status
  406. * - fast notification was requested (primary status)
  407. * - unsolicited interrupts
  408. */
  409. stctl = scsw_stctl(&cdev->private->irb.scsw);
  410. ending_status = (stctl & SCSW_STCTL_SEC_STATUS) ||
  411. (stctl == (SCSW_STCTL_ALERT_STATUS | SCSW_STCTL_STATUS_PEND)) ||
  412. (stctl == SCSW_STCTL_STATUS_PEND);
  413. if (!ending_status &&
  414. !cdev->private->options.repall &&
  415. !(stctl & SCSW_STCTL_INTER_STATUS) &&
  416. !(cdev->private->options.fast &&
  417. (stctl & SCSW_STCTL_PRIM_STATUS)))
  418. return 0;
  419. /* Clear pending timers for device driver initiated I/O. */
  420. if (ending_status)
  421. ccw_device_set_timeout(cdev, 0);
  422. /*
  423. * Now we are ready to call the device driver interrupt handler.
  424. */
  425. if (cdev->handler)
  426. cdev->handler(cdev, cdev->private->intparm,
  427. &cdev->private->irb);
  428. /*
  429. * Clear the old and now useless interrupt response block.
  430. */
  431. memset(&cdev->private->irb, 0, sizeof(struct irb));
  432. return 1;
  433. }
  434. /**
  435. * ccw_device_get_ciw() - Search for CIW command in extended sense data.
  436. * @cdev: ccw device to inspect
  437. * @ct: command type to look for
  438. *
  439. * During SenseID, command information words (CIWs) describing special
  440. * commands available to the device may have been stored in the extended
  441. * sense data. This function searches for CIWs of a specified command
  442. * type in the extended sense data.
  443. * Returns:
  444. * %NULL if no extended sense data has been stored or if no CIW of the
  445. * specified command type could be found,
  446. * else a pointer to the CIW of the specified command type.
  447. */
  448. struct ciw *ccw_device_get_ciw(struct ccw_device *cdev, __u32 ct)
  449. {
  450. int ciw_cnt;
  451. if (cdev->private->flags.esid == 0)
  452. return NULL;
  453. for (ciw_cnt = 0; ciw_cnt < MAX_CIWS; ciw_cnt++)
  454. if (cdev->private->senseid.ciw[ciw_cnt].ct == ct)
  455. return cdev->private->senseid.ciw + ciw_cnt;
  456. return NULL;
  457. }
  458. /**
  459. * ccw_device_get_path_mask() - get currently available paths
  460. * @cdev: ccw device to be queried
  461. * Returns:
  462. * %0 if no subchannel for the device is available,
  463. * else the mask of currently available paths for the ccw device's subchannel.
  464. */
  465. __u8 ccw_device_get_path_mask(struct ccw_device *cdev)
  466. {
  467. struct subchannel *sch;
  468. if (!cdev->dev.parent)
  469. return 0;
  470. sch = to_subchannel(cdev->dev.parent);
  471. return sch->lpm;
  472. }
  473. /*
  474. * Try to break the lock on a boxed device.
  475. */
  476. int
  477. ccw_device_stlck(struct ccw_device *cdev)
  478. {
  479. void *buf, *buf2;
  480. unsigned long flags;
  481. struct subchannel *sch;
  482. int ret;
  483. if (!cdev)
  484. return -ENODEV;
  485. if (cdev->drv && !cdev->private->options.force)
  486. return -EINVAL;
  487. sch = to_subchannel(cdev->dev.parent);
  488. CIO_TRACE_EVENT(2, "stl lock");
  489. CIO_TRACE_EVENT(2, dev_name(&cdev->dev));
  490. buf = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL);
  491. if (!buf)
  492. return -ENOMEM;
  493. buf2 = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL);
  494. if (!buf2) {
  495. kfree(buf);
  496. return -ENOMEM;
  497. }
  498. spin_lock_irqsave(sch->lock, flags);
  499. ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
  500. if (ret)
  501. goto out_unlock;
  502. /*
  503. * Setup ccw. We chain an unconditional reserve and a release so we
  504. * only break the lock.
  505. */
  506. cdev->private->iccws[0].cmd_code = CCW_CMD_STLCK;
  507. cdev->private->iccws[0].cda = (__u32) __pa(buf);
  508. cdev->private->iccws[0].count = 32;
  509. cdev->private->iccws[0].flags = CCW_FLAG_CC;
  510. cdev->private->iccws[1].cmd_code = CCW_CMD_RELEASE;
  511. cdev->private->iccws[1].cda = (__u32) __pa(buf2);
  512. cdev->private->iccws[1].count = 32;
  513. cdev->private->iccws[1].flags = 0;
  514. ret = cio_start(sch, cdev->private->iccws, 0);
  515. if (ret) {
  516. cio_disable_subchannel(sch); //FIXME: return code?
  517. goto out_unlock;
  518. }
  519. cdev->private->irb.scsw.cmd.actl |= SCSW_ACTL_START_PEND;
  520. spin_unlock_irqrestore(sch->lock, flags);
  521. wait_event(cdev->private->wait_q,
  522. cdev->private->irb.scsw.cmd.actl == 0);
  523. spin_lock_irqsave(sch->lock, flags);
  524. cio_disable_subchannel(sch); //FIXME: return code?
  525. if ((cdev->private->irb.scsw.cmd.dstat !=
  526. (DEV_STAT_CHN_END|DEV_STAT_DEV_END)) ||
  527. (cdev->private->irb.scsw.cmd.cstat != 0))
  528. ret = -EIO;
  529. /* Clear irb. */
  530. memset(&cdev->private->irb, 0, sizeof(struct irb));
  531. out_unlock:
  532. kfree(buf);
  533. kfree(buf2);
  534. spin_unlock_irqrestore(sch->lock, flags);
  535. return ret;
  536. }
  537. void *ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no)
  538. {
  539. struct subchannel *sch;
  540. struct chp_id chpid;
  541. sch = to_subchannel(cdev->dev.parent);
  542. chp_id_init(&chpid);
  543. chpid.id = sch->schib.pmcw.chpid[chp_no];
  544. return chp_get_chp_desc(chpid);
  545. }
  546. /**
  547. * ccw_device_get_id - obtain a ccw device id
  548. * @cdev: device to obtain the id for
  549. * @dev_id: where to fill in the values
  550. */
  551. void ccw_device_get_id(struct ccw_device *cdev, struct ccw_dev_id *dev_id)
  552. {
  553. *dev_id = cdev->private->dev_id;
  554. }
  555. EXPORT_SYMBOL(ccw_device_get_id);
  556. /**
  557. * ccw_device_tm_start_key - perform start function
  558. * @cdev: ccw device on which to perform the start function
  559. * @tcw: transport-command word to be started
  560. * @intparm: user defined parameter to be passed to the interrupt handler
  561. * @lpm: mask of paths to use
  562. * @key: storage key to use for storage access
  563. *
  564. * Start the tcw on the given ccw device. Return zero on success, non-zero
  565. * otherwise.
  566. */
  567. int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw,
  568. unsigned long intparm, u8 lpm, u8 key)
  569. {
  570. struct subchannel *sch;
  571. int rc;
  572. sch = to_subchannel(cdev->dev.parent);
  573. if (!sch->schib.pmcw.ena)
  574. return -EINVAL;
  575. if (cdev->private->state != DEV_STATE_ONLINE)
  576. return -EIO;
  577. /* Adjust requested path mask to excluded varied off paths. */
  578. if (lpm) {
  579. lpm &= sch->opm;
  580. if (lpm == 0)
  581. return -EACCES;
  582. }
  583. rc = cio_tm_start_key(sch, tcw, lpm, key);
  584. if (rc == 0)
  585. cdev->private->intparm = intparm;
  586. return rc;
  587. }
  588. EXPORT_SYMBOL(ccw_device_tm_start_key);
  589. /**
  590. * ccw_device_tm_start_timeout_key - perform start function
  591. * @cdev: ccw device on which to perform the start function
  592. * @tcw: transport-command word to be started
  593. * @intparm: user defined parameter to be passed to the interrupt handler
  594. * @lpm: mask of paths to use
  595. * @key: storage key to use for storage access
  596. * @expires: time span in jiffies after which to abort request
  597. *
  598. * Start the tcw on the given ccw device. Return zero on success, non-zero
  599. * otherwise.
  600. */
  601. int ccw_device_tm_start_timeout_key(struct ccw_device *cdev, struct tcw *tcw,
  602. unsigned long intparm, u8 lpm, u8 key,
  603. int expires)
  604. {
  605. int ret;
  606. ccw_device_set_timeout(cdev, expires);
  607. ret = ccw_device_tm_start_key(cdev, tcw, intparm, lpm, key);
  608. if (ret != 0)
  609. ccw_device_set_timeout(cdev, 0);
  610. return ret;
  611. }
  612. EXPORT_SYMBOL(ccw_device_tm_start_timeout_key);
  613. /**
  614. * ccw_device_tm_start - perform start function
  615. * @cdev: ccw device on which to perform the start function
  616. * @tcw: transport-command word to be started
  617. * @intparm: user defined parameter to be passed to the interrupt handler
  618. * @lpm: mask of paths to use
  619. *
  620. * Start the tcw on the given ccw device. Return zero on success, non-zero
  621. * otherwise.
  622. */
  623. int ccw_device_tm_start(struct ccw_device *cdev, struct tcw *tcw,
  624. unsigned long intparm, u8 lpm)
  625. {
  626. return ccw_device_tm_start_key(cdev, tcw, intparm, lpm,
  627. PAGE_DEFAULT_KEY);
  628. }
  629. EXPORT_SYMBOL(ccw_device_tm_start);
  630. /**
  631. * ccw_device_tm_start_timeout - perform start function
  632. * @cdev: ccw device on which to perform the start function
  633. * @tcw: transport-command word to be started
  634. * @intparm: user defined parameter to be passed to the interrupt handler
  635. * @lpm: mask of paths to use
  636. * @expires: time span in jiffies after which to abort request
  637. *
  638. * Start the tcw on the given ccw device. Return zero on success, non-zero
  639. * otherwise.
  640. */
  641. int ccw_device_tm_start_timeout(struct ccw_device *cdev, struct tcw *tcw,
  642. unsigned long intparm, u8 lpm, int expires)
  643. {
  644. return ccw_device_tm_start_timeout_key(cdev, tcw, intparm, lpm,
  645. PAGE_DEFAULT_KEY, expires);
  646. }
  647. EXPORT_SYMBOL(ccw_device_tm_start_timeout);
  648. /**
  649. * ccw_device_tm_intrg - perform interrogate function
  650. * @cdev: ccw device on which to perform the interrogate function
  651. *
  652. * Perform an interrogate function on the given ccw device. Return zero on
  653. * success, non-zero otherwise.
  654. */
  655. int ccw_device_tm_intrg(struct ccw_device *cdev)
  656. {
  657. struct subchannel *sch = to_subchannel(cdev->dev.parent);
  658. if (!sch->schib.pmcw.ena)
  659. return -EINVAL;
  660. if (cdev->private->state != DEV_STATE_ONLINE)
  661. return -EIO;
  662. if (!scsw_is_tm(&sch->schib.scsw) ||
  663. !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_START_PEND))
  664. return -EINVAL;
  665. return cio_tm_intrg(sch);
  666. }
  667. EXPORT_SYMBOL(ccw_device_tm_intrg);
  668. // FIXME: these have to go:
  669. int
  670. _ccw_device_get_subchannel_number(struct ccw_device *cdev)
  671. {
  672. return cdev->private->schid.sch_no;
  673. }
  674. MODULE_LICENSE("GPL");
  675. EXPORT_SYMBOL(ccw_device_set_options_mask);
  676. EXPORT_SYMBOL(ccw_device_set_options);
  677. EXPORT_SYMBOL(ccw_device_clear_options);
  678. EXPORT_SYMBOL(ccw_device_clear);
  679. EXPORT_SYMBOL(ccw_device_halt);
  680. EXPORT_SYMBOL(ccw_device_resume);
  681. EXPORT_SYMBOL(ccw_device_start_timeout);
  682. EXPORT_SYMBOL(ccw_device_start);
  683. EXPORT_SYMBOL(ccw_device_start_timeout_key);
  684. EXPORT_SYMBOL(ccw_device_start_key);
  685. EXPORT_SYMBOL(ccw_device_get_ciw);
  686. EXPORT_SYMBOL(ccw_device_get_path_mask);
  687. EXPORT_SYMBOL(_ccw_device_get_subchannel_number);
  688. EXPORT_SYMBOL_GPL(ccw_device_get_chp_desc);