1 /* CARDRDR.C    (c) Copyright Roger Bowler, 1999-2009                */
2 /*              ESA/390 Card Reader Device Handler                   */
3 
4 /*-------------------------------------------------------------------*/
5 /* This module contains device handling functions for emulated       */
6 /* card reader devices.                                              */
7 /*-------------------------------------------------------------------*/
8 
9 #include "hstdinc.h"
10 #include "hercules.h"
11 
12 #include "devtype.h"
13 
14 #include "sockdev.h"
15 
16 
17 #if defined(WIN32) && defined(OPTION_DYNAMIC_LOAD) && !defined(HDL_USE_LIBTOOL) && !defined(_MSVC_)
18  SYSBLK *psysblk;
19  #define sysblk (*psysblk)
20 #endif
21 
22 
23 /*-------------------------------------------------------------------*/
24 /* ISW 2003/03/07                                                    */
25 /* 3505 Byte 1 Sense Codes                                           */
26 /*-------------------------------------------------------------------*/
27 #define SENSE1_RDR_PERM         0x80 /* Permanent Err key depressed  */
28 #define SENSE1_RDR_AUTORETRY    0x40 /* Don't know                   */
29 #define SENSE1_RDR_MOTIONMF     0x20 /* Motion Malfunction           */
30 #define SENSE1_RDR_RAIC         0x10 /* Retry After Intreq Cleared   */
31 /*-------------------------------------------------------------------*/
32 /* Internal macro definitions                                        */
33 /*-------------------------------------------------------------------*/
34 #define CARD_SIZE        80
35 #define HEX40            ((BYTE)0x40)
36 
37 /*-------------------------------------------------------------------*/
38 /* Initialize the device handler                                     */
39 /*-------------------------------------------------------------------*/
cardrdr_init_handler(DEVBLK * dev,int argc,char * argv[])40 static int cardrdr_init_handler ( DEVBLK *dev, int argc, char *argv[] )
41 {
42 int     i;                              /* Array subscript           */
43 int     fc;                             /* File counter              */
44 
45     int sockdev = 0;
46 
47     if (dev->bs)
48     {
49         if (!unbind_device(dev))
50         {
51             // (error message already issued)
52             return -1;
53         }
54     }
55 
56     /* Initialize device dependent fields */
57 
58     dev->fd = -1;
59     dev->fh = NULL;
60     dev->multifile = 0;
61     dev->ebcdic = 0;
62     dev->ascii = 0;
63     dev->trunc = 0;
64     dev->cardpos = 0;
65     dev->cardrem = 0;
66     dev->autopad = 0;
67 
68     if(!sscanf(dev->typname,"%hx",&(dev->devtype)))
69         dev->devtype = 0x2501;
70 
71     fc = 0;
72 
73     if (dev->more_files) free (dev->more_files);
74 
75     dev->more_files = malloc(sizeof(char*) * (fc + 1));
76 
77     if (!dev->more_files)
78     {
79         logmsg (_("HHCRD001E Out of memory\n"));
80         return -1;
81     }
82 
83     dev->more_files[fc] = NULL;
84 
85     /* Process the driver arguments starting with the SECOND
86        argument. (The FIRST argument is the filename and is
87        checked later further below.) */
88 
89     for (i = 1; i < argc; i++)
90     {
91         /* sockdev means the device file is actually
92            a connected socket instead of a disk file.
93            The file name is the socket_spec (host:port)
94            to listen for connections on. */
95 
96         if (strcasecmp(argv[i], "sockdev") == 0)
97         {
98             sockdev = 1;
99             continue;
100         }
101 
102         /* multifile means to automatically open the next
103            i/p file if multiple i/p files are defined.   */
104 
105         if (strcasecmp(argv[i], "multifile") == 0)
106         {
107             dev->multifile = 1;
108             continue;
109         }
110 
111         /* eof means that unit exception will be returned at
112            end of file, instead of intervention required */
113 
114         if (strcasecmp(argv[i], "eof") == 0)
115         {
116             dev->rdreof = 1;
117             continue;
118         }
119 
120         /* intrq means that intervention required will be returned at
121            end of file, instead of unit exception */
122 
123         if (strcasecmp(argv[i], "intrq") == 0)
124         {
125             dev->rdreof = 0;
126             continue;
127         }
128 
129         /* ebcdic means that the card image file consists of
130            fixed length 80-byte EBCDIC card images with no
131            line-end delimiters */
132 
133         if (strcasecmp(argv[i], "ebcdic") == 0)
134         {
135             dev->ebcdic = 1;
136             continue;
137         }
138 
139         /* ascii means that the card image file consists of
140            variable length ASCII records delimited by either
141            line-feed or carriage-return line-feed sequences */
142 
143         if (strcasecmp(argv[i], "ascii") == 0)
144         {
145             dev->ascii = 1;
146             continue;
147         }
148 
149         /* trunc means that records longer than 80 bytes will
150            be silently truncated to 80 bytes when processing a
151            variable length ASCII file.  The default behaviour
152            is to present a data check if an overlength record
153            is encountered.  The trunc option is ignored except
154            when processing an ASCII card image file. */
155 
156         if (strcasecmp(argv[i], "trunc") == 0)
157         {
158             dev->trunc = 1;
159             continue;
160         }
161 
162         /* autopad means that if reading fixed sized records
163          * (ebcdic) and end of file is reached in the middle of
164          * a record, the record is automatically padded to 80 bytes.
165          */
166 
167         if (strcasecmp(argv[i], "autopad") == 0)
168         {
169             dev->autopad = 1;
170             continue;
171         }
172 
173         // add additional file arguments
174 
175         if (strlen(argv[i]) > sizeof(dev->filename)-1)
176         {
177             logmsg (_("HHCRD002E File name too long (max=%ud): \"%s\"\n"),
178                 (unsigned int)sizeof(dev->filename)-1,argv[i]);
179             return -1;
180         }
181 
182         if (access(argv[i], R_OK | F_OK) != 0)
183         {
184             logmsg (_("HHCRD003E Unable to access file \"%s\": %s\n"),
185                 argv[i], strerror(errno));
186             return -1;
187         }
188 
189         dev->more_files[fc++] = strdup(argv[i]);
190         dev->more_files = realloc(dev->more_files, sizeof(char*) * (fc + 1));
191 
192         if (!dev->more_files)
193         {
194             logmsg (_("HHCRD004E Out of memory\n"));
195             return -1;
196         }
197 
198         dev->more_files[fc] = NULL;
199     }
200 
201     dev->current_file = dev->more_files;
202 
203     /* Check for conflicting arguments */
204 
205     if (dev->ebcdic && dev->ascii)
206     {
207         logmsg (_("HHCRD005E Specify 'ascii' or 'ebcdic' (or neither) but"
208                   " not both\n"));
209         return -1;
210     }
211 
212     if (sockdev)
213     {
214         if (fc)
215         {
216             logmsg (_("HHCRD006E Only one filename (sock_spec) allowed for"
217                       " socket devices\n"));
218             return -1;
219         }
220 
221         // If neither ascii nor ebcdic is specified, default to ascii.
222         // This is required for socket devices because the open logic,
223         // if neither is specified, attempts to determine whether the data
224         // is actually ascii or ebcdic by reading the 1st 160 bytes of
225         // data and then rewinding to the beginning of the file afterwards.
226         //  Since you can't "rewind" a socket, we must therefore default
227         // to one of them.
228 
229         if (!dev->ebcdic && !dev->ascii)
230         {
231             logmsg (_("HHCRD007I Defaulting to 'ascii' for socket device"
232                       " %4.4X\n"),dev->devnum);
233             dev->ascii = 1;
234         }
235     }
236 
237     if (dev->multifile && !fc)
238     {
239         logmsg (_("HHCRD008W 'multifile' option ignored: only one file"
240                   " specified\n"));
241         dev->multifile = 0;
242     }
243 
244     /* The first argument is the file name */
245 
246     if (argc > 0)
247     {
248         /* Check for valid file name */
249 
250         if (strlen(argv[0]) > sizeof(dev->filename)-1)
251         {
252             logmsg (_("HHCRD009E File name too long (max=%ud): \"%s\"\n"),
253                 (unsigned int)sizeof(dev->filename)-1,argv[0]);
254             return -1;
255         }
256 
257         if (!sockdev)
258         {
259             /* Check for specification of no file mounted on reader */
260             if (argv[0][0] == '*')
261             {
262                 dev->filename[0] = '\0';
263             }
264             else if (access(argv[0], R_OK | F_OK) != 0)
265             {
266                 logmsg (_("HHCRD010E Unable to access file \"%s\": %s\n"),
267                     argv[0], strerror(errno));
268                 return -1;
269             }
270         }
271 
272         /* Save the file name in the device block */
273 
274         strcpy (dev->filename, argv[0]);
275     }
276     else
277     {
278         dev->filename[0] = '\0';
279     }
280 
281     /* Set size of i/o buffer */
282 
283     dev->bufsize = CARD_SIZE;
284 
285     /* Set number of sense bytes */
286 
287     /* ISW 20030307 : Empirical knowledge : DOS/VS R34 Erep */
288     /*                indicates 4 bytes in 3505 sense       */
289     dev->numsense = 4;
290 
291     /* Initialize the device identifier bytes */
292 
293     dev->devid[0] = 0xFF;
294     dev->devid[1] = 0x28; /* Control unit type is 2821-1 */
295     dev->devid[2] = 0x21;
296     dev->devid[3] = 0x01;
297     dev->devid[4] = dev->devtype >> 8;
298     dev->devid[5] = dev->devtype & 0xFF;
299     dev->devid[6] = 0x01;
300     dev->numdevid = 7;
301 
302     // If socket device, create a listening socket
303     // to accept connections on.
304 
305     if (sockdev && !bind_device(dev,dev->filename))
306     {
307         // (error message already issued)
308         return -1;
309     }
310 
311     return 0;
312 } /* end function cardrdr_init_handler */
313 
314 /*-------------------------------------------------------------------*/
315 /* Query the device definition                                       */
316 /*-------------------------------------------------------------------*/
cardrdr_query_device(DEVBLK * dev,char ** class,int buflen,char * buffer)317 static void cardrdr_query_device (DEVBLK *dev, char **class,
318                 int buflen, char *buffer)
319 {
320     BEGIN_DEVICE_CLASS_QUERY( "RDR", dev, class, buflen, buffer );
321 
322     snprintf (buffer, buflen, "%s%s%s%s%s%s%s%s",
323         ((dev->filename[0] == '\0') ? "*"          : (char *)dev->filename),
324         (dev->bs ?                    " sockdev"   : ""),
325         (dev->multifile ?             " multifile" : ""),
326         (dev->ascii ?                 " ascii"     : ""),
327         (dev->ebcdic ?                " ebcdic"    : ""),
328         (dev->autopad ?               " autopad"   : ""),
329         ((dev->ascii && dev->trunc) ? " trunc"     : ""),
330         (dev->rdreof ?                " eof"       : " intrq"));
331 
332 } /* end function cardrdr_query_device */
333 
334 /*-------------------------------------------------------------------*/
335 /* Close the device                                                  */
336 /*-------------------------------------------------------------------*/
cardrdr_close_device(DEVBLK * dev)337 static int cardrdr_close_device ( DEVBLK *dev )
338 {
339     /* Close the device file */
340 
341     if (0
342         || (  dev->bs && dev->fd >=  0   && close_socket( dev->fd ) <  0 )
343         || ( !dev->bs && dev->fh != NULL &&    fclose(    dev->fh ) != 0 )
344     )
345     {
346         int errnum = dev->bs ? get_HSO_errno() : errno;
347         logmsg (_("HHCRD011E Close error on file \"%s\": %s\n"),
348             dev->filename, strerror(errnum));
349         dev->fd = -1;
350         dev->fh = NULL;
351         return -1;
352     }
353 
354     if (dev->bs && (dev->bs->clientip || dev->bs->clientname))
355     {
356         logmsg (_("HHCRD012I %s (%s) disconnected from device %4.4X (%s)\n"),
357             dev->bs->clientip, dev->bs->clientname, dev->devnum, dev->bs->spec);
358     }
359 
360     dev->fd = -1;
361     dev->fh = NULL;
362 
363     return 0;
364 } /* end function cardrdr_close_device */
365 
366 
367 /*-------------------------------------------------------------------*/
368 /* Clear the card reader                                             */
369 /*-------------------------------------------------------------------*/
clear_cardrdr(DEVBLK * dev)370 static int clear_cardrdr ( DEVBLK *dev )
371 {
372     /* Close the card image file */
373     if (cardrdr_close_device(dev) != 0) return -1;
374 
375     if (dev->bs) return 0;
376 
377     /* Clear the file name */
378     dev->filename[0] = '\0';
379 
380     /* If next file is available, open it */
381     if (dev->current_file && *(dev->current_file))
382     {
383         strcpy(dev->filename, *(dev->current_file++));
384     }
385     else
386     {
387         /* Reset the device dependent flags */
388         dev->multifile = 0;
389         dev->ascii = 0;
390         dev->ebcdic = 0;
391 //      dev->rdreof = 0;
392         dev->trunc = 0;
393         dev->autopad = 0;
394     }
395 
396     return 0;
397 } /* end function clear_cardrdr */
398 
399 
400 /*-------------------------------------------------------------------*/
401 /* Open the card image file                                          */
402 /*-------------------------------------------------------------------*/
open_cardrdr(DEVBLK * dev,BYTE * unitstat)403 static int open_cardrdr ( DEVBLK *dev, BYTE *unitstat )
404 {
405 int     rc;                             /* Return code               */
406 int     i;                              /* Array subscript           */
407 int     len;                            /* Length of data            */
408 BYTE    buf[160];                       /* Auto-detection buffer     */
409 char    pathname[MAX_PATH];             /* file path in host format  */
410 
411     *unitstat = 0;
412 
413     // Socket device?
414 
415     if (dev->bs)
416     {
417         // Intervention required if no one has connected yet
418 
419         if (dev->fd == -1)
420         {
421             if(dev->rdreof)
422             {
423                 *unitstat=CSW_CE|CSW_DE|CSW_UX;
424                 return -1;
425             }
426             dev->sense[0] = SENSE_IR;
427             dev->sense[1] = SENSE1_RDR_RAIC; /* Retry when IntReq Cleared */
428             *unitstat = CSW_CE | CSW_DE | CSW_UC;
429             return -1;
430         }
431 
432         return 0;
433     }
434 
435     /* Intervention required if device has no file name */
436     if (dev->filename[0] == '\0')
437     {
438         if(dev->rdreof)
439         {
440             *unitstat=CSW_CE|CSW_DE|CSW_UX;
441             return -1;
442         }
443         dev->sense[0] = SENSE_IR;
444         dev->sense[1] = SENSE1_RDR_RAIC; /* Retry when IntReq Cleared */
445         *unitstat = CSW_CE | CSW_DE | CSW_UC;
446         return -1;
447     }
448 
449     /* Open the device file */
450     hostpath(pathname, dev->filename, sizeof(pathname));
451     rc = hopen(pathname, O_RDONLY | O_BINARY);
452     if (rc < 0)
453     {
454         /* Handle open failure */
455         logmsg (_("HHCRD013E Error opening file %s: %s\n"),
456                 dev->filename, strerror(errno));
457 
458         /* Set unit check with equipment check */
459         dev->sense[0] = SENSE_EC;
460         *unitstat = CSW_CE | CSW_DE | CSW_UC;
461         return -1;
462     }
463 
464     /* Save the file descriptor in the device block */
465     dev->fd = rc;
466     dev->fh = fdopen(dev->fd, "rb");
467 
468     /* If neither EBCDIC nor ASCII was specified, attempt to
469        detect the format by inspecting the first 160 bytes */
470     if (dev->ebcdic == 0 && dev->ascii == 0)
471     {
472         /* Read first 160 bytes of file into the buffer */
473         len = fread(buf, 1, sizeof(buf), dev->fh);
474         if (len < 0)
475         {
476             /* Handle read error condition */
477             logmsg (_("HHCRD014E Error reading file %s: %s\n"),
478                     dev->filename, strerror(errno));
479 
480             /* Close the file */
481             fclose(dev->fh);
482             dev->fd = -1;
483             dev->fh = NULL;
484 
485             /* Set unit check with equipment check */
486             dev->sense[0] = SENSE_EC;
487             *unitstat = CSW_CE | CSW_DE | CSW_UC;
488             return -1;
489         }
490 
491         /* Assume ASCII format if first 160 bytes contain only ASCII
492            characters, carriage return, line feed, tab, or EOF */
493         for (i = 0, dev->ascii = 1; i < len && buf[i] != '\x1A'; i++)
494         {
495             if ((buf[i] < 0x20 || buf[i] > 0x7F)
496                 && buf[i] != '\r' && buf[i] != '\n'
497                 && buf[i] != '\t')
498             {
499                 dev->ascii = 0;
500                 dev->ebcdic = 1;
501                 break;
502             }
503         } /* end for(i) */
504 
505         /* Rewind to start of file */
506         rc = fseek (dev->fh, 0, SEEK_SET);
507         if (rc < 0)
508         {
509             /* Handle seek error condition */
510             logmsg (_("HHCRD015E Seek error in file %s: %s\n"),
511                     dev->filename, strerror(errno));
512 
513             /* Close the file */
514             fclose (dev->fh);
515             dev->fd = -1;
516             dev->fh = NULL;
517 
518             /* Set unit check with equipment check */
519             dev->sense[0] = SENSE_EC;
520             *unitstat = CSW_CE | CSW_DE | CSW_UC;
521             return -1;
522         }
523 
524     } /* end if(auto-detect) */
525 
526     ASSERT(dev->fd != -1 && dev->fh);
527 
528     return 0;
529 } /* end function open_cardrdr */
530 
531 /*-------------------------------------------------------------------*/
532 /* Read an 80-byte EBCDIC card image into the device buffer          */
533 /*-------------------------------------------------------------------*/
read_ebcdic(DEVBLK * dev,BYTE * unitstat)534 static int read_ebcdic ( DEVBLK *dev, BYTE *unitstat )
535 {
536 int     rc;                             /* Return code               */
537 
538     /* Read 80 bytes of card image data into the device buffer */
539     if (dev->bs)
540         rc = read_socket( dev->fd, dev->buf, CARD_SIZE );
541     else
542         rc = fread(dev->buf, 1, CARD_SIZE, dev->fh);
543 
544     if ((rc > 0) && (rc < CARD_SIZE) && dev->autopad)
545     {
546         memset(&dev->buf[rc], 0, CARD_SIZE - rc);
547         rc = CARD_SIZE;
548     }
549     else if /* Check for End of file */
550     (0
551         || ( dev->bs && rc <= 0)
552         || (!dev->bs && feof(dev->fh))
553     )
554     {
555         /* Return unit exception or intervention required */
556         if (dev->rdreof)
557         {
558             *unitstat = CSW_CE | CSW_DE | CSW_UX;
559         }
560         else
561         {
562             dev->sense[0] = SENSE_IR;
563             dev->sense[1] = SENSE1_RDR_RAIC; /* Retry when IntReq Cleared */
564             *unitstat = CSW_CE | CSW_DE | CSW_UC;
565         }
566 
567         /* Close the file and clear the file name and flags */
568         if (clear_cardrdr(dev) != 0)
569         {
570             /* Set unit check with equipment check */
571             dev->sense[0] = SENSE_EC;
572             *unitstat = CSW_CE | CSW_DE | CSW_UC;
573             return -1;
574         }
575 
576         return -2;
577     }
578 
579     /* Handle read error condition */
580     if (rc < CARD_SIZE)
581     {
582         if (rc < 0)
583             logmsg (_("HHCRD016E Error reading file %s: %s\n"),
584                     dev->filename, strerror(errno));
585         else
586             logmsg (_("HHCRD017E Unexpected end of file on %s\n"),
587                     dev->filename);
588 
589         /* Set unit check with equipment check */
590         dev->sense[0] = SENSE_EC;
591         *unitstat = CSW_CE | CSW_DE | CSW_UC;
592         return -1;
593     }
594 
595     return 0;
596 } /* end function read_ebcdic */
597 
598 
599 /*-------------------------------------------------------------------*/
600 /* Read a variable length ASCII card image into the device buffer    */
601 /*-------------------------------------------------------------------*/
read_ascii(DEVBLK * dev,BYTE * unitstat)602 static int read_ascii ( DEVBLK *dev, BYTE *unitstat )
603 {
604 int     rc;                             /* Return code               */
605 int     i;                              /* Array subscript           */
606 BYTE    c = 0;                          /* Input character           */
607 
608     /* Prefill the card image with EBCDIC blanks */
609     memset (dev->buf, HEX40, CARD_SIZE);
610 
611     /* Read up to 80 bytes into device buffer */
612     for (i = 0; ; )
613     {
614         /* Read next byte of card image */
615         if (dev->bs)
616         {
617             BYTE b; rc = read_socket( dev->fd, &b, 1 );
618             if (rc <= 0) rc = EOF; else c = b;
619         }
620         else
621         {
622             rc = getc(dev->fh);
623             c = (BYTE)rc;
624         }
625 
626         /* Handle end-of-file condition */
627         if (rc == EOF || c == '\x1A')
628         {
629             /* End of record if there is any data in buffer */
630             if (i > 0) break;
631 
632             /* Return unit exception or intervention required */
633             if (dev->rdreof)
634             {
635                 *unitstat = CSW_CE | CSW_DE | CSW_UX;
636             }
637             else
638             {
639                 dev->sense[0] = SENSE_IR;
640                 dev->sense[1] = SENSE1_RDR_RAIC; /* Retry when IntReq Cleared */
641                 *unitstat = CSW_CE | CSW_DE | CSW_UC;
642             }
643 
644             /* Close the file and clear the file name and flags */
645             if (clear_cardrdr(dev) != 0)
646             {
647                 /* Set unit check with equipment check */
648                 dev->sense[0] = SENSE_EC;
649                 *unitstat = CSW_CE | CSW_DE | CSW_UC;
650                 return -1;
651             }
652 
653             return -2;
654         }
655 
656         /* Handle read error condition */
657         if (rc < 0)
658         {
659             logmsg (_("HHCRD018E Error reading file %s: %s\n"),
660                     dev->filename, strerror(errno));
661 
662             /* Set unit check with equipment check */
663             dev->sense[0] = SENSE_EC;
664             *unitstat = CSW_CE | CSW_DE | CSW_UC;
665             return -1;
666         }
667 
668         /* Ignore carriage return */
669         if (c == '\r') continue;
670 
671         /* Line-feed indicates end of variable length record */
672         if (c == '\n') break;
673 
674         /* Expand tabs to spaces */
675         if (c == '\t')
676         {
677             do {i++;} while ((i & 7) && (i < CARD_SIZE));
678             continue;
679         }
680 
681         /* Test for overlength record */
682         if (i >= CARD_SIZE)
683         {
684             /* Ignore excess characters if trunc option specified */
685             if (dev->trunc) continue;
686 
687             logmsg (_("HHCRD019E Card image exceeds %d bytes in file %s\n"),
688                     CARD_SIZE, dev->filename);
689 
690             /* Set unit check with data check */
691             dev->sense[0] = SENSE_DC;
692             *unitstat = CSW_CE | CSW_DE | CSW_UC;
693             return -1;
694         }
695 
696         /* Convert character to EBCDIC and store in device buffer */
697         dev->buf[i++] = host_to_guest(c);
698 
699     } /* end for(i) */
700 
701     return 0;
702 } /* end function read_ascii */
703 
704 
705 /*-------------------------------------------------------------------*/
706 /* Execute a Channel Command Word                                    */
707 /*-------------------------------------------------------------------*/
cardrdr_execute_ccw(DEVBLK * dev,BYTE code,BYTE flags,BYTE chained,U16 count,BYTE prevcode,int ccwseq,BYTE * iobuf,BYTE * more,BYTE * unitstat,U16 * residual)708 static void cardrdr_execute_ccw ( DEVBLK *dev, BYTE code, BYTE flags,
709         BYTE chained, U16 count, BYTE prevcode, int ccwseq,
710         BYTE *iobuf, BYTE *more, BYTE *unitstat, U16 *residual )
711 {
712 int     rc;                             /* Return code               */
713 int     num;                            /* Number of bytes to move   */
714 
715     UNREFERENCED(flags);
716     UNREFERENCED(prevcode);
717     UNREFERENCED(ccwseq);
718 
719     /* Open the device file if necessary */
720     if ( !IS_CCW_SENSE(code) &&
721         (dev->fd < 0 || (!dev->bs && !dev->fh)))
722     {
723         rc = open_cardrdr (dev, unitstat);
724         if (rc) return;
725     }
726 
727     /* Turn all read/feed commands into read, feed, select stacker 1 */
728     if ((code & 0x17) == 0x02) code = 0x02;
729 
730     /* Turn all feed-only commands into NOP. This is ugly, and should
731         really be thought out more. --JRM */
732     if ((code & 0x37) == 0x23) code = 0x03;
733 
734     /* Process depending on CCW opcode */
735     switch (code) {
736 
737     case 0x02:
738     /*---------------------------------------------------------------*/
739     /* READ                                                          */
740     /*---------------------------------------------------------------*/
741         /* Read next card if not data-chained from previous CCW */
742         if ((chained & CCW_FLAGS_CD) == 0)
743         {
744             for (;;)
745             {
746                 /* Read ASCII or EBCDIC card image */
747                 if (dev->ascii)
748                         rc = read_ascii (dev, unitstat);
749                 else
750                         rc = read_ebcdic (dev, unitstat);
751 
752                 if (0
753                         || rc != -2
754                         || !dev->multifile
755                         || open_cardrdr (dev, unitstat) != 0
756                         )
757                 break;
758             }
759 
760             /* Return error status if read was unsuccessful */
761             if (rc) break;
762 
763             /* Initialize number of bytes in current card */
764             dev->cardpos = 0;
765             dev->cardrem = CARD_SIZE;
766 
767         } /* end if(!data-chained) */
768 
769         /* Calculate number of bytes to read and set residual count */
770         num = (count < dev->cardrem) ? count : dev->cardrem;
771         *residual = count - num;
772         if (count < dev->cardrem) *more = 1;
773 
774         /* Copy data from card image buffer into channel buffer */
775         memcpy (iobuf, dev->buf + dev->cardpos, num);
776 
777         /* Update number of bytes remaining in card image buffer */
778         dev->cardpos += num;
779         dev->cardrem -= num;
780 
781         /* Return normal status */
782         *unitstat = CSW_CE | CSW_DE;
783         break;
784 
785     case 0x03:
786     /*---------------------------------------------------------------*/
787     /* CONTROL NO-OPERATION                                          */
788     /*---------------------------------------------------------------*/
789         *residual = 0;
790         *unitstat = CSW_CE | CSW_DE;
791         break;
792 
793     case 0x04:
794     /*---------------------------------------------------------------*/
795     /* SENSE                                                         */
796     /*---------------------------------------------------------------*/
797         /* Calculate residual byte count */
798         num = (count < dev->numsense) ? count : dev->numsense;
799         *residual = count - num;
800         if (count < dev->numsense) *more = 1;
801 
802         /* If sense is clear AND filename = "" OR sockdev and fd=-1 */
803         /* Put an IR sense - so that an unsolicited sense can see the intreq */
804         if(dev->sense[0]==0)
805         {
806             if(dev->filename[0]==0x00 ||
807                     (dev->bs && dev->fd==-1))
808             {
809                 dev->sense[0] = SENSE_IR;
810                 dev->sense[1] = SENSE1_RDR_RAIC; /* Retry when IntReq Cleared */
811             }
812         }
813 
814         /* Copy device sense bytes to channel I/O buffer */
815         memcpy (iobuf, dev->sense, num);
816 
817         /* Clear the device sense bytes */
818         memset (dev->sense, 0, sizeof(dev->sense));
819 
820         /* Return unit status */
821         *unitstat = CSW_CE | CSW_DE;
822         break;
823 
824     case 0xE4:
825     /*---------------------------------------------------------------*/
826     /* SENSE ID                                                      */
827     /*---------------------------------------------------------------*/
828         /* Calculate residual byte count */
829         num = (count < dev->numdevid) ? count : dev->numdevid;
830         *residual = count - num;
831         if (count < dev->numdevid) *more = 1;
832 
833         /* Copy device identifier bytes to channel I/O buffer */
834         memcpy (iobuf, dev->devid, num);
835 
836         /* Return unit status */
837         *unitstat = CSW_CE | CSW_DE;
838         break;
839 
840     default:
841     /*---------------------------------------------------------------*/
842     /* INVALID OPERATION                                             */
843     /*---------------------------------------------------------------*/
844         /* Set command reject sense byte, and unit check status */
845         dev->sense[0] = SENSE_CR;
846         *unitstat = CSW_CE | CSW_DE | CSW_UC;
847 
848     } /* end switch(code) */
849 
850 } /* end function cardrdr_execute_ccw */
851 
852 
853 #if defined(OPTION_DYNAMIC_LOAD)
854 static
855 #endif
856 DEVHND cardrdr_device_hndinfo = {
857         &cardrdr_init_handler,         /* Device Initialisation      */
858         &cardrdr_execute_ccw,          /* Device CCW execute         */
859         &cardrdr_close_device,         /* Device Close               */
860         &cardrdr_query_device,         /* Device Query               */
861         NULL,                          /* Device Start channel pgm   */
862         NULL,                          /* Device End channel pgm     */
863         NULL,                          /* Device Resume channel pgm  */
864         NULL,                          /* Device Suspend channel pgm */
865         NULL,                          /* Device Read                */
866         NULL,                          /* Device Write               */
867         NULL,                          /* Device Query used          */
868         NULL,                          /* Device Reserve             */
869         NULL,                          /* Device Release             */
870         NULL,                          /* Device Attention           */
871         NULL,                          /* Immediate CCW Codes        */
872         NULL,                          /* Signal Adapter Input       */
873         NULL,                          /* Signal Adapter Output      */
874         NULL,                          /* Hercules suspend           */
875         NULL                           /* Hercules resume            */
876 };
877 
878 /* Libtool static name colision resolution */
879 /* note : lt_dlopen will look for symbol & modulename_LTX_symbol */
880 #if !defined(HDL_BUILD_SHARED) && defined(HDL_USE_LIBTOOL)
881 #define hdl_ddev hdt3505_LTX_hdl_ddev
882 #define hdl_depc hdt3505_LTX_hdl_depc
883 #define hdl_reso hdt3505_LTX_hdl_reso
884 #define hdl_init hdt3505_LTX_hdl_init
885 #define hdl_fini hdt3505_LTX_hdl_fini
886 #endif
887 
888 
889 #if defined(OPTION_DYNAMIC_LOAD)
890 HDL_DEPENDENCY_SECTION;
891 {
892      HDL_DEPENDENCY(HERCULES);
893      HDL_DEPENDENCY(DEVBLK);
894      HDL_DEPENDENCY(SYSBLK);
895 }
896 END_DEPENDENCY_SECTION
897 
898 
899 #if defined(WIN32) && !defined(HDL_USE_LIBTOOL) && !defined(_MSVC_)
900   #undef sysblk
901   HDL_RESOLVER_SECTION;
902   {
903     HDL_RESOLVE_PTRVAR( psysblk, sysblk );
904   }
905   END_RESOLVER_SECTION
906 #endif
907 
908 
909 HDL_DEVICE_SECTION;
910 {
911     HDL_DEVICE(1442, cardrdr_device_hndinfo );
912     HDL_DEVICE(2501, cardrdr_device_hndinfo );
913     HDL_DEVICE(3505, cardrdr_device_hndinfo );
914 }
915 END_DEVICE_SECTION
916 #endif
917