1#ifndef _ASM_IRQ_H
2#define _ASM_IRQ_H
3
4#include <linux/config.h>
5#ifdef __KERNEL__
6#include <asm/hardirq.h>
7
8/*
9 * How many IRQ's for S390 ?!?
10 */
11#define __MAX_SUBCHANNELS 65536
12#define NR_IRQS           __MAX_SUBCHANNELS
13#define NR_CHPIDS 256
14
15#define LPM_ANYPATH 0xff /* doesn't really belong here, Ingo? */
16
17#define INVALID_STORAGE_AREA ((void *)(-1 - 0x3FFF ))
18
19extern int disable_irq(unsigned int);
20extern int enable_irq(unsigned int);
21
22/*
23 * path management control word
24 */
25typedef struct {
26      __u32 intparm;      /* interruption parameter */
27      __u32 qf   : 1;     /* qdio facility */
28      __u32 res0 : 1;     /* reserved zeros */
29      __u32 isc  : 3;     /* interruption sublass */
30      __u32 res5 : 3;     /* reserved zeros */
31      __u32 ena  : 1;     /* enabled */
32      __u32 lm   : 2;     /* limit mode */
33      __u32 mme  : 2;     /* measurement-mode enable */
34      __u32 mp   : 1;     /* multipath mode */
35      __u32 tf   : 1;     /* timing facility */
36      __u32 dnv  : 1;     /* device number valid */
37      __u32 dev  : 16;    /* device number */
38      __u8  lpm;          /* logical path mask */
39      __u8  pnom;         /* path not operational mask */
40      __u8  lpum;         /* last path used mask */
41      __u8  pim;          /* path installed mask */
42      __u16 mbi;          /* measurement-block index */
43      __u8  pom;          /* path operational mask */
44      __u8  pam;          /* path available mask */
45      __u8  chpid[8];     /* CHPID 0-7 (if available) */
46      __u32 unused1 : 8;  /* reserved zeros */
47      __u32 st      : 3;  /* subchannel type */
48      __u32 unused2 : 20; /* reserved zeros */
49      __u32 csense  : 1;  /* concurrent sense; can be enabled ...*/
50                          /*  ... per MSCH, however, if facility */
51                          /*  ... is not installed, this results */
52                          /*  ... in an operand exception.       */
53   } __attribute__ ((packed)) pmcw_t;
54
55#endif /* __KERNEL__ */
56/*
57 * subchannel status word
58 */
59typedef struct {
60      __u32 key  : 4; /* subchannel key */
61      __u32 sctl : 1; /* suspend control */
62      __u32 eswf : 1; /* ESW format */
63      __u32 cc   : 2; /* deferred condition code */
64      __u32 fmt  : 1; /* format */
65      __u32 pfch : 1; /* prefetch */
66      __u32 isic : 1; /* initial-status interruption control */
67      __u32 alcc : 1; /* address-limit checking control */
68      __u32 ssi  : 1; /* supress-suspended interruption */
69      __u32 zcc  : 1; /* zero condition code */
70      __u32 ectl : 1; /* extended control */
71      __u32 pno  : 1;     /* path not operational */
72      __u32 res  : 1;     /* reserved */
73      __u32 fctl : 3;     /* function control */
74      __u32 actl : 7;     /* activity control */
75      __u32 stctl : 5;    /* status control */
76      __u32 cpa;          /* channel program address */
77      __u32 dstat : 8;    /* device status */
78      __u32 cstat : 8;    /* subchannel status */
79      __u32 count : 16;   /* residual count */
80   } __attribute__ ((packed)) scsw_t;
81
82#define SCSW_FCTL_CLEAR_FUNC     0x1
83#define SCSW_FCTL_HALT_FUNC      0x2
84#define SCSW_FCTL_START_FUNC     0x4
85
86#define SCSW_ACTL_SUSPENDED      0x1
87#define SCSW_ACTL_DEVACT         0x2
88#define SCSW_ACTL_SCHACT         0x4
89#define SCSW_ACTL_CLEAR_PEND     0x8
90#define SCSW_ACTL_HALT_PEND      0x10
91#define SCSW_ACTL_START_PEND     0x20
92#define SCSW_ACTL_RESUME_PEND    0x40
93
94#define SCSW_STCTL_STATUS_PEND   0x1
95#define SCSW_STCTL_SEC_STATUS    0x2
96#define SCSW_STCTL_PRIM_STATUS   0x4
97#define SCSW_STCTL_INTER_STATUS  0x8
98#define SCSW_STCTL_ALERT_STATUS  0x10
99
100#define DEV_STAT_ATTENTION       0x80
101#define DEV_STAT_STAT_MOD        0x40
102#define DEV_STAT_CU_END          0x20
103#define DEV_STAT_BUSY            0x10
104#define DEV_STAT_CHN_END         0x08
105#define DEV_STAT_DEV_END         0x04
106#define DEV_STAT_UNIT_CHECK      0x02
107#define DEV_STAT_UNIT_EXCEP      0x01
108
109#define SCHN_STAT_PCI            0x80
110#define SCHN_STAT_INCORR_LEN     0x40
111#define SCHN_STAT_PROG_CHECK     0x20
112#define SCHN_STAT_PROT_CHECK     0x10
113#define SCHN_STAT_CHN_DATA_CHK   0x08
114#define SCHN_STAT_CHN_CTRL_CHK   0x04
115#define SCHN_STAT_INTF_CTRL_CHK  0x02
116#define SCHN_STAT_CHAIN_CHECK    0x01
117
118/*
119 * architectured values for first sense byte
120 */
121#define SNS0_CMD_REJECT         0x80
122#define SNS_CMD_REJECT          SNS0_CMD_REJECT
123#define SNS0_INTERVENTION_REQ   0x40
124#define SNS0_BUS_OUT_CHECK      0x20
125#define SNS0_EQUIPMENT_CHECK    0x10
126#define SNS0_DATA_CHECK         0x08
127#define SNS0_OVERRUN            0x04
128/*                              0x02 reserved */
129#define SNS0_INCOMPL_DOMAIN     0x01
130
131/*
132 * architectured values for second sense byte
133 */
134#define SNS1_PERM_ERR           0x80
135#define SNS1_INV_TRACK_FORMAT   0x40
136#define SNS1_EOC                0x20
137#define SNS1_MESSAGE_TO_OPER    0x10
138#define SNS1_NO_REC_FOUND       0x08
139#define SNS1_FILE_PROTECTED     0x04
140#define SNS1_WRITE_INHIBITED    0x02
141#define SNS1_INPRECISE_END      0x01
142
143/*
144 * architectured values for third sense byte
145 */
146#define SNS2_REQ_INH_WRITE      0x80
147#define SNS2_CORRECTABLE        0x40
148#define SNS2_FIRST_LOG_ERR      0x20
149#define SNS2_ENV_DATA_PRESENT   0x10
150/*                              0x08 reserved */
151#define SNS2_INPRECISE_END      0x04
152/*                              0x02 reserved */
153/*                              0x01 reserved */
154
155#ifdef __KERNEL__
156/*
157 * subchannel information block
158 */
159typedef struct {
160      pmcw_t pmcw;             /* path management control word */
161      scsw_t scsw;             /* subchannel status word */
162      __u8 mda[12];            /* model dependent area */
163   } __attribute__ ((packed,aligned(4))) schib_t;
164#endif /* __KERNEL__ */
165
166typedef struct {
167      __u8  cmd_code;/* command code */
168      __u8  flags;   /* flags, like IDA adressing, etc. */
169      __u16 count;   /* byte count */
170      __u32 cda;     /* data address */
171   } __attribute__ ((packed,aligned(8))) ccw1_t;
172
173#define CCW_FLAG_DC             0x80
174#define CCW_FLAG_CC             0x40
175#define CCW_FLAG_SLI            0x20
176#define CCW_FLAG_SKIP           0x10
177#define CCW_FLAG_PCI            0x08
178#define CCW_FLAG_IDA            0x04
179#define CCW_FLAG_SUSPEND        0x02
180
181#define CCW_CMD_READ_IPL        0x02
182#define CCW_CMD_NOOP            0x03
183#define CCW_CMD_BASIC_SENSE     0x04
184#define CCW_CMD_TIC             0x08
185#define CCW_CMD_SENSE_PGID      0x34
186#define CCW_CMD_SUSPEND_RECONN  0x5B
187#define CCW_CMD_RDC             0x64
188#define CCW_CMD_SET_PGID        0xAF
189#define CCW_CMD_SENSE_ID        0xE4
190#define CCW_CMD_DCTL            0xF3
191
192#ifdef __KERNEL__
193#define SENSE_MAX_COUNT         0x20
194
195/*
196 * architectured values for first sense byte
197 */
198#define SNS0_CMD_REJECT         0x80
199#define SNS_CMD_REJECT          SNS0_CMD_REJECT
200#define SNS0_INTERVENTION_REQ   0x40
201#define SNS0_BUS_OUT_CHECK      0x20
202#define SNS0_EQUIPMENT_CHECK    0x10
203#define SNS0_DATA_CHECK         0x08
204#define SNS0_OVERRUN            0x04
205
206/*
207 * operation request block
208 */
209typedef struct {
210      __u32 intparm;  /* interruption parameter */
211      __u32 key  : 4; /* flags, like key, suspend control, etc. */
212      __u32 spnd : 1; /* suspend control */
213      __u32 res1 : 1; /* reserved */
214      __u32 mod  : 1; /* modification control */
215      __u32 sync : 1; /* synchronize control */
216      __u32 fmt  : 1; /* format control */
217      __u32 pfch : 1; /* prefetch control */
218      __u32 isic : 1; /* initial-status-interruption control */
219      __u32 alcc : 1; /* address-limit-checking control */
220      __u32 ssic : 1; /* suppress-suspended-interr. control */
221      __u32 res2 : 1; /* reserved */
222      __u32 c64  : 1; /* IDAW/QDIO 64 bit control  */
223      __u32 i2k  : 1; /* IDAW 2/4kB block size control */
224      __u32 lpm  : 8; /* logical path mask */
225      __u32 ils  : 1; /* incorrect length */
226      __u32 zero : 6; /* reserved zeros */
227      __u32 orbx : 1; /* ORB extension control */
228      __u32 cpa;      /* channel program address */
229   }  __attribute__ ((packed,aligned(4))) orb_t;
230
231#endif /* __KERNEL__ */
232typedef struct {
233      __u32 res0  : 4;  /* reserved */
234      __u32 pvrf  : 1;  /* path-verification-required flag */
235      __u32 cpt   : 1;  /* channel-path timeout */
236      __u32 fsavf : 1;  /* Failing storage address validity flag */
237      __u32 cons  : 1;  /* concurrent-sense */
238      __u32 res8  : 2;  /* reserved */
239      __u32 scnt  : 6;  /* sense count if cons == 1 */
240      __u32 res16 : 16; /* reserved */
241   } __attribute__ ((packed)) erw_t;
242
243/*
244 * subchannel logout area
245 */
246typedef struct {
247      __u32 res0  : 1;  /* reserved */
248      __u32 esf   : 7;  /* extended status flags */
249      __u32 lpum  : 8;  /* last path used mask */
250      __u32 res16 : 1;  /* reserved */
251      __u32 fvf   : 5;  /* field-validity flags */
252      __u32 sacc  : 2;  /* storage access code */
253      __u32 termc : 2;  /* termination code */
254      __u32 devsc : 1;  /* device-status check */
255      __u32 serr  : 1;  /* secondary error */
256      __u32 ioerr : 1;  /* i/o-error alert */
257      __u32 seqc  : 3;  /* sequence code */
258   } __attribute__ ((packed)) sublog_t ;
259
260/*
261 * Format 0 Extended Status Word (ESW)
262 */
263typedef struct {
264      sublog_t sublog;    /* subchannel logout */
265      erw_t    erw;       /* extended report word */
266      __u32    faddr;     /* failing address */
267      __u32    zeros[2];  /* 2 fullwords of zeros */
268   } __attribute__ ((packed)) esw0_t;
269
270/*
271 * Format 1 Extended Status Word (ESW)
272 */
273typedef struct {
274      __u8  zero0;    /* reserved zeros */
275      __u8  lpum;     /* last path used mask */
276      __u16 zero16;   /* reserved zeros */
277      erw_t erw;      /* extended report word */
278      __u32 zeros[3]; /* 2 fullwords of zeros */
279   } __attribute__ ((packed)) esw1_t;
280
281/*
282 * Format 2 Extended Status Word (ESW)
283 */
284typedef struct {
285      __u8  zero0;    /* reserved zeros */
286      __u8  lpum;     /* last path used mask */
287      __u16 dcti;     /* device-connect-time interval */
288      erw_t erw;      /* extended report word */
289      __u32 zeros[3]; /* 2 fullwords of zeros */
290   } __attribute__ ((packed)) esw2_t;
291
292/*
293 * Format 3 Extended Status Word (ESW)
294 */
295typedef struct {
296      __u8  zero0;    /* reserved zeros */
297      __u8  lpum;     /* last path used mask */
298      __u16 res;      /* reserved */
299      erw_t erw;      /* extended report word */
300      __u32 zeros[3]; /* 2 fullwords of zeros */
301   } __attribute__ ((packed)) esw3_t;
302
303typedef union {
304      esw0_t esw0;
305      esw1_t esw1;
306      esw2_t esw2;
307      esw3_t esw3;
308   } __attribute__ ((packed)) esw_t;
309
310/*
311 * interruption response block
312 */
313typedef struct {
314      scsw_t scsw;             /* subchannel status word */
315      esw_t  esw;              /* extended status word */
316      __u8   ecw[32];          /* extended control word */
317   } __attribute__ ((packed,aligned(4))) irb_t;
318#ifdef __KERNEL__
319
320/*
321 * TPI info structure
322 */
323typedef struct {
324	__u32 reserved1  : 16;   /* reserved 0x00000001 */
325	__u32 irq        : 16;   /* aka. subchannel number */
326	__u32 intparm;           /* interruption parameter */
327	__u32 adapter_IO : 1;
328	__u32 reserved2  : 1;
329	__u32 isc        : 3;
330	__u32 reserved3  : 12;
331	__u32 int_type   : 3;
332	__u32 reserved4  : 12;
333   } __attribute__ ((packed)) tpi_info_t;
334
335
336//
337// command information word  (CIW) layout
338//
339typedef struct _ciw {
340   __u32        et       :  2; // entry type
341   __u32        reserved :  2; // reserved
342   __u32        ct       :  4; // command type
343   __u32        cmd      :  8; // command
344   __u32        count    : 16; // count
345   } __attribute__ ((packed)) ciw_t;
346
347#define CIW_TYPE_RCD    0x0    // read configuration data
348#define CIW_TYPE_SII    0x1    // set interface identifier
349#define CIW_TYPE_RNI    0x2    // read node identifier
350
351#define MAX_CIWS 8
352//
353// sense-id response buffer layout
354//
355typedef struct {
356  /* common part */
357      __u8           reserved;     /* always 0x'FF' */
358      __u16          cu_type;      /* control unit type */
359      __u8           cu_model;     /* control unit model */
360      __u16          dev_type;     /* device type */
361      __u8           dev_model;    /* device model */
362      __u8           unused;       /* padding byte */
363  /* extended part */
364      ciw_t    ciw[MAX_CIWS];      /* variable # of CIWs */
365   }  __attribute__ ((packed,aligned(4))) senseid_t;
366/*
367 * where we put the ssd info
368 */
369typedef struct _ssd_info {
370	__u8   valid:1;
371	__u8   type:7;          /* subchannel type */
372	__u8   chpid[8];        /* chpids */
373	__u16  fla[8];          /* full link addresses */
374} __attribute__ ((packed)) ssd_info_t;
375
376/*
377 * area for store event information
378 */
379typedef struct chsc_area_t {
380	struct {
381		/* word 0 */
382		__u16 command_code1;
383		__u16 command_code2;
384		union {
385			struct {
386				/* word 1 */
387				__u32 reserved1;
388				/* word 2 */
389				__u32 reserved2;
390			} __attribute__ ((packed,aligned(8))) sei_req;
391			struct {
392				/* word 1 */
393				__u16 reserved1;
394				__u16 f_sch;     /* first subchannel */
395				/* word 2 */
396				__u16 reserved2;
397				__u16 l_sch;    /* last subchannel */
398			} __attribute__ ((packed,aligned(8))) ssd_req;
399		} request_block_data;
400		/* word 3 */
401		__u32 reserved3;
402	} __attribute__ ((packed,aligned(8))) request_block;
403	struct {
404		/* word 0 */
405		__u16 length;
406		__u16 response_code;
407		/* word 1 */
408		__u32 reserved1;
409		union {
410			struct {
411				/* word 2 */
412				__u8  flags;
413				__u8  vf;         /* validity flags */
414				__u8  rs;         /* reporting source */
415				__u8  cc;         /* content code */
416				/* word 3 */
417				__u16 fla;        /* full link address */
418				__u16 rsid;       /* reporting source id */
419				/* word 4 */
420				__u32 reserved2;
421				/* word 5 */
422				__u32 reserved3;
423				/* word 6 */
424				__u32 ccdf;       /* content-code dependent field */
425				/* word 7 */
426				__u32 reserved4;
427				/* word 8 */
428				__u32 reserved5;
429				/* word 9 */
430				__u32 reserved6;
431			} __attribute__ ((packed,aligned(8))) sei_res;
432			struct {
433				/* word 2 */
434				__u8 sch_valid : 1;
435				__u8 dev_valid : 1;
436				__u8 st        : 3; /* subchannel type */
437				__u8 zeroes    : 3;
438				__u8  unit_addr;  /* unit address */
439				__u16 devno;      /* device number */
440				/* word 3 */
441				__u8 path_mask;
442				__u8 fla_valid_mask;
443				__u16 sch;        /* subchannel */
444				/* words 4-5 */
445				__u8 chpid[8];    /* chpids 0-7 */
446				/* words 6-9 */
447				__u16 fla[8];     /* full link addresses 0-7 */
448			} __attribute__ ((packed,aligned(8))) ssd_res;
449		} response_block_data;
450	} __attribute__ ((packed,aligned(8))) response_block;
451} __attribute__ ((packed,aligned(PAGE_SIZE))) chsc_area_t;
452
453#endif /* __KERNEL__ */
454/*
455 * sense data
456 */
457typedef struct {
458      __u8          res[32];   /* reserved   */
459      __u8          data[32];  /* sense data */
460   } __attribute__ ((packed)) sense_t;
461
462/*
463 * device status area, to be provided by the device driver
464 *  when calling request_irq() as parameter "dev_id", later
465 *  tied to the "action" control block.
466 *
467 * Note : No data area must be added after union ii or the
468 *         effective devstat size calculation will fail !
469 */
470typedef struct {
471     __u16         devno;    /* device number, aka. "cuu" from irb */
472     unsigned long intparm;  /* interrupt parameter */
473     __u8          cstat;    /* channel status - accumulated */
474     __u8          dstat;    /* device status - accumulated */
475     __u8          lpum;     /* last path used mask from irb */
476     __u8          unused;   /* not used - reserved */
477     unsigned int  flag;     /* flag : see below */
478     __u32         cpa;      /* CCW address from irb at primary status */
479     __u32         rescnt;   /* res. count from irb at primary status */
480     __u32         scnt;     /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */
481     union {
482        irb_t   irb;         /* interruption response block */
483        sense_t sense;       /* sense information */
484        } ii;                /* interrupt information */
485  } devstat_t;
486
487#define DEVSTAT_FLAG_SENSE_AVAIL   0x00000001
488#define DEVSTAT_NOT_OPER           0x00000002
489#define DEVSTAT_START_FUNCTION     0x00000004
490#define DEVSTAT_HALT_FUNCTION      0x00000008
491#define DEVSTAT_STATUS_PENDING     0x00000010
492#define DEVSTAT_REVALIDATE         0x00000020
493#define DEVSTAT_DEVICE_GONE        0x00000040
494#define DEVSTAT_DEVICE_OWNED       0x00000080
495#define DEVSTAT_CLEAR_FUNCTION     0x00000100
496#define DEVSTAT_PCI                0x00000200
497#define DEVSTAT_SUSPENDED          0x00000400
498#define DEVSTAT_UNKNOWN_DEV        0x00000800
499#define DEVSTAT_UNFRIENDLY_DEV     0x00001000
500#define DEVSTAT_FINAL_STATUS       0x80000000
501
502#define DEVINFO_NOT_OPER           DEVSTAT_NOT_OPER
503#define DEVINFO_UNKNOWN_DEV        DEVSTAT_UNKNOWN_DEV
504#define DEVINFO_DEVICE_OWNED       DEVSTAT_DEVICE_OWNED
505#define DEVINFO_QDIO_CAPABLE       0x40000000
506#define DEVINFO_UNFRIENDLY_DEV     DEVSTAT_UNFRIENDLY_DEV
507
508#define INTPARM_STATUS_PENDING     0xFFFFFFFF
509#ifdef __KERNEL__
510
511#define IO_INTERRUPT_TYPE          0 /* I/O interrupt type */
512
513typedef  void (* io_handler_func1_t) ( int             irq,
514                                       devstat_t      *devstat,
515                                       struct pt_regs *rgs);
516
517typedef  void (* io_handler_func_t) ( int             irq,
518                                      void           *devstat,
519                                      struct pt_regs *rgs);
520
521typedef  void ( * not_oper_handler_func_t)( int irq,
522                                            int status );
523
524typedef  int  (* adapter_int_handler_t)( __u32 intparm );
525
526typedef struct {
527	io_handler_func_t         handler;  /* interrupt handler routine */
528	const char               *name;     /* device name */
529	devstat_t                *dev_id;   /* device status block */
530   } irq_desc_t;
531
532typedef struct {
533	__u8  state1    :  2;   /* path state value 1 */
534	__u8  state2    :  2;   /* path state value 2 */
535	__u8  state3    :  1;   /* path state value 3 */
536	__u8  resvd     :  3;   /* reserved */
537	} __attribute__ ((packed)) path_state_t;
538
539typedef struct {
540   union {
541		__u8         fc;   /* SPID function code */
542		path_state_t ps;   /* SNID path state */
543	} inf;
544	__u32 cpu_addr  : 16;   /* CPU address */
545	__u32 cpu_id    : 24;   /* CPU identification */
546	__u32 cpu_model : 16;   /* CPU model */
547	__u32 tod_high;         /* high word TOD clock */
548	} __attribute__ ((packed)) pgid_t;
549
550#define SPID_FUNC_SINGLE_PATH      0x00
551#define SPID_FUNC_MULTI_PATH       0x80
552#define SPID_FUNC_ESTABLISH        0x00
553#define SPID_FUNC_RESIGN           0x40
554#define SPID_FUNC_DISBAND          0x20
555
556#define SNID_STATE1_RESET          0
557#define SNID_STATE1_UNGROUPED      2
558#define SNID_STATE1_GROUPED        3
559
560#define SNID_STATE2_NOT_RESVD      0
561#define SNID_STATE2_RESVD_ELSE     2
562#define SNID_STATE2_RESVD_SELF     3
563
564#define SNID_STATE3_MULTI_PATH     1
565#define SNID_STATE3_SINGLE_PATH    0
566
567/*
568 * Flags used as input parameters for do_IO()
569 */
570#define DOIO_EARLY_NOTIFICATION  0x0001 /* allow for I/O completion ... */
571                                        /* ... notification after ... */
572                                        /* ... primary interrupt status */
573#define DOIO_RETURN_CHAN_END     DOIO_EARLY_NOTIFICATION
574#define DOIO_VALID_LPM           0x0002 /* LPM input parameter is valid */
575#define DOIO_WAIT_FOR_INTERRUPT  0x0004 /* wait synchronously for interrupt */
576#define DOIO_REPORT_ALL          0x0008 /* report all interrupt conditions */
577#define DOIO_ALLOW_SUSPEND       0x0010 /* allow for channel prog. suspend */
578#define DOIO_DENY_PREFETCH       0x0020 /* don't allow for CCW prefetch */
579#define DOIO_SUPPRESS_INTER      0x0040 /* suppress intermediate inter. */
580                                        /* ... for suspended CCWs */
581#define DOIO_TIMEOUT             0x0080 /* 3 secs. timeout for sync. I/O */
582#define DOIO_DONT_CALL_INTHDLR   0x0100 /* don't call interrupt handler */
583#define DOIO_CANCEL_ON_TIMEOUT   0x0200 /* cancel I/O if it timed out */
584
585/*
586 * do_IO()
587 *
588 *  Start a S/390 channel program. When the interrupt arrives, the
589 *  IRQ handler is called, either immediately, delayed (dev-end missing,
590 *  or sense required) or never (no IRQ handler registered -
591 *  should never occur, as the IRQ (subchannel ID) should be
592 *  disabled if no handler is present. Depending on the action
593 *  taken, do_IO() returns :  0      - Success
594 *                           -EIO    - Status pending
595 *                                        see : action->dev_id->cstat
596 *                                              action->dev_id->dstat
597 *                           -EBUSY  - Device busy
598 *                           -ENODEV - Device not operational
599 */
600int do_IO( int            irq,          /* IRQ aka. subchannel number */
601           ccw1_t        *cpa,          /* logical channel program address */
602           unsigned long  intparm,      /* interruption parameter */
603           __u8           lpm,          /* logical path mask */
604           unsigned long  flag);        /* flags : see above */
605
606int start_IO( int           irq,       /* IRQ aka. subchannel number */
607              ccw1_t       *cpa,       /* logical channel program address */
608              unsigned long  intparm,   /* interruption parameter */
609              __u8          lpm,       /* logical path mask */
610              unsigned int  flag);     /* flags : see above */
611
612void do_crw_pending( void  );	         /* CRW handler */
613
614int resume_IO( int irq);               /* IRQ aka. subchannel number */
615
616int halt_IO( int           irq,         /* IRQ aka. subchannel number */
617             unsigned long intparm,     /* dummy intparm */
618             unsigned long flag);       /* possible DOIO_WAIT_FOR_INTERRUPT */
619
620int clear_IO( int           irq,         /* IRQ aka. subchannel number */
621              unsigned long intparm,     /* dummy intparm */
622              unsigned long flag);       /* possible DOIO_WAIT_FOR_INTERRUPT */
623
624int process_IRQ( struct pt_regs regs,
625                 unsigned int   irq,
626                 unsigned int   intparm);
627
628
629int enable_cpu_sync_isc ( int irq );
630int disable_cpu_sync_isc( int irq );
631
632typedef struct {
633     int          irq;                  /* irq, aka. subchannel */
634     __u16        devno;                /* device number */
635     unsigned int status;               /* device status */
636     senseid_t    sid_data;             /* senseID data */
637     } s390_dev_info_t;
638
639int get_dev_info( int irq, s390_dev_info_t *);   /* to be eliminated - don't use */
640
641int get_dev_info_by_irq  ( int irq, s390_dev_info_t *pdi);
642int get_dev_info_by_devno( __u16 devno, s390_dev_info_t *pdi);
643
644int          get_irq_by_devno( __u16 devno );
645unsigned int get_devno_by_irq( int irq );
646
647int get_irq_first( void );
648int get_irq_next ( int irq );
649
650int read_dev_chars( int irq, void **buffer, int length );
651int read_conf_data( int irq, void **buffer, int *length, __u8 lpm );
652
653int  s390_DevicePathVerification( int irq, __u8 domask );
654
655int s390_trigger_resense(int irq);
656
657int s390_request_irq_special( int                      irq,
658                              io_handler_func_t        io_handler,
659                              not_oper_handler_func_t  not_oper_handler,
660                              unsigned long            irqflags,
661                              const char              *devname,
662                              void                    *dev_id);
663
664extern int set_cons_dev(int irq);
665extern int reset_cons_dev(int irq);
666extern int wait_cons_dev(int irq);
667extern schib_t *s390_get_schib( int irq );
668
669extern int s390_register_adapter_interrupt(adapter_int_handler_t handler);
670extern int s390_unregister_adapter_interrupt(adapter_int_handler_t handler);
671
672/*
673 * Some S390 specific IO instructions as inline
674 */
675
676extern __inline__ int stsch(int irq, volatile schib_t *addr)
677{
678        int ccode;
679
680        __asm__ __volatile__(
681                "   lr    1,%1\n"
682                "   stsch 0(%2)\n"
683                "   ipm   %0\n"
684                "   srl   %0,28"
685                : "=d" (ccode)
686		: "d" (irq | 0x10000), "a" (addr)
687		: "cc", "1" );
688        return ccode;
689}
690
691extern __inline__ int msch(int irq, volatile schib_t *addr)
692{
693        int ccode;
694
695        __asm__ __volatile__(
696                "   lr    1,%1\n"
697                "   msch  0(%2)\n"
698                "   ipm   %0\n"
699                "   srl   %0,28"
700                : "=d" (ccode)
701		: "d" (irq | 0x10000L), "a" (addr)
702                : "cc", "1" );
703        return ccode;
704}
705
706extern __inline__ int msch_err(int irq, volatile schib_t *addr)
707{
708        int ccode;
709
710        __asm__ __volatile__(
711                "    lr   1,%1\n"
712                "    msch 0(%2)\n"
713                "0:  ipm  %0\n"
714                "    srl  %0,28\n"
715                "1:\n"
716#ifdef CONFIG_ARCH_S390X
717                ".section .fixup,\"ax\"\n"
718                "2:  l    %0,%3\n"
719                "    jg   1b\n"
720                ".previous\n"
721                ".section __ex_table,\"a\"\n"
722                "   .align 8\n"
723                "   .quad 0b,2b\n"
724                ".previous"
725#else
726                ".section .fixup,\"ax\"\n"
727                "2:  l    %0,%3\n"
728                "    bras 1,3f\n"
729                "    .long 1b\n"
730                "3:  l    1,0(1)\n"
731                "    br   1\n"
732                ".previous\n"
733                ".section __ex_table,\"a\"\n"
734                "   .align 4\n"
735                "   .long 0b,2b\n"
736                ".previous"
737#endif
738                : "=d" (ccode)
739                : "d" (irq | 0x10000L), "a" (addr), "i" (__LC_PGM_ILC)
740                : "cc", "1" );
741        return ccode;
742}
743
744extern __inline__ int tsch(int irq, volatile irb_t *addr)
745{
746        int ccode;
747
748        __asm__ __volatile__(
749                "   lr    1,%1\n"
750                "   tsch  0(%2)\n"
751                "   ipm   %0\n"
752                "   srl   %0,28"
753                : "=d" (ccode)
754		: "d" (irq | 0x10000L), "a" (addr)
755                : "cc", "1" );
756        return ccode;
757}
758
759extern __inline__ int tpi( volatile tpi_info_t *addr)
760{
761        int ccode;
762
763        __asm__ __volatile__(
764                "   tpi   0(%1)\n"
765                "   ipm   %0\n"
766                "   srl   %0,28"
767                : "=d" (ccode)
768		: "a" (addr)
769                : "cc", "1" );
770        return ccode;
771}
772
773extern __inline__ int ssch(int irq, volatile orb_t *addr)
774{
775        int ccode;
776
777        __asm__ __volatile__(
778                "   lr    1,%1\n"
779                "   ssch  0(%2)\n"
780                "   ipm   %0\n"
781                "   srl   %0,28"
782                : "=d" (ccode)
783		: "d" (irq | 0x10000L), "a" (addr)
784                : "cc", "1" );
785        return ccode;
786}
787
788extern __inline__ int rsch(int irq)
789{
790        int ccode;
791
792        __asm__ __volatile__(
793                "   lr    1,%1\n"
794                "   rsch\n"
795                "   ipm   %0\n"
796                "   srl   %0,28"
797                : "=d" (ccode)
798		: "d" (irq | 0x10000L)
799                : "cc", "1" );
800        return ccode;
801}
802
803extern __inline__ int csch(int irq)
804{
805        int ccode;
806
807        __asm__ __volatile__(
808                "   lr    1,%1\n"
809                "   csch\n"
810                "   ipm   %0\n"
811                "   srl   %0,28"
812                : "=d" (ccode)
813		: "d" (irq | 0x10000L)
814                : "cc", "1" );
815        return ccode;
816}
817
818extern __inline__ int hsch(int irq)
819{
820        int ccode;
821
822        __asm__ __volatile__(
823                "   lr    1,%1\n"
824                "   hsch\n"
825                "   ipm   %0\n"
826                "   srl   %0,28"
827                : "=d" (ccode)
828		: "d" (irq | 0x10000L)
829                : "cc", "1" );
830        return ccode;
831}
832
833extern __inline__ int xsch(int irq)
834{
835	int ccode;
836
837	__asm__ __volatile__(
838                "   lr    1,%1\n"
839                "   .insn rre,0xb2760000,%1,0\n"
840                "   ipm   %0\n"
841                "   srl   %0,28"
842                : "=d" (ccode)
843		: "d" (irq | 0x10000L)
844                : "cc", "1" );
845	return ccode;
846}
847
848extern __inline__ int iac( void)
849{
850        int ccode;
851
852        __asm__ __volatile__(
853                "   iac   1\n"
854                "   ipm   %0\n"
855                "   srl   %0,28"
856                : "=d" (ccode) : : "cc", "1" );
857        return ccode;
858}
859
860extern __inline__ int rchp(int chpid)
861{
862        int ccode;
863
864        __asm__ __volatile__(
865                "   lr    1,%1\n"
866                "   rchp\n"
867                "   ipm   %0\n"
868                "   srl   %0,28"
869                : "=d" (ccode)
870		: "d" (chpid)
871                : "cc", "1" );
872        return ccode;
873}
874
875typedef struct {
876     __u16 vrdcdvno : 16;   /* device number (input) */
877     __u16 vrdclen  : 16;   /* data block length (input) */
878     __u32 vrdcvcla : 8;    /* virtual device class (output) */
879     __u32 vrdcvtyp : 8;    /* virtual device type (output) */
880     __u32 vrdcvsta : 8;    /* virtual device status (output) */
881     __u32 vrdcvfla : 8;    /* virtual device flags (output) */
882     __u32 vrdcrccl : 8;    /* real device class (output) */
883     __u32 vrdccrty : 8;    /* real device type (output) */
884     __u32 vrdccrmd : 8;    /* real device model (output) */
885     __u32 vrdccrft : 8;    /* real device feature (output) */
886     } __attribute__ ((packed,aligned(4))) diag210_t;
887
888void VM_virtual_device_info( __u16      devno,   /* device number */
889                             senseid_t *ps );    /* ptr to senseID data */
890
891extern __inline__ int diag210( diag210_t * addr)
892{
893        int ccode;
894
895        __asm__ __volatile__(
896#ifdef CONFIG_ARCH_S390X
897                "   sam31\n"
898                "   diag  %1,0,0x210\n"
899                "   sam64\n"
900#else
901                "   diag  %1,0,0x210\n"
902#endif
903                "   ipm   %0\n"
904                "   srl   %0,28"
905                : "=d" (ccode)
906		: "a" (addr)
907                : "cc" );
908        return ccode;
909}
910extern __inline__ int chsc( chsc_area_t * chsc_area)
911{
912	int cc;
913
914	__asm__ __volatile__ (
915	        ".insn	rre,0xb25f0000,%1,0	\n\t"
916		"ipm	%0	\n\t"
917		"srl	%0,28	\n\t"
918		: "=d" (cc)
919		: "d" (chsc_area)
920		: "cc" );
921
922	return cc;
923}
924
925/*
926 * Various low-level irq details needed by irq.c, process.c,
927 * time.c, io_apic.c and smp.c
928 *
929 * Interrupt entry/exit code at both C and assembly level
930 */
931
932void mask_irq(unsigned int irq);
933void unmask_irq(unsigned int irq);
934
935#define MAX_IRQ_SOURCES 128
936
937extern spinlock_t irq_controller_lock;
938
939#ifdef CONFIG_SMP
940
941#include <asm/atomic.h>
942
943static inline void irq_enter(int cpu, unsigned int irq)
944{
945        hardirq_enter(cpu);
946        while (atomic_read(&global_irq_lock) != 0) {
947                eieio();
948        }
949}
950
951static inline void irq_exit(int cpu, unsigned int irq)
952{
953        hardirq_exit(cpu);
954        release_irqlock(cpu);
955}
956
957
958#else
959
960#define irq_enter(cpu, irq)     (++local_irq_count(cpu))
961#define irq_exit(cpu, irq)      (--local_irq_count(cpu))
962
963#endif
964
965#define __STR(x) #x
966#define STR(x) __STR(x)
967
968#ifdef CONFIG_SMP
969
970/*
971 *      SMP has a few special interrupts for IPI messages
972 */
973
974#endif /* CONFIG_SMP */
975
976/*
977 * x86 profiling function, SMP safe. We might want to do this in
978 * assembly totally?
979 */
980extern char _stext;
981static inline void s390_do_profile (unsigned long addr)
982{
983        if (prof_buffer && current->pid) {
984#ifndef CONFIG_ARCH_S390X
985                addr &= 0x7fffffff;
986#endif
987                addr -= (unsigned long) &_stext;
988                addr >>= prof_shift;
989                /*
990                 * Don't ignore out-of-bounds EIP values silently,
991                 * put them into the last histogram slot, so if
992                 * present, they will show up as a sharp peak.
993                 */
994                if (addr > prof_len-1)
995                        addr = prof_len-1;
996                atomic_inc((atomic_t *)&prof_buffer[addr]);
997        }
998}
999
1000#include <asm/s390io.h>
1001
1002#define s390irq_spin_lock(irq) \
1003        spin_lock(&(ioinfo[irq]->irq_lock))
1004
1005#define s390irq_spin_unlock(irq) \
1006        spin_unlock(&(ioinfo[irq]->irq_lock))
1007
1008#define s390irq_spin_lock_irqsave(irq,flags) \
1009        spin_lock_irqsave(&(ioinfo[irq]->irq_lock), flags)
1010#define s390irq_spin_unlock_irqrestore(irq,flags) \
1011        spin_unlock_irqrestore(&(ioinfo[irq]->irq_lock), flags)
1012
1013#define touch_nmi_watchdog() do { } while(0)
1014
1015#endif /* __KERNEL__ */
1016#endif
1017
1018