s390/kernel: introduce .dma sections
[linux-2.6-microblaze.git] / arch / s390 / kernel / diag.c
index 7edaa73..e9dac9a 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/debugfs.h>
 #include <asm/diag.h>
 #include <asm/trace/diag.h>
+#include <asm/sections.h>
 
 struct diag_stat {
        unsigned int counter[NR_DIAG_STAT];
@@ -49,6 +50,9 @@ static const struct diag_desc diag_map[NR_DIAG_STAT] = {
        [DIAG_STAT_X500] = { .code = 0x500, .name = "Virtio Service" },
 };
 
+struct diag_ops __bootdata_preserved(diag_dma_ops);
+struct diag210 *__bootdata_preserved(__diag210_tmp_dma);
+
 static int show_diag_stat(struct seq_file *m, void *v)
 {
        struct diag_stat *stat;
@@ -139,30 +143,10 @@ EXPORT_SYMBOL(diag_stat_inc_norecursion);
 /*
  * Diagnose 14: Input spool file manipulation
  */
-static inline int __diag14(unsigned long rx, unsigned long ry1,
-                          unsigned long subcode)
-{
-       register unsigned long _ry1 asm("2") = ry1;
-       register unsigned long _ry2 asm("3") = subcode;
-       int rc = 0;
-
-       asm volatile(
-               "   sam31\n"
-               "   diag    %2,2,0x14\n"
-               "   sam64\n"
-               "   ipm     %0\n"
-               "   srl     %0,28\n"
-               : "=d" (rc), "+d" (_ry2)
-               : "d" (rx), "d" (_ry1)
-               : "cc");
-
-       return rc;
-}
-
 int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
 {
        diag_stat_inc(DIAG_STAT_X014);
-       return __diag14(rx, ry1, subcode);
+       return diag_dma_ops.diag14(rx, ry1, subcode);
 }
 EXPORT_SYMBOL(diag14);
 
@@ -195,30 +179,17 @@ EXPORT_SYMBOL(diag204);
  */
 int diag210(struct diag210 *addr)
 {
-       /*
-        * diag 210 needs its data below the 2GB border, so we
-        * use a static data area to be sure
-        */
-       static struct diag210 diag210_tmp;
        static DEFINE_SPINLOCK(diag210_lock);
        unsigned long flags;
        int ccode;
 
        spin_lock_irqsave(&diag210_lock, flags);
-       diag210_tmp = *addr;
+       *__diag210_tmp_dma = *addr;
 
        diag_stat_inc(DIAG_STAT_X210);
-       asm volatile(
-               "       lhi     %0,-1\n"
-               "       sam31\n"
-               "       diag    %1,0,0x210\n"
-               "0:     ipm     %0\n"
-               "       srl     %0,28\n"
-               "1:     sam64\n"
-               EX_TABLE(0b, 1b)
-               : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory");
-
-       *addr = diag210_tmp;
+       ccode = diag_dma_ops.diag210(__diag210_tmp_dma);
+
+       *addr = *__diag210_tmp_dma;
        spin_unlock_irqrestore(&diag210_lock, flags);
 
        return ccode;
@@ -243,27 +214,9 @@ EXPORT_SYMBOL(diag224);
 /*
  * Diagnose 26C: Access Certain System Information
  */
-static inline int __diag26c(void *req, void *resp, enum diag26c_sc subcode)
-{
-       register unsigned long _req asm("2") = (addr_t) req;
-       register unsigned long _resp asm("3") = (addr_t) resp;
-       register unsigned long _subcode asm("4") = subcode;
-       register unsigned long _rc asm("5") = -EOPNOTSUPP;
-
-       asm volatile(
-               "       sam31\n"
-               "       diag    %[rx],%[ry],0x26c\n"
-               "0:     sam64\n"
-               EX_TABLE(0b,0b)
-               : "+d" (_rc)
-               : [rx] "d" (_req), "d" (_resp), [ry] "d" (_subcode)
-               : "cc", "memory");
-       return _rc;
-}
-
 int diag26c(void *req, void *resp, enum diag26c_sc subcode)
 {
        diag_stat_inc(DIAG_STAT_X26C);
-       return __diag26c(req, resp, subcode);
+       return diag_dma_ops.diag26c(req, resp, subcode);
 }
 EXPORT_SYMBOL(diag26c);