| .. | .. |
|---|
| 124 | 124 | /** |
|---|
| 125 | 125 | * ccw_device_clear() - terminate I/O request processing |
|---|
| 126 | 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 |
|---|
| 127 | + * @intparm: interruption parameter to be returned upon conclusion of csch |
|---|
| 130 | 128 | * |
|---|
| 131 | 129 | * ccw_device_clear() calls csch on @cdev's subchannel. |
|---|
| 132 | 130 | * Returns: |
|---|
| .. | .. |
|---|
| 179 | 177 | * completed during the time specified by @expires. If a timeout occurs, the |
|---|
| 180 | 178 | * channel program is terminated via xsch, hsch or csch, and the device's |
|---|
| 181 | 179 | * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT). |
|---|
| 180 | + * The interruption handler will echo back the @intparm specified here, unless |
|---|
| 181 | + * another interruption parameter is specified by a subsequent invocation of |
|---|
| 182 | + * ccw_device_halt() or ccw_device_clear(). |
|---|
| 182 | 183 | * Returns: |
|---|
| 183 | 184 | * %0, if the operation was successful; |
|---|
| 184 | 185 | * -%EBUSY, if the device is busy, or status pending; |
|---|
| .. | .. |
|---|
| 256 | 257 | * Start a S/390 channel program. When the interrupt arrives, the |
|---|
| 257 | 258 | * IRQ handler is called, either immediately, delayed (dev-end missing, |
|---|
| 258 | 259 | * or sense required) or never (no IRQ handler registered). |
|---|
| 260 | + * The interruption handler will echo back the @intparm specified here, unless |
|---|
| 261 | + * another interruption parameter is specified by a subsequent invocation of |
|---|
| 262 | + * ccw_device_halt() or ccw_device_clear(). |
|---|
| 259 | 263 | * Returns: |
|---|
| 260 | 264 | * %0, if the operation was successful; |
|---|
| 261 | 265 | * -%EBUSY, if the device is busy, or status pending; |
|---|
| .. | .. |
|---|
| 287 | 291 | * Start a S/390 channel program. When the interrupt arrives, the |
|---|
| 288 | 292 | * IRQ handler is called, either immediately, delayed (dev-end missing, |
|---|
| 289 | 293 | * or sense required) or never (no IRQ handler registered). |
|---|
| 294 | + * The interruption handler will echo back the @intparm specified here, unless |
|---|
| 295 | + * another interruption parameter is specified by a subsequent invocation of |
|---|
| 296 | + * ccw_device_halt() or ccw_device_clear(). |
|---|
| 290 | 297 | * Returns: |
|---|
| 291 | 298 | * %0, if the operation was successful; |
|---|
| 292 | 299 | * -%EBUSY, if the device is busy, or status pending; |
|---|
| .. | .. |
|---|
| 322 | 329 | * completed during the time specified by @expires. If a timeout occurs, the |
|---|
| 323 | 330 | * channel program is terminated via xsch, hsch or csch, and the device's |
|---|
| 324 | 331 | * interrupt handler will be called with an irb containing ERR_PTR(-%ETIMEDOUT). |
|---|
| 332 | + * The interruption handler will echo back the @intparm specified here, unless |
|---|
| 333 | + * another interruption parameter is specified by a subsequent invocation of |
|---|
| 334 | + * ccw_device_halt() or ccw_device_clear(). |
|---|
| 325 | 335 | * Returns: |
|---|
| 326 | 336 | * %0, if the operation was successful; |
|---|
| 327 | 337 | * -%EBUSY, if the device is busy, or status pending; |
|---|
| .. | .. |
|---|
| 343 | 353 | /** |
|---|
| 344 | 354 | * ccw_device_halt() - halt I/O request processing |
|---|
| 345 | 355 | * @cdev: target ccw device |
|---|
| 346 | | - * @intparm: interruption parameter; value is only used if no I/O is |
|---|
| 347 | | - * outstanding, otherwise the intparm associated with the I/O request |
|---|
| 348 | | - * is returned |
|---|
| 356 | + * @intparm: interruption parameter to be returned upon conclusion of hsch |
|---|
| 349 | 357 | * |
|---|
| 350 | 358 | * ccw_device_halt() calls hsch on @cdev's subchannel. |
|---|
| 359 | + * The interruption handler will echo back the @intparm specified here, unless |
|---|
| 360 | + * another interruption parameter is specified by a subsequent invocation of |
|---|
| 361 | + * ccw_device_clear(). |
|---|
| 351 | 362 | * Returns: |
|---|
| 352 | 363 | * %0 on success, |
|---|
| 353 | 364 | * -%ENODEV on device not operational, |
|---|
| .. | .. |
|---|
| 429 | 440 | if (cdev->private->flags.esid == 0) |
|---|
| 430 | 441 | return NULL; |
|---|
| 431 | 442 | for (ciw_cnt = 0; ciw_cnt < MAX_CIWS; ciw_cnt++) |
|---|
| 432 | | - if (cdev->private->senseid.ciw[ciw_cnt].ct == ct) |
|---|
| 433 | | - return cdev->private->senseid.ciw + ciw_cnt; |
|---|
| 443 | + if (cdev->private->dma_area->senseid.ciw[ciw_cnt].ct == ct) |
|---|
| 444 | + return cdev->private->dma_area->senseid.ciw + ciw_cnt; |
|---|
| 434 | 445 | return NULL; |
|---|
| 435 | 446 | } |
|---|
| 436 | 447 | |
|---|
| .. | .. |
|---|
| 699 | 710 | } |
|---|
| 700 | 711 | EXPORT_SYMBOL_GPL(ccw_device_get_schid); |
|---|
| 701 | 712 | |
|---|
| 713 | +/** |
|---|
| 714 | + * ccw_device_pnso() - Perform Network-Subchannel Operation |
|---|
| 715 | + * @cdev: device on which PNSO is performed |
|---|
| 716 | + * @pnso_area: request and response block for the operation |
|---|
| 717 | + * @oc: Operation Code |
|---|
| 718 | + * @resume_token: resume token for multiblock response |
|---|
| 719 | + * @cnc: Boolean change-notification control |
|---|
| 720 | + * |
|---|
| 721 | + * pnso_area must be allocated by the caller with get_zeroed_page(GFP_KERNEL) |
|---|
| 722 | + * |
|---|
| 723 | + * Returns 0 on success. |
|---|
| 724 | + */ |
|---|
| 725 | +int ccw_device_pnso(struct ccw_device *cdev, |
|---|
| 726 | + struct chsc_pnso_area *pnso_area, u8 oc, |
|---|
| 727 | + struct chsc_pnso_resume_token resume_token, int cnc) |
|---|
| 728 | +{ |
|---|
| 729 | + struct subchannel_id schid; |
|---|
| 730 | + |
|---|
| 731 | + ccw_device_get_schid(cdev, &schid); |
|---|
| 732 | + return chsc_pnso(schid, pnso_area, oc, resume_token, cnc); |
|---|
| 733 | +} |
|---|
| 734 | +EXPORT_SYMBOL_GPL(ccw_device_pnso); |
|---|
| 735 | + |
|---|
| 736 | +/** |
|---|
| 737 | + * ccw_device_get_cssid() - obtain Channel Subsystem ID |
|---|
| 738 | + * @cdev: device to obtain the CSSID for |
|---|
| 739 | + * @cssid: The resulting Channel Subsystem ID |
|---|
| 740 | + */ |
|---|
| 741 | +int ccw_device_get_cssid(struct ccw_device *cdev, u8 *cssid) |
|---|
| 742 | +{ |
|---|
| 743 | + struct device *sch_dev = cdev->dev.parent; |
|---|
| 744 | + struct channel_subsystem *css = to_css(sch_dev->parent); |
|---|
| 745 | + |
|---|
| 746 | + if (css->id_valid) |
|---|
| 747 | + *cssid = css->cssid; |
|---|
| 748 | + return css->id_valid ? 0 : -ENODEV; |
|---|
| 749 | +} |
|---|
| 750 | +EXPORT_SYMBOL_GPL(ccw_device_get_cssid); |
|---|
| 751 | + |
|---|
| 752 | +/** |
|---|
| 753 | + * ccw_device_get_iid() - obtain MIF-image ID |
|---|
| 754 | + * @cdev: device to obtain the MIF-image ID for |
|---|
| 755 | + * @iid: The resulting MIF-image ID |
|---|
| 756 | + */ |
|---|
| 757 | +int ccw_device_get_iid(struct ccw_device *cdev, u8 *iid) |
|---|
| 758 | +{ |
|---|
| 759 | + struct device *sch_dev = cdev->dev.parent; |
|---|
| 760 | + struct channel_subsystem *css = to_css(sch_dev->parent); |
|---|
| 761 | + |
|---|
| 762 | + if (css->id_valid) |
|---|
| 763 | + *iid = css->iid; |
|---|
| 764 | + return css->id_valid ? 0 : -ENODEV; |
|---|
| 765 | +} |
|---|
| 766 | +EXPORT_SYMBOL_GPL(ccw_device_get_iid); |
|---|
| 767 | + |
|---|
| 768 | +/** |
|---|
| 769 | + * ccw_device_get_chpid() - obtain Channel Path ID |
|---|
| 770 | + * @cdev: device to obtain the Channel Path ID for |
|---|
| 771 | + * @chp_idx: Index of the channel path |
|---|
| 772 | + * @chpid: The resulting Channel Path ID |
|---|
| 773 | + */ |
|---|
| 774 | +int ccw_device_get_chpid(struct ccw_device *cdev, int chp_idx, u8 *chpid) |
|---|
| 775 | +{ |
|---|
| 776 | + struct subchannel *sch = to_subchannel(cdev->dev.parent); |
|---|
| 777 | + int mask; |
|---|
| 778 | + |
|---|
| 779 | + if ((chp_idx < 0) || (chp_idx > 7)) |
|---|
| 780 | + return -EINVAL; |
|---|
| 781 | + mask = 0x80 >> chp_idx; |
|---|
| 782 | + if (!(sch->schib.pmcw.pim & mask)) |
|---|
| 783 | + return -ENODEV; |
|---|
| 784 | + |
|---|
| 785 | + *chpid = sch->schib.pmcw.chpid[chp_idx]; |
|---|
| 786 | + return 0; |
|---|
| 787 | +} |
|---|
| 788 | +EXPORT_SYMBOL_GPL(ccw_device_get_chpid); |
|---|
| 789 | + |
|---|
| 790 | +/** |
|---|
| 791 | + * ccw_device_get_chid() - obtain Channel ID associated with specified CHPID |
|---|
| 792 | + * @cdev: device to obtain the Channel ID for |
|---|
| 793 | + * @chp_idx: Index of the channel path |
|---|
| 794 | + * @chid: The resulting Channel ID |
|---|
| 795 | + */ |
|---|
| 796 | +int ccw_device_get_chid(struct ccw_device *cdev, int chp_idx, u16 *chid) |
|---|
| 797 | +{ |
|---|
| 798 | + struct chp_id cssid_chpid; |
|---|
| 799 | + struct channel_path *chp; |
|---|
| 800 | + int rc; |
|---|
| 801 | + |
|---|
| 802 | + chp_id_init(&cssid_chpid); |
|---|
| 803 | + rc = ccw_device_get_chpid(cdev, chp_idx, &cssid_chpid.id); |
|---|
| 804 | + if (rc) |
|---|
| 805 | + return rc; |
|---|
| 806 | + chp = chpid_to_chp(cssid_chpid); |
|---|
| 807 | + if (!chp) |
|---|
| 808 | + return -ENODEV; |
|---|
| 809 | + |
|---|
| 810 | + mutex_lock(&chp->lock); |
|---|
| 811 | + if (chp->desc_fmt1.flags & 0x10) |
|---|
| 812 | + *chid = chp->desc_fmt1.chid; |
|---|
| 813 | + else |
|---|
| 814 | + rc = -ENODEV; |
|---|
| 815 | + mutex_unlock(&chp->lock); |
|---|
| 816 | + |
|---|
| 817 | + return rc; |
|---|
| 818 | +} |
|---|
| 819 | +EXPORT_SYMBOL_GPL(ccw_device_get_chid); |
|---|
| 820 | + |
|---|
| 821 | +/* |
|---|
| 822 | + * Allocate zeroed dma coherent 31 bit addressable memory using |
|---|
| 823 | + * the subchannels dma pool. Maximal size of allocation supported |
|---|
| 824 | + * is PAGE_SIZE. |
|---|
| 825 | + */ |
|---|
| 826 | +void *ccw_device_dma_zalloc(struct ccw_device *cdev, size_t size) |
|---|
| 827 | +{ |
|---|
| 828 | + void *addr; |
|---|
| 829 | + |
|---|
| 830 | + if (!get_device(&cdev->dev)) |
|---|
| 831 | + return NULL; |
|---|
| 832 | + addr = cio_gp_dma_zalloc(cdev->private->dma_pool, &cdev->dev, size); |
|---|
| 833 | + if (IS_ERR_OR_NULL(addr)) |
|---|
| 834 | + put_device(&cdev->dev); |
|---|
| 835 | + return addr; |
|---|
| 836 | +} |
|---|
| 837 | +EXPORT_SYMBOL(ccw_device_dma_zalloc); |
|---|
| 838 | + |
|---|
| 839 | +void ccw_device_dma_free(struct ccw_device *cdev, void *cpu_addr, size_t size) |
|---|
| 840 | +{ |
|---|
| 841 | + if (!cpu_addr) |
|---|
| 842 | + return; |
|---|
| 843 | + cio_gp_dma_free(cdev->private->dma_pool, cpu_addr, size); |
|---|
| 844 | + put_device(&cdev->dev); |
|---|
| 845 | +} |
|---|
| 846 | +EXPORT_SYMBOL(ccw_device_dma_free); |
|---|
| 847 | + |
|---|
| 702 | 848 | EXPORT_SYMBOL(ccw_device_set_options_mask); |
|---|
| 703 | 849 | EXPORT_SYMBOL(ccw_device_set_options); |
|---|
| 704 | 850 | EXPORT_SYMBOL(ccw_device_clear_options); |
|---|