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