device_ops.c 22 KB

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