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