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