hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/s390/cio/device_ops.c
....@@ -124,9 +124,7 @@
124124 /**
125125 * ccw_device_clear() - terminate I/O request processing
126126 * @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
130128 *
131129 * ccw_device_clear() calls csch on @cdev's subchannel.
132130 * Returns:
....@@ -179,6 +177,9 @@
179177 * completed during the time specified by @expires. If a timeout occurs, the
180178 * channel program is terminated via xsch, hsch or csch, and the device's
181179 * 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().
182183 * Returns:
183184 * %0, if the operation was successful;
184185 * -%EBUSY, if the device is busy, or status pending;
....@@ -256,6 +257,9 @@
256257 * Start a S/390 channel program. When the interrupt arrives, the
257258 * IRQ handler is called, either immediately, delayed (dev-end missing,
258259 * 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().
259263 * Returns:
260264 * %0, if the operation was successful;
261265 * -%EBUSY, if the device is busy, or status pending;
....@@ -287,6 +291,9 @@
287291 * Start a S/390 channel program. When the interrupt arrives, the
288292 * IRQ handler is called, either immediately, delayed (dev-end missing,
289293 * 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().
290297 * Returns:
291298 * %0, if the operation was successful;
292299 * -%EBUSY, if the device is busy, or status pending;
....@@ -322,6 +329,9 @@
322329 * completed during the time specified by @expires. If a timeout occurs, the
323330 * channel program is terminated via xsch, hsch or csch, and the device's
324331 * 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().
325335 * Returns:
326336 * %0, if the operation was successful;
327337 * -%EBUSY, if the device is busy, or status pending;
....@@ -343,11 +353,12 @@
343353 /**
344354 * ccw_device_halt() - halt I/O request processing
345355 * @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
349357 *
350358 * 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().
351362 * Returns:
352363 * %0 on success,
353364 * -%ENODEV on device not operational,
....@@ -429,8 +440,8 @@
429440 if (cdev->private->flags.esid == 0)
430441 return NULL;
431442 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;
434445 return NULL;
435446 }
436447
....@@ -699,6 +710,141 @@
699710 }
700711 EXPORT_SYMBOL_GPL(ccw_device_get_schid);
701712
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
+
702848 EXPORT_SYMBOL(ccw_device_set_options_mask);
703849 EXPORT_SYMBOL(ccw_device_set_options);
704850 EXPORT_SYMBOL(ccw_device_clear_options);