diff --git a/src/devOpt/devBBInteract.c b/src/devOpt/devBBInteract.c deleted file mode 100644 index 9ad56d06c..000000000 --- a/src/devOpt/devBBInteract.c +++ /dev/null @@ -1,803 +0,0 @@ -/* devBBInteract.c */ -/* share/src/devOpt $Id$ - * - * Author: Ned D. Arnold - * Date: 06/19/91 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1988, 1989, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * All rights reserved. No part of this publication may be reproduced, - * stored in a retrieval system, transmitted, in any form or by any - * means, electronic, mechanical, photocopying, recording, or otherwise - * without prior written permission of Los Alamos National Laboratory - * and Argonne National Laboratory. - * - * Modification Log: - * ----------------- - * .01 06-19-91 nda initial coding & debugging - * .02 09-23-91 jrw added proper multi-link support - * .03 10-04-91 jrw rewrote as BI.c for use with BitBus - * .04 02-12-92 jrw added HEX file downloading support - * - */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -extern struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; - DRVSUPFUN qReq; -} drvBitBus; - -struct cmdPvt { - int busy; - long int count; -}; - -#define LIST_SIZE 10 - -static struct dpvtBitBusHead adpvt[LIST_SIZE+1]; /* last one is used for the 'F' command */ - -/* declare other required variables used by more than one routine */ - -int bbMsgDly = 0; - -extern int bbDebug; -static int replyIsBack; - -static int sendMsg(); -static int bbWork(); -static int configMsg(); -static int getInt(); -static int getChar(); -static int getString(); -static int showBbMsg(); -static int timingStudy(); -static int pingEm(); -static int downLoadCode(); -static int hex2bin(); -static int sendOnly(void); - -static int firstTime = 1; -static FAST_LOCK msgReply; - -int -BI() -{ - unsigned char ans; - int cnt; - - if(firstTime) - { - firstTime = 0; - FASTLOCKINIT(&msgReply); - FASTUNLOCK(&msgReply); - FASTLOCK(&msgReply); /* Make sure is locked at the begining */ - - for (cnt = 0; cnt <= LIST_SIZE; cnt++) - { - adpvt[cnt].finishProc = bbWork; - adpvt[cnt].priority = 0; - - adpvt[cnt].next = NULL; - adpvt[cnt].prev = NULL; - adpvt[cnt].txMsg.data = (unsigned char *)malloc(BB_MAX_DAT_LEN); - adpvt[cnt].txMsg.length = 7; - adpvt[cnt].txMsg.route = 0x40; - adpvt[cnt].rxMsg.data = (unsigned char *)malloc(BB_MAX_DAT_LEN); - adpvt[cnt].rxMsg.length = 7; - adpvt[cnt].psyncSem = NULL; - adpvt[cnt].rxMaxLen = BB_MAX_MSG_LENGTH; - } - } - - ans = 0; /* set loop not to exit */ - printf("\n\n"); - - while ((ans != 'q') && (ans != 'Q')) - { - printf("\n\nInteractive BB Program\n"); - printf("Select a function:\n"); /* main menu */ - printf(" 'C' to configure send message content\n"); - printf(" 'D' to display transmit & receive messages\n"); - printf(" 'P' to ping all Bitbus device addresses\n"); - printf(" 'S' to send & receive a message one time\n"); - printf(" 'T' to do timing on messages\n"); - printf(" 'R' to turn on the BB debugging flag\n"); - printf(" 'r' to turn off the BB debugging flag\n"); - printf(" 'F' to download intel HEX file to a bug\n"); - printf(" 'Q' to quit program\n"); - printf(">"); - ans = 0; /* clear previous selection */ - getChar(&ans); - - switch (ans) { - case 'c': /* configure message contents */ - case 'C': - configMsg(); - break; - - case 'p': - case 'P': /* ping all the bug addresses */ - pingEm(); - break; - - case 's': - case 'S': /* one shot: send one message */ - sendMsg(); - break; - - case 'u': - case 'U': - sendOnly(); /* Send a pair of messages */ - break; - - case 't': - case 'T': /* Timing analysis */ - /*timingStudy();*/ - break; - - case 'd': - case 'D': /* Display message contents */ - for (cnt = 1; cnt < LIST_SIZE; cnt++) /* for each message */ - { - printf("message %d Transmit buffer:\n", cnt); - showBbMsg(&(adpvt[cnt].txMsg)); - printf("message %d Receive buffer:\n", cnt); - showBbMsg(&(adpvt[cnt].rxMsg)); - } - break; - - case 'q': - case 'Q': /* quit */ - break; - - case 'r': /* turn off bbDebug */ - bbDebug = 0; - break; - case 'R': /* turn on bbDebug */ - bbDebug = 1; - break; - case 'f': - case 'F': - downLoadCode(); - break; - } /* end case */ - } /* end of while ans== q or Q */ - return(0); -} /* end of main */ - -#ifdef DONT_DO_THIS -static int -timingStudy() -{ - struct bbIntCmd *pCmd[LIST_SIZE]; - int inInt; /* input integer from operator */ - int reps; /* number of times to send a message */ - ULONG startTime; - ULONG endTime; - ULONG delta; - int Reps; - int i; - int j; - - for (i=0; i to terminate list) > "); - if (getInt(&inInt)) - { - if (inInt>0 && inIntbusy = 0; /* mark message 'not in queue' */ - pCmd[i]->count = 0; - } - else - { - pCmd[i] = NULL; /* terminate the list */ - i = LIST_SIZE; - } - } - else - { - pCmd[i] = NULL; /* terminate the list */ - i = LIST_SIZE; - } - } - - printf("Enter the number of messages to send > "); - if (!getInt(&inInt)) - return; /* if no entry, return to main menu */ - if(inInt < 0) - return; - reps = inInt; - Reps = reps; - - startTime = tickGet(); /* time the looping started */ - - while(reps) - { - for(i=0; ibusy) - { - pCmd[i]->count++; - pCmd[i]->busy = 1; /* mark the xact as busy */ - (*(drvBitBus.qReq))(pCmd[i]->link, &(pCmd[i]), BB_Q_HIGH); - reps--; - if (reps%10000 == 0) - { - printf("Timing study in progress with %d messages left, current status:\n", reps); - for (j=0; jcount); - } - else - j = LIST_SIZE; - } - - } - } - } - else - i = LIST_SIZE; /* force an exit from the loop */ - } - FASTLOCK(&msgReply); - } - - endTime = tickGet(); - delta = (endTime - startTime); /* measured time in ticks */ - if (delta == 0) - delta = 1; - printf("Total transmit and receiving time = %ld/60 Sec\n", delta); - printf("Messages/second = %.2f\n", (float) (60*Reps)/(float)delta); - - for (i=0; icount); - } - else - i = LIST_SIZE; - } - return(OK); -} -#endif -static int -sendOnly(void) -{ - int msgNum; /* index to array of messages */ - - printf("\nEnter Message # to Send (1 thru 5) > "); - if (!getInt(&msgNum)) - return(ERROR); /* if no entry, return to main menu */ - - if((msgNum >= LIST_SIZE) || (msgNum < 0)) - return(ERROR); - - return((*(drvBitBus.qReq))(&(adpvt[msgNum]), BB_Q_HIGH)); -} - -/***************************************************************************** - * sendMsg() - *****************************************************************************/ - -static int -sendMsg(void) -{ - int msgNum; /* index to array of messages */ - - printf("\nEnter Message # to Send (1 thru 5) > "); - if (!getInt(&msgNum)) - return(ERROR); /* if no entry, return to main menu */ - if((msgNum >= LIST_SIZE) || (msgNum < 0)) - return(ERROR); - - adpvt[msgNum].ageLimit = 0; /* Don't really need to reset each time */ - if ((*(drvBitBus.qReq))(&(adpvt[msgNum]), BB_Q_HIGH) != ERROR) - { - FASTLOCK(&msgReply); /* wait for response to return */ - - taskDelay(bbMsgDly); - - printf("response message:\n"); - showBbMsg(&(adpvt[msgNum].rxMsg)); - return(OK); - } - else - return(ERROR); -} - -static int -bbWork(pdpvt) -struct dpvtBitBusHead *pdpvt; -{ - if (bbDebug) - printf("BI's bbWork():entered\n"); - - replyIsBack = TRUE; - FASTUNLOCK(&msgReply); - return(0); -} -static int -pingEm() -{ - struct dpvtBitBusHead pdpvt; - char str[100]; - int inInt; - - pdpvt.finishProc = bbWork; - pdpvt.priority = 0; - - pdpvt.next = NULL; - pdpvt.prev = NULL; - pdpvt.txMsg.data = (unsigned char *)malloc(BB_MAX_DAT_LEN); - pdpvt.txMsg.length = 15; - pdpvt.txMsg.route = 0x40; - pdpvt.rxMsg.data = (unsigned char *)malloc(BB_MAX_DAT_LEN); - pdpvt.rxMsg.length = 7; - pdpvt.psyncSem = NULL; - pdpvt.rxMaxLen = BB_MAX_MSG_LENGTH; - - /* build a "send ID's" message */ - - printf("Enter BB Link (hex) [00]: "); - gets(str); - if (sscanf(str, "%x", &inInt) == 1) - pdpvt.link = inInt; - else - pdpvt.link = 0; - - pdpvt.txMsg.tasks = 0; - pdpvt.txMsg.cmd = 3; - pdpvt.txMsg.node = 0; - - while (pdpvt.txMsg.node < 255) - { - pdpvt.ageLimit = 0; - if ((*(drvBitBus.qReq))(&(pdpvt), BB_Q_HIGH) == ERROR) - return(ERROR); - - FASTLOCK(&msgReply); /* wait for response to return */ - if (pdpvt.rxMsg.cmd == 0) - { - printf("response message:\n"); - showBbMsg(&(pdpvt.rxMsg)); - } - pdpvt.txMsg.node++; - } - - return(OK); -} - -/*-------------------------------------------------------------------- - * configMsg() - * - * - Purpose - * Prompts the operator for the contents of a BB message - * Displays current value of the field as the default entry - * - */ - -static int -configMsg() -{ - int msgNum; /* index to array of messages */ - int inInt; - int cnt; - char str[100]; - - printf("\nEnter Message # to Configure (1 thru 5) > "); - if (!getInt(&inInt)) - return(0); /* if no entry, return to main menu */ - if((inInt >= LIST_SIZE) || (inInt < 0)) - return(0); - - msgNum = inInt; - - printf("\n\n Configuring Send Message # %d at %p \n", msgNum, &(adpvt[msgNum].txMsg)); - -/* Prompt the Operator with the current value of each parameter If - * only a is typed, keep current value, else replace value with - * entered value - */ - - adpvt[msgNum].txMsg.link = 0; - - printf("Enter BB Link (hex) [%2.2X]: ", (int) adpvt[msgNum].link); - gets(str); - if (sscanf(str, "%x", &inInt) == 1) - adpvt[msgNum].link = inInt; - - printf("Enter route (hex) [%2.2X]: ", adpvt[msgNum].txMsg.route); - gets(str); - if (sscanf(str, "%x", &inInt) == 1) - adpvt[msgNum].txMsg.route = inInt; - - printf("Enter Node (hex) [%2.2X]: ", adpvt[msgNum].txMsg.node); - gets(str); - if (sscanf(str, "%x", &inInt) == 1) - adpvt[msgNum].txMsg.node = inInt; - - printf("Enter tasks (hex) [%2.2X]: ", adpvt[msgNum].txMsg.tasks); - gets(str); - if (sscanf(str, "%x", &inInt) == 1) - adpvt[msgNum].txMsg.tasks = inInt; - - printf("Enter command (hex) [%2.2X]: ", adpvt[msgNum].txMsg.cmd); - gets(str); - if (sscanf(str, "%x", &inInt) == 1) - adpvt[msgNum].txMsg.cmd = inInt; - - adpvt[msgNum].txMsg.length = 7; - printf("Enter data 1 byte per line. Enter a dot to terminate list (hex)\n"); - for (cnt=0; cnt%s<\n", fnameStr); - return(ERROR); - } - /* get the link number */ - printf("Enter BB Link (hex) [%2.2X]: ", (int) pdpvt->link); - gets(str); - if (sscanf(str, "%x", &inInt) == 1) - pdpvt->link = inInt; - - /* get the bug number */ - printf("Enter Node (hex) [%2.2X]: ", pdpvt->txMsg.node); - gets(str); - if (sscanf(str, "%x", &inInt) == 1) - pdpvt->txMsg.node = inInt; - - pdpvt->txMsg.cmd = RAC_DOWNLOAD_MEM; - pdpvt->txMsg.tasks = BB_RAC_TASK; - - totalBytes = 0; - totalMsg = 0; - status = OK; - - FASTUNLOCK(&msgReply); /* prime for first loop */ - FASTLOCK(&msgReply); - - /* read the file 1 line at a time & send the code to the bug */ - msgBytes=0; - while (fgets(hexBuf, sizeof(hexBuf), fp) != NULL) - { - /* parse the headers in the hex record */ - if (hexBuf[0] != ':' || (hex2bin(&(hexBuf[7]) ,&recType) == ERROR)) - { - printf("Bad line in HEX file. Line:\n%s", hexBuf); - status = ERROR; - break; - } - if (recType == 1) /* EOF record located */ - break; - - if (recType != 0) /* unrecognised record type encountered */ - { - printf("Unrecognised record type 0x%2.2X in HEX file. Line:\n%s", recType, hexBuf); - status = ERROR; - break; - } - - /* find the starting address */ - if ((hex2bin(&(hexBuf[3]), &(pdpvt->txMsg.data[0])) == ERROR) || - (hex2bin(&(hexBuf[5]), &(pdpvt->txMsg.data[1])) == ERROR)) - { - printf("Invalid characters in HEX record offset field. Line:\n%s", hexBuf); - status = ERROR; - break; - } - - /* find the number of bytes in the hex record */ - if (hex2bin(&(hexBuf[1]), &hexTotal) == ERROR) - { - printf("Invalid characters in HEX record count field. Line:\n%s", hexBuf); - status = ERROR; - break; - } - hexTotal += hexTotal; /* double since is printable format */ - hexBytes = 0; - msgBytes = 2; /* skip over the address field of the bitbus message */ - - while ((hexBytes < hexTotal) && (status == OK)) - { - while ((msgBytes < 13) && (hexBytes < hexTotal)) - { /* convert up to 1 message worth of data (or hit EOL) */ - hex2bin(&(hexBuf[hexBytes+9]), &(pdpvt->txMsg.data[msgBytes])); - msgBytes++; - hexBytes+=2; - } - if (msgBytes > 2) - { /* send the bitbus RAC command message */ - - /* length = hexBytes + header size of the bitbus message */ - pdpvt->txMsg.length = msgBytes+7; - - pdpvt->ageLimit = 0; /* need to reset each time */ - - if ((*(drvBitBus.qReq))(pdpvt, BB_Q_LOW) != ERROR) - { - FASTLOCK(&msgReply); /* wait for last message to finish */ - - *((unsigned short int *)(pdpvt->txMsg.data)) += msgBytes-2; /* ready for next message */ - - totalBytes += msgBytes-2; - totalMsg++; - msgBytes=2; - - if (pdpvt->rxMsg.cmd != 0) - { - printf("Bad message response status 0x%2.2X\n", pdpvt->rxMsg.cmd); - status = ERROR; - } - } - else - status = ERROR; - } - } - } - /* close the hex file */ - fclose(fp); - - printf("Total bytes down loaded to BUG = %u = 0x%4.4X\n", totalBytes, totalBytes); - printf("Total messages sent = %u = 0x%4.4X\n", totalMsg, totalMsg); - - bbDebug = oldDebug; - return(status); -} -/* - * This function translates a printable ascii string containing hex - * digits into a binary value. - */ -static int -hex2bin(pstr, pchar) -char *pstr; /* string containing the ascii bytes */ -unsigned char *pchar; /* where to return the binary value */ -{ - int ctr; - - ctr = 0; - *pchar = 0; - while(ctr < 2) - { - *pchar = (*pchar) << 4; - - if ((pstr[ctr] >= '0') && (pstr[ctr] <= '9')) - (*pchar) += (pstr[ctr] & 0x0f); /* is 0-9 value */ - else if ((pstr[ctr] >= 'A') && (pstr[ctr] <= 'F')) - (*pchar) += (pstr[ctr] - 'A' + 0x0a); /* is A-f value */ - else if ((pstr[ctr] >= 'a') && (pstr[ctr] <= 'f')) - (*pchar) += (pstr[ctr] - 'a' + 0x0a); /* is a-f value */ - else - return (ERROR); /* invalid character found in input string */ - ctr++; - } - - return(OK); -} - -/* - * getInt(pInt) **************************************************** - * - * gets a line of input from STDIN (10 characters MAX !!!!) scans the line - * for an integer. - * - * Parm1 : pointer to an integer - * - * Returns (0) if a was hit, *pInt left unchanged. Returns (1) if a new - * value was written to *pvalue. Returns (2) if a entry was not a valid - * integer entry - * - */ - -static int -getInt(pInt) -int *pInt; -{ - char input[10]; - int inval; - - gets(input); - - if (input[0] == 0) /* if only a */ - return (0); - else - { - if (sscanf(input, "%d", &inval) == 1) - { /* if a valid entry ... */ - *pInt = inval; - return (1); - } - else /* if not a valid entry, return 2 */ - return (2); - } -} - -/* - * int getChar(pChar) ************************************************** - * - * gets a line of input from STDIN (10 characters MAX !!!!) scans the line - * for a character entry - * - * Parm1 : pointer to an unsigned character variable - * - * Returns(0) if a was hit, *pChar left unchanged. Returns(1) if a new - * value was written to *pChar - * - */ - -static int -getChar(pChar) -unsigned char *pChar; -{ - char input[10]; - unsigned char inval; - - gets(input); - - if (input[0] == 0) - return (0); - else - { - sscanf(input, "%c", &inval); - *pChar = inval; - return (1); - } -} - -/* - * int getString(pString) **************************************************** - * - * gets a line of input from STDIN (100 characters MAX !!!!) . - * If length is greater than 0, copies string into pString - * - * Parm1 : pointer to an character string - * - * Returns : 0 if a was hit, *pvalue left unchanged Returns : 1 if a - * new value was written to *pvalue - * - */ - -static int -getString(pString) -char *pString; -{ - char input[100]; - - gets(input); - - if (input[0] == 0) - return (0); - else - { - strcpy(pString, input); - return (1); - } -} - -/* - * Print the bb message contents onto the screen. - * msgNum selects the message to be displayed - */ - -static int -showBbMsg(msg) -struct bitBusMsg *msg; -{ - int i; - - printf(" %p:link=%4.4X length=%2.2X route=%2.2X node=%2.2X tasks=%2.2X cmd=%2.2X\n", - msg, msg->link, msg->length, msg->route, msg->node, msg->tasks, msg->cmd); - printf(" data :"); - for (i = 0; i < msg->length - 7; i++) - { - printf(" %2.2X", msg->data[i]); - } - putchar('\n'); - return(0); -} diff --git a/src/drv/ansi/Makefile.Vx b/src/drv/ansi/Makefile.Vx index 8730b82e8..6a7cc4511 100644 --- a/src/drv/ansi/Makefile.Vx +++ b/src/drv/ansi/Makefile.Vx @@ -5,7 +5,6 @@ TOP = ../../../.. include $(TOP)/config/CONFIG_BASE -INC += drvAb.h INC += drvAt5Vxi.h INC += drvEpvxi.h INC += drvHp1404a.h @@ -15,7 +14,6 @@ INC += drvMz8310.h INC += drvStc.h INC += epvxi.h -SRCS.c += ../drvAb.c SRCS.c += ../drvAt5Vxi.c SRCS.c += ../drvEpvxi.c SRCS.c += ../drvEpvxiMsg.c diff --git a/src/drv/ansi/drvAb.c b/src/drv/ansi/drvAb.c deleted file mode 100644 index 52f11855f..000000000 --- a/src/drv/ansi/drvAb.c +++ /dev/null @@ -1,1891 +0,0 @@ -/* drvAb.c - Driver Support Routines for Allen Bradley */ -/* - * Interface to the Allen-Bradley Remote Serial IO - * - * Author: Bob Dalesio - * Date: 6-21-88 - * Major Revision March 1995. Bob Dalesio and Marty Kraimer - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Notes: - * 1. This driver uses Asynchronous Communications to the AB scanner - * The manual description for this type of interface is - * misleading in the area of interrupt handling. - * 2. We are using double slot addressing - * The database uses card numbers 0-11 to address slots 1-12 - * It is possible to use 1 slot and 1/2 slot addressing. - * For 1 slot addressing assign card=slot*2 - * For 1/2 slot addressing assign card = slot*4 - * 3. The binary io is memory mapped and the analog io is handled through - * block transfers of whole cards of data. - * 4. The driver spawns a task for each 6008 card in VME and scans cards as - * the database claims they exist - there is no way to poll the hardware - * to determine what is present. - * 4. A flag is used to limit the requests to the analog input modules. This - * assures that only one request is outstanding at any time. - * - * Modification Log: - * ----------------- - * .19 08-01-89 lrd changed sc_queue and bt_queue to always set - * length to 0 for compatibility with PLC-5 - * communication - * .26 10-17-89 cbf added logic to see if the scanner was using the - * dual port when we had it locked. it is! - * **************************************************************************** - * * Many of the above were needed to work around problems in the * - * * 6008-SV firmware. These problems have been reported to Allen- * - * * Bradley and fixes are promised. The PROMs we are presently using * - * * are both labeled "91332-501". U63 chksum = A7A1. U64 chksum = 912B * - * * (Series A, Revision C.) * - * **************************************************************************** - * .27 12-11-89 cbf new PROMs implemented which allow output image - * table to be preserved during SYSTEM RESET. - * This driver is still compatible with the old - * firmware also. - * A piece of code was added to store the firmware - * revision level in array ab_firmware_info. - * .28 12-11-89 cbf With the new firmware, the scanner no longer - * uses the dual port when we have it locked so - * the tests for this condition have been removed. - * .29 01-23-90 cbf In the previous rev of this driver we made an - * attempt to build a scan list automatically by - * waiting until the periodic scan task had asked - * for data from each needed adapter. - * This scheme caused problems with the - * the initialization of BOs and AOs, because they - * were not initially in the scan list and so - * could not be read at initialization. - * In this rev, that code has been removed and the - * scan list is always built to include all - * eight possible adapters. This has some - * performance implications because each - * non-existant adapter which appears in the scan - * list adds an extra 12 ms to each I/O scan time - * for the 6008SV. The decreased performance does - * not appear to be very significant, however. - * The 6008SV front panel "SER" LED blinks if not - * all adapters in the scan list are responding. - * With this rev of the driver, the light will - * therefore be blinking. - **************************************************************************** - ** Allen-Bradley has given us a new firmware revision. - ** This revision allows the reset of the scanner without using the - ** sysReset on the VME backplane. It also maintains the output image table - ** for the binary outputs. This reset is used to recover from a scanner - ** fault, where the 6008 firmware deadends - ab_reset provides this - ** function. * - ***************************************************************************** - * .41 05-16-91 lrd have the ab_scan_task driver analog outputs - * periodically as well as on change - * .56 06-30-93 mrk After 3 attempts to queue request reinitialize - * .64 09-16-93 mrk ab_reset: all links; only reset scanner. - * ???????????? ??? fix scaling on IXE 4-20 Milli amp - * .65 04-04-94 lrd return the value for overrange and underrange - * .66 04-04-94 lrd put the binary change of state into the AB scan task - * .67 04-04-94 lrd support N serial cards - * - put all link and adapter information into structure - * - allocate structures as needed - * .68 09-29-94 lrd removed historical comments of no current significance - * .69 10-20-94 lrd moved all I/O board specific stuff up to the device layer - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "errlog.h" -#include "task_params.h" -#include "dbScan.h" -#include "drvSup.h" -#include "taskwd.h" -#include "module_types.h" -#include "devLib.h" -#include "drvAb.h" - - - -#define maxCmdTrys 3 -#define AB_INT_LEVEL 5 -#define MAX_AB_ADAPTERS 8 -#define MAX_GROUPS_PER_ADAPTER 8 -#define MAX_CARDS_PER_ADAPTER 16 - -/*Definitions for dual ported memory on scanner interface card*/ -/* Command Word */ -#define AUTO_CONF 0x10 -#define SCAN_LIST 0x11 -#define SET_UP 0x13 -#define SET_MODE 0x20 -#define LINK_STATUS 0x21 -#define AB_READ 0x01 -#define AB_WRITE 0x02 -/* osw - operating status word definitions */ -#define PROGRAM_MODE 0x01 /* program/reset mode */ -#define TEST_MODE 0x02 /* test/reset mode */ -#define RUN_MODE 0x04 /* run mode */ -#define DEBUG_MODE 0x08 /* we are debugging */ -#define UNSOLICITED_BT 0x10 /* detected block xfer we didn't want */ -#define BTS_QUEUED 0x20 /* block xfers queued */ -#define ADAPTER_FAULT 0x40 /* at least one faulted adapter list */ -#define ADAP_FLT_CHNG 0x80 /* Adapter status change*/ -/* Confirmation Status Word */ -#define SCANNER_POWERUP 0x90 /* power up status */ -#define BT_ACCEPTED 0x2f /* block trans accepted by scanner */ -#define BT_QUEUE_FULL 0x14 /* Queue Full*/ -#define BT_TIMEOUT 0x23 /* block transfer timeout */ -/* these are used for the SET_UP command */ -#define DEF_RATE 0x01 /* default baud rate 57.6K */ -#define FAST_RATE 0x02 /* 115.2 KB */ -#define NO_CHANGE 0xff /* no change */ -#define DEBUG 0x01 /* debug - turn off watchdog timer */ -#define AB_INT_ENABLE 0x00 /* interrupt enabled */ -#define AB_SYSFAIL_DISABLE 0x01 /* disable VMEbus SYSFAIL signal */ - -/* DUAL PORTED MEMORY AREA DEFINITION */ -/* mail box definition */ -typedef volatile struct dp_mbox{ - unsigned short conf_stat; /* confirmation status word */ - unsigned short command; /* command word */ - unsigned short address; /* module address */ - unsigned short bt_tag; /* block transfer tag number */ - unsigned short resv[9]; /* 18 bytes reserved */ - unsigned char dummy; - unsigned char fl_lock; /* semaphore word byte */ - unsigned short data_len; /* length of data sent/returned */ - unsigned short msg[64]; /*mail box message */ -}dp_mbox; - -/* entire region with the mailbox */ -typedef volatile struct ab_region { - unsigned short oit[64]; /* output image table */ - unsigned short iit[64]; /* input image table */ - unsigned short osw; /* operating status word */ - dp_mbox mail; /* dual port mail box */ - unsigned short gda[1872-66]; /* unused part gen data area */ - unsigned short sys_fail_set1; /* 1st byte to recover from SYSFAIL */ - unsigned short sys_fail_set2; /* 2nd byte to recover from SYSFAIL */ - unsigned char vmeid[60]; /* scanner id */ - unsigned short sc_intr; /* to interrupt the scanner */ - unsigned short sc_pad; /* last word in scanner shared mem */ -}ab_region; - -typedef struct { - abStatus btStatus; - unsigned short cmd; - unsigned short msg_len; - unsigned short *pmsg; - /* The following field is only used for cardType = typeBt */ - WDOG_ID wdId; /*For Timeout */ -}btInfo; - -typedef enum { - stateInit,stateInitBTwait,stateCountdown,stateBT,stateBTwait -}scanState; -typedef struct { - scanState state; - unsigned short update_rate; - unsigned short *pread_msg; - unsigned short *pwrite_msg; - unsigned short read_msg_len; - unsigned short write_msg_len; - unsigned short state_cnt; /* number of consecutive time in state*/ - unsigned short down_cnt; /* down_counter for scanning */ - unsigned short bt_to; /* data transfer timed out */ - unsigned short bt_fail; /*block transfer bad status*/ - unsigned short init_ctr; /* number times the card initialized*/ -}scanInfo; - -typedef struct { - unsigned short link; - unsigned short adapter; - unsigned short card; - cardType type; - const char *card_name; - abNumBits nBits; - BOOL needsUpdate; - BOOL active; - abStatus status; - SEM_ID card_sem; - btInfo *pbtInfo; - scanInfo *pscanInfo; - void *userPvt; - void (*callback)(void *pcard); /*user's callback routine*/ - void (*bocallback)(void *pcard); /*user's callback routine*/ - unsigned long diprev; -}ab_card; - -typedef struct{ - unsigned short adapter; - BOOL adapter_online; - BOOL adapter_status_change; - ab_card **papcard; /*pointer to array of pointers*/ - SEM_ID adapter_sem; /* request talk to scanner*/ -}ab_adapter; - -typedef struct { - void *base_address; - unsigned short baud_rate; - unsigned short int_vector; - unsigned short int_level; - unsigned short autoconfig; - unsigned short scan_list_len; - unsigned char scan_list[64]; -} ab_config; - -typedef struct { - unsigned short list_len; - unsigned short status[32]; - unsigned char list[64]; -}ab_link_status; - -typedef struct{ - unsigned short link; - unsigned short ab_disable; - SEM_ID request_sem; /* request talk to scanner*/ - SEM_ID ab_cmd_sem; /* transfer complete semaphore */ - SEM_ID ab_data_sem; /* transfer complete semaphore */ - int abScanId; /* id of the Allen-Bradley scan task */ - int abDoneId; /* id of the Allen-Bradley done task */ - unsigned short sclock_to; /* Timeout trying to lock mailbox*/ - unsigned short sccmd_to; /* command timeout on semTake*/ - unsigned short sc_fail; /* Scanner Command Failure*/ - unsigned short intr_cnt; /* interrupt counter*/ - unsigned short intrSec; /* interrupts per second */ - unsigned short bt_cnt; /* Block Transfer counter*/ - unsigned short btSec; /* block transfers per second*/ - ab_config *pconfig; - char firmware_info[96]; /* NOTE: available only temporarily */ - ab_region *vme_addr; /* ptr to the memory of interface */ - ab_adapter **papadapter; - ab_link_status *plink_status; - BOOL initialCallback; - BOOL initialized; -}ab_link; - -/*Local variables and function prototypes*/ -LOCAL ab_link **pab_links=NULL; -LOCAL unsigned int max_ab_6008s = 2; - -/* forward references */ -LOCAL void *abCalloc(size_t nobj,size_t size); -LOCAL ab_link *allocLink(unsigned short link); -LOCAL void ab_intr(int link); -LOCAL int sc_lock(ab_link *plink); -LOCAL int sc_waitcmd(ab_link *plink); -LOCAL void sc_conferr(ab_link *plink); -LOCAL void sc_unlock(ab_link *plink); -LOCAL void uctrans (unsigned char *from,unsigned char *to,unsigned short n); -LOCAL void ustrans (unsigned short *from,unsigned short *to, - unsigned short nwords); -LOCAL void di_read(ab_card *pcard,unsigned long *pvalue); -LOCAL void do_read(ab_card *pcard,unsigned long *pvalue); -LOCAL void do_write(ab_card *pcard,unsigned long value); -LOCAL abStatus bt_queue(unsigned short command,ab_card *pcard, - unsigned short *pmsg, unsigned short msg_len); -LOCAL int link_status(ab_link *plink); -LOCAL int ab_reboot_hook(int boot_type); -LOCAL void config_init(ab_link *plink); -LOCAL int ab_driver_init(); -LOCAL int link_init(ab_link *plink); -LOCAL void abScanTask(ab_link *plink); -LOCAL void abDoneTask(ab_link *plink); -LOCAL void read_ab_adapter(ab_link *plink, ab_adapter *padapter); -LOCAL void ab_reset_task(ab_link *plink); -LOCAL long ab_io_report(int level); - -/*Global variables */ -unsigned int ab_debug=0; - -LOCAL char *statusMessage[] = { - "Success","New Card","Card Conflict","No Card", - "Card not initialized","block transfer queued", - "Card Busy","Timeout","Adapter Down","Failure"}; -char **abStatusMessage = statusMessage; - -LOCAL char *numBitsMessage[] = { - "nbits_Not_defined"," 8_Bit","16_Bit","32_Bit"}; -char **abNumBitsMessage = numBitsMessage; -/*End Global variables*/ - -/*Beginning of DSET routines */ - -LOCAL long report(); -LOCAL long init(); -struct { - long number; - DRVSUPFUN report; - DRVSUPFUN init; -} drvAb={ - 2, - report, - init -}; - -LOCAL long report(int level) -{ - return(ab_io_report(level)); -} -LOCAL long init() -{ - - return(ab_driver_init()); -} - -LOCAL void *abCalloc(size_t nobj,size_t size) -{ - void *p; - - p=calloc(nobj,size); - if(p) return(p); - logMsg("drvAb: calloc failure\n",0,0,0,0,0,0); - taskSuspend(0); - return(NULL); -} -LOCAL ab_link *allocLink(unsigned short link) -{ - ab_link *plink; - - if(pab_links[link]) return(pab_links[link]); - plink = abCalloc(1,sizeof(ab_link)); - plink->ab_disable = TRUE; - plink->papadapter = abCalloc(MAX_AB_ADAPTERS,sizeof(ab_adapter *)); - plink->plink_status = abCalloc(1,sizeof(ab_link_status)); - plink->link = link; - config_init(plink); - pab_links[link] = plink; - return(plink); -} - -/* - * AB_INTR - * - * The Allen-Bradley protocol requires that an interrupt be received when - * a block transfer request is given to the scanner board through the dual - * ported memory and then another when the command is complete. - * dual-ported memory lock is controlled in a much different fashion than it is. - */ -LOCAL void ab_intr(int link) -{ - ab_link *plink; - ab_region *p6008; - dp_mbox *pmb; - - if(!pab_links) return; /*Called before init complete*/ - plink = pab_links[link]; - if(!plink) return; /*Called before init complete*/ - p6008 = plink->vme_addr; - if(!p6008) return; - pmb = &p6008->mail; - if((pmb->fl_lock&0x80)==0) {/*Should NEVER be True*/ - if (ab_debug != 0) - logMsg("drvAb: Interrupt but fl_lock not locked\n", 0,0,0,0,0,0); - } - if(p6008->osw & UNSOLICITED_BT){ - if (ab_debug != 0) - logMsg("link %x, unsolicited_block xfer\n",plink->link,0,0,0,0,0); - /* scanner depends on us to clear some bits */ - p6008->osw = 0; - } - plink->intr_cnt++; - if((pmb->command==AB_WRITE || pmb->command==AB_READ) - && (pmb->conf_stat != BT_ACCEPTED) && (pmb->conf_stat != BT_QUEUE_FULL)) { - semGive(plink->ab_data_sem); - } else { - semGive(plink->ab_cmd_sem); - } -} - -/*Routines for communication with scanner*/ -LOCAL int sc_lock(ab_link *plink) -{ - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - unsigned short lock_stat = 0; - int i; - - if(ab_debug>3)printf("sc_lock\n"); - semTake(plink->request_sem,WAIT_FOREVER); - /* try to to lock the dual port memory */ - for(i=0; ifl_lock)) == TRUE) break; - taskDelay(1); - } - if(lock_stat == FALSE) { - if(ab_debug) - printf("drvAb: link %x sc_lock failure\n", plink->link); - plink->sclock_to += 1; - pmb->fl_lock = 0; /*Unlock to attempt to recover. May not work*/ - semGive(plink->request_sem); - return (ERROR); - } - return(0); -} - -LOCAL int sc_waitcmd(ab_link *plink) -{ - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - unsigned short savecmd; - int status; - int ntry; - - if(ab_debug>3)printf("sc_waitcmd\n"); - savecmd = pmb->command; - pmb->conf_stat = 0x000f; - ntry = 0; - p6008->sc_intr = 1; /*Wake up scanner*/ - status = semTake(plink->ab_cmd_sem,sysClkRateGet()); - if(status!=OK) { - plink->sccmd_to++; - if(ab_debug) printf( - "drvAb: sc_waitcmd timeout link %hu command %4x\n", - plink->link,savecmd); - sc_unlock(plink); - return(ERROR); - } - if(pmb->command != savecmd){ - plink->sc_fail++; - if(ab_debug) printf( - "drvAb: bad cmd response. link %hu sent %4x received %4x\n", - plink->link,savecmd,pmb->command); - sc_unlock(plink); - return(ERROR); - } - return(0); -} - -LOCAL void sc_conferr(ab_link *plink) -{ - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - - if(ab_debug>3)printf("sc_conferr\n"); - plink->sc_fail++; - if(ab_debug) printf("drvAb: link %hu conf_stat error %4x\n", - plink->link,pmb->conf_stat); - sc_unlock(plink); - return; -} - -LOCAL void sc_unlock(ab_link *plink) -{ - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - - if(ab_debug>3)printf("sc_unlock\n"); - pmb->fl_lock = 0; - semGive(plink->request_sem); -} - -/*Routines to transfer data to/from mailbox*/ -/* Unsigned character transfer*/ -LOCAL void uctrans (unsigned char *from,unsigned char *to,unsigned short n) -{ - int i; - for (i=0;ilink; - unsigned short adapter = pcard->adapter; - unsigned short card = pcard->card; - unsigned short group,slot; - unsigned short rack_offset; - unsigned short *pimage; - unsigned long value; - - rack_offset = (adapter * MAX_GROUPS_PER_ADAPTER); - group = card/2; slot = card - group*2; - pimage = &(pab_links[link]->vme_addr->iit[rack_offset + group]); - if (pcard->nBits == abBit8) { - value = *pimage; - if(slot==1) value >>= 8; - value &= 0x00ff; - *pvalue = value; - }else if(pcard->nBits == abBit16){ - *pvalue = *pimage; - } else if (pcard->nBits == abBit32) { - value = *(pimage+1); - value <<= 16; - value += *pimage; - *pvalue = value; - } -} - -/* read the values from the hardware into the local word */ -LOCAL void do_read(ab_card *pcard,unsigned long *pvalue) -{ - unsigned short link = pcard->link; - unsigned short adapter = pcard->adapter; - unsigned short card = pcard->card; - unsigned short group,slot; - unsigned short rack_offset; - unsigned short *pimage; - unsigned long value; - - rack_offset = (adapter * MAX_GROUPS_PER_ADAPTER); - group = card/2; slot = card - group*2; - pimage = &(pab_links[link]->vme_addr->oit[rack_offset + group]); - if (pcard->nBits == abBit8) { - value = *pimage; - if(slot==1) value >>= 8; - value &= 0x00ff; - *pvalue = value; - }else if(pcard->nBits == abBit16){ - *pvalue = *pimage; - } else if (pcard->nBits == abBit32) { - value = *(pimage+1); - value <<= 16; - value += *pimage; - *pvalue = value; - } -} - -/* write the values to the hardware from the local word */ -LOCAL void do_write(ab_card *pcard,unsigned long value) -{ - unsigned short link = pcard->link; - unsigned short adapter = pcard->adapter; - unsigned short card = pcard->card; - unsigned short group,slot; - unsigned short rack_offset; - unsigned short *pimage; - - rack_offset = (adapter * MAX_GROUPS_PER_ADAPTER); - group = card/2; slot = card - group*2; - pimage = &(pab_links[link]->vme_addr->oit[rack_offset + group]); - if (pcard->nBits == abBit8) { - if(slot==0) { - *pimage = (*pimage & 0xff00) | ((unsigned short)value & 0x00ff); - } else { - value <<= 8; - *pimage = (*pimage & 0x00ff) | ((unsigned short)value & 0xff00); - } - }else if(pcard->nBits == abBit16){ - *pimage = (unsigned short)value; - } else if (pcard->nBits == abBit32) { - *pimage = (unsigned short)value; - *(pimage+1) = (unsigned short)(value >> 16); - } -} - -LOCAL abStatus bt_queue(unsigned short command,ab_card *pcard, - unsigned short *pmsg, unsigned short msg_len) -{ - ab_link *plink = pab_links[pcard->link]; - ab_adapter *padapter = plink->papadapter[pcard->adapter]; - btInfo *pbtInfo = pcard->pbtInfo; - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - unsigned short *pmb_msg = &pmb->msg[0]; - int status; - - if(!padapter->adapter_online) return(abAdapterDown); - pbtInfo->cmd = command; - pbtInfo->pmsg = pmsg; - pbtInfo->msg_len = msg_len; - status = sc_lock(plink); - if(status) return(abFailure); - pmb->command = command; - pmb->address = (padapter->adapter << 4) + pcard->card; - pmb->data_len = msg_len; - if(pbtInfo->cmd==AB_WRITE) ustrans(pmsg,pmb_msg,msg_len); - status = sc_waitcmd(plink); - if(status) return(abFailure); - status = pmb->conf_stat; - if(status != BT_ACCEPTED){ - sc_conferr(plink); - if (status == BT_QUEUE_FULL){ - printf("drvAb: BT_QUEUE_FULL link %hu\n",plink->link); - taskDelay(sysClkRateGet()/10); - } - return(abFailure); - } - pbtInfo->btStatus = abBtqueued; - sc_unlock(plink); - return(abBtqueued); -} - -/* - * LINK_STATUS - * - * Fetches the status of the adapters on the specified link - * The ab_adapter_status table is used to determine hardware communication - * errors and convey them to the database - */ -LOCAL int link_status(ab_link *plink) -{ - short i; - ab_adapter *padapter; - dp_mbox *pmb; - ab_link_status *plink_status = plink->plink_status; - int status; - int ntry; - int linkOK = TRUE; - - /* initialize the pointer to the dual ported memory */ - pmb = (dp_mbox *)(&plink->vme_addr->mail); - /* get the link status */ - for(ntry=0; ntrycommand = LINK_STATUS; - pmb->data_len = 0; - status = sc_waitcmd(plink); - if(status) continue; - if(pmb->conf_stat != 0) { - sc_conferr(plink); - continue; - } - plink_status->list_len = pmb->data_len; - ustrans(pmb->msg,plink_status->status,32); - uctrans((unsigned char *)(pmb->msg+32),plink_status->list,64); - sc_unlock(plink); - break; - } - if(ntry>=maxCmdTrys) { - if(ab_debug)printf("abDrv: link_status failed link %hu\n",plink->link); - linkOK = FALSE; - } - /* check each adapter on this link */ - for (i = 0; i< AB_MAX_ADAPTERS; i++){ - padapter = plink->papadapter[i]; - - if(!padapter) continue; - /* good status */ - if (linkOK && plink_status->status[i*4] & 0x70){ - if (!padapter->adapter_online) { - printf("link %d adapter %d change bad to good\n", - plink->link,i); - padapter->adapter_status_change=TRUE; - } - padapter->adapter_online = TRUE; - }else { /* bad status */ - if (padapter->adapter_online){ - printf("link %d adapter %d change good to bad\n", - plink->link,i); - padapter->adapter_status_change=TRUE; - } - padapter->adapter_online = FALSE; - } - } - return(0); -} - -/* ab_reboot_hook - routine to call when IOC is rebooted with a control-x */ -LOCAL int ab_reboot_hook(int boot_type) -{ - short i; - ab_link *plink; - - /* Stop communication to the Allen-Bradley Scanner Cards */ - /* delete the scan task stops analog input communication */ - for (i=0; iab_disable = 1; - taskDelete(pab_links[i]->abScanId); - } - } - /* this seems to be necessary for the AB card to stop talking */ - printf("\nReboot: drvAb delay to clear interrupts off backplane\n"); - taskDelay(sysClkRateGet()*2); - return(0); -} - - -LOCAL void config_init(ab_link *plink) -{ - ab_config *pconfig = plink->pconfig; - int i; - ab_region *p6008; - - if(!pconfig) plink->pconfig = pconfig = abCalloc(1,sizeof(ab_config)); - p6008 = (ab_region *)AB_BASE_ADDR; - p6008 += plink->link; - pconfig->base_address = (void *)p6008; - pconfig->baud_rate = DEF_RATE; - pconfig->autoconfig = FALSE; - pconfig->int_vector = AB_VEC_BASE + plink->link; - pconfig->int_level = AB_INT_LEVEL; - pconfig->scan_list_len = 8; - for(i=0; i< AB_MAX_ADAPTERS; i++) pconfig->scan_list[i] = (i<<2); -} - -int abConfigNlinks(int nlinks) -{ - if(pab_links) { - printf("abConfigNlinks Illegal call. Must be first abDrv related call\n"); - return(-1); - } - max_ab_6008s = nlinks; - pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - return(0); -} - -int abConfigVme(int link, int base, int vector, int level) -{ - ab_link *plink; - ab_config *pconfig; - - if(link<0 || link>=max_ab_6008s) return(-1); - if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - plink = pab_links[link]; - if(!plink) plink = allocLink(link); - pconfig = plink->pconfig; - pconfig->base_address = (void *)base; - pconfig->int_vector = vector; - pconfig->int_level = level; - return(0); -} - -int abConfigBaud(int link, int baud) -{ - ab_link *plink; - ab_config *pconfig; - - if(link<0 || link>=max_ab_6008s) return(-1); - if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - plink = pab_links[link]; - if(!plink) plink = allocLink(link); - pconfig = plink->pconfig; - if(baud = 0) pconfig->baud_rate = DEF_RATE; - else pconfig->baud_rate = FAST_RATE; - return(0); -} - -int abConfigAuto(int link) -{ - ab_link *plink; - ab_config *pconfig; - - if(link<0 || link>=max_ab_6008s) return(-1); - if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - plink = pab_links[link]; - if(!plink) plink = allocLink(link); - pconfig = plink->pconfig; - pconfig->autoconfig = TRUE; - return(0); -} - -int abConfigScanList(int link, int scan_list_len, char *scan_list) -{ - ab_link *plink; - ab_config *pconfig; - - if(link<0 || link>=max_ab_6008s) return(-1); - if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - plink = pab_links[link]; - if(!plink) plink = allocLink(link); - pconfig = plink->pconfig; - pconfig->scan_list_len = scan_list_len; - memset(pconfig->scan_list,'\0',64); - memcpy(pconfig->scan_list,scan_list,scan_list_len); - return(0); -} - -int abConfigScanListAscii(int link, char *filename,int setRackSize) -{ - FILE *fp; - char *scan_list; - char buf[80]; - unsigned rack,group,size; - int nItemsRead,nCharsRead,scan_list_len; - - scan_list = abCalloc(64,sizeof(char)); - fp = fopen(filename,"r"); - scan_list_len = 0; - while(fgets(buf,80,fp)) { - if(buf[0] == '#') continue; - nItemsRead = sscanf(buf,"%u %u %n",&rack,&group,&nCharsRead); - if(nItemsRead!=2) { - printf("abConfigScanListAscii: Illegal line %d %s\n", - scan_list_len,buf); - fclose(fp); - return(0); - } - if(!setRackSize) { - size = 0x00; - } else if(strstr(&buf[nCharsRead],"1/4")) { - size = 0x00; - } else if(strstr(&buf[nCharsRead],"1/2")) { - size = 0x40; - } else if(strstr(&buf[nCharsRead],"3/4")) { - size = 0x80; - } else if(strstr(&buf[nCharsRead],"Full")) { - size = 0xc0; - } else { - printf("abConfigScanListAscii: Illegal line %d %s\n", - scan_list_len,buf); - fclose(fp); - return(0); - } - scan_list[scan_list_len] = size | (rack<<2) | group; - scan_list_len++; - } - fclose(fp); - return(abConfigScanList(link,scan_list_len,scan_list)); -} - -LOCAL int ab_driver_init() -{ - unsigned short cok; - unsigned short link; - ab_link *plink; - ab_region *p6008; - ab_config *pconfig; - int vxstatus; - long status; - int got_one; - char task_name[50]; - - if(!pab_links) pab_links = abCalloc(max_ab_6008s,sizeof(ab_link *)); - /* check if any of the cards are there */ - got_one = 0; - for (link = 0; link < max_ab_6008s; link++,p6008++){ - plink = pab_links[link]; - if(plink) { - p6008 = plink->pconfig->base_address; - } else { - p6008 = (void *)AB_BASE_ADDR; - p6008 += link; - } - status = devRegisterAddress("drvAb",atVMEA24,(void *)p6008, - sizeof(ab_region),(void **)&p6008); - if(status) { - errMessage(status,"drvAb"); - return(status); - } - if (vxMemProbe((char *)p6008,READ,1,(char *)&cok)==ERROR) { - continue; - } - got_one = 1; - if(!plink) plink = allocLink(link); - plink->vme_addr = p6008; /* set AB card address */ - pconfig = plink->pconfig; - if(!(plink->request_sem = semBCreate(SEM_Q_FIFO,SEM_EMPTY))){ - printf("AB_DRIVER_INIT: semBcreate failed\n"); - taskSuspend(0); - } - if(!(plink->ab_cmd_sem = semBCreate(SEM_Q_FIFO,SEM_EMPTY))){ - printf("AB_DRIVER_INIT: semBcreate failed\n"); - taskSuspend(0); - } - if(!(plink->ab_data_sem = semBCreate(SEM_Q_FIFO,SEM_EMPTY))){ - printf("AB_DRIVER_INIT: semBcreate failed\n"); - taskSuspend(0); - } - status = devConnectInterrupt(intVME,pconfig->int_vector, - ab_intr,(void *)(int)link); - if(status) { - errMessage(status,"drvAb"); - return(status); - } - status = devEnableInterruptLevel(intVME,pconfig->int_level); - if(status) { - errMessage(status,"drvAb"); - taskSuspend(0); - } - /* initialize the serial link */ - if(link_init(plink)) { - /*No use proceeding*/ - continue; - } - plink->initialized = TRUE; - sprintf(task_name,"%s%2.2d",ABSCAN_NAME,link); - vxstatus = taskSpawn(task_name,ABSCAN_PRI,ABSCAN_OPT, - ABSCAN_STACK,(FUNCPTR)abScanTask,(int)plink, - 0,0,0,0,0,0,0,0,0); - if(vxstatus < 0){ - printf("AB_DRIVER_INIT: failed taskSpawn\n"); - taskSuspend(0); - } - plink->abScanId = vxstatus; - taskwdInsert(plink->abScanId,NULL,NULL); - sprintf(task_name,"%s%2.2d",ABDONE_NAME,link); - vxstatus = taskSpawn(task_name,ABDONE_PRI,ABDONE_OPT, - ABDONE_STACK,(FUNCPTR)abDoneTask,(int)plink, - 0,0,0,0,0,0,0,0,0); - if(vxstatus < 0){ - printf("AB_DRIVER_INIT: failed taskSpawn\n"); - taskSuspend(0); - } - plink->abDoneId = vxstatus; - taskwdInsert(plink->abDoneId,NULL,NULL); - plink->ab_disable = FALSE; - } - /* put in hook for disabling communication for a reboot */ - if (got_one) rebootHookAdd(ab_reboot_hook); - return(0); -} - -/* - * link_init - * - * establish the communication link with the AB scanner - */ -LOCAL int link_init(ab_link *plink) -{ - ab_region *p6008 = plink->vme_addr; - dp_mbox *pmb = &p6008->mail; - ab_config *pconfig=plink->pconfig; - int status; - int ntry; - - /* the scanner comes up with the dual ported memory locked */ - pmb->fl_lock = 0; /* so unlock it */ - /*clear request semaphore*/ - semGive(plink->request_sem); - if(pmb->conf_stat != SCANNER_POWERUP){ - /* This link must already be initialized. We're done */ - if (ab_debug){ - printf("Link %x already initialized\n", plink->link); - } - return(0); - } - if(ab_debug) printf("drvAb: link %x, powerup...\n",plink->link); - /* on initialization the scanner puts its firmware revision info*/ - /* into the general data are of the dual-port. We save it here. */ - /* (The most current revision is Series A, Revision D.) */ - strcpy(plink->firmware_info,(char *)&pmb->msg[0]); - /* setup scanner */ - /* Wake up scanner for the first time*/ - p6008->sc_intr = 1; /*Wake up scanner*/ - taskDelay(1); /*Give it time to initialize*/ - for(ntry=0; ntrycommand = SET_UP; - pmb->data_len = 4; - pmb->msg[0] = (pconfig->baud_rate<<8) | 0; - pmb->msg[1] = (DEBUG<<8) | pconfig->int_level; - pmb->msg[2] = (pconfig->int_vector<<8) | AB_INT_ENABLE; - pmb->msg[3] = (AB_SYSFAIL_DISABLE<<8) | 0; - status = sc_waitcmd(plink); - if(status) continue; - if(pmb->conf_stat != 0) { - sc_conferr(plink); - continue; - } - break; - } - if(ntry>=maxCmdTrys) { - printf("abDrv: SET_UP failed link %hu\n",plink->link); - return(ERROR); - } - sc_unlock(plink); - /* Once scanner has been placed in RUN_MODE, putting it back into - * PROGRAM_MODE will disable binary outputs until it is placed back in - * RUN_MODE. Some scanner commands, such as SCAN_LIST, can only be - * performed in PROGRAM_MODE. These commands should only be issued* - * immediately after initialization. - * Re-booting an IOC (without powering it down) is the presently - * the only way of getting it into PROGRAM_MODE - * without disabling binary outputs */ - - /* initialize scan list for each link present */ - /* A promised firmware change will allow us to RESET - the scanner over the vmeBus. For now, the only way - to get the scanner into prog-mode without having - the BO's glitch is with the vmeBus SYSRESET signal, - which occurs when the RESET switch on the VME chassis - is used. Until the f/w change is made, changing the - scanner from run mode to program mode (to modify the - scan list, for instance) will cause the BO's to turn - off until the scanner is returned to run mode. It's - not nice, but for now we'll have to assume that all - adapters are needed and put them all in the scan list. */ - /* set scan list*/ - if(pconfig->autoconfig) for(ntry=0; ntrycommand = AUTO_CONF; - pmb->data_len = 0; - status = sc_waitcmd(plink); - if(status) continue; - if(pmb->conf_stat != 0) { - sc_conferr(plink); - continue; - } - break; - }else for(ntry=0; ntrycommand = SCAN_LIST; - pmb->data_len = pconfig->scan_list_len; - uctrans(pconfig->scan_list,(unsigned char *)pmb->msg, - pconfig->scan_list_len); - status = sc_waitcmd(plink); - if(status) continue; - if(pmb->conf_stat != 0) { - sc_conferr(plink); - continue; - } - break; - } - if(ntry>=maxCmdTrys) { - printf("abDrv: AUTO_CONFIG or SCAN_LIST failed link %hu\n",plink->link); - return(ERROR); - } - sc_unlock(plink); - /* place the scanner into run mode */ - for(ntry=0; ntrycommand = SET_MODE; - pmb->msg[0] = (RUN_MODE<<8); - status = sc_waitcmd(plink); - if(status) continue; - if(pmb->conf_stat != 0) { - sc_conferr(plink); - continue; - } - break; - } - if(ntry>=maxCmdTrys) { - printf("abDrv: SET_MODE failed link %hu\n",plink->link); - return(ERROR); - } - sc_unlock(plink); - return(0); -} - -/* - * abScanTask - * - * Scans the AB IO according to the AB configuration table. - * Entries are made in the AB configuration table when an IO - * interface is attempted from the database scan tasks. - * The sleep time assures that there is at least 1/10 second between the passes. - * The time through the scan loop seems to be minimal so there are no provisions - * for excluding the scan time from the sleep time. - */ -LOCAL void abScanTask(ab_link *plink) -{ - unsigned short adapter; - ab_adapter *padapter; - unsigned int pass = 0; - BOOL madeInitialCallback = FALSE; - unsigned long tickNow,tickBeg,tickDiff; - - tickBeg = tickGet(); - while(TRUE){ - /* run every 1/10 second */ - taskDelay(sysClkRateGet()/10); - if(plink->ab_disable) continue; - /* Every second perform a link check to see if any adapters */ - /* have changed state. (Don't want to queue up requests if*/ - /* they're off) */ - if((pass % 10) == 0){ - if (link_status(plink) != 0){ - if(ab_debug) printf("%x link_stat error\n",plink->link); - } - } - if(!madeInitialCallback && interruptAccept) - plink->initialCallback = TRUE; - pass++; - /*recompute intrSec and btSec about every 10 seconds*/ - if((pass %100) == 0) { - tickNow = tickGet(); - if(tickNow > tickBeg){/*skip overflows*/ - tickDiff = tickNow - tickBeg; - /*round to nearest counts/sec */ - plink->intrSec=((plink->intr_cnt*sysClkRateGet())+5)/tickDiff; - plink->btSec=((plink->bt_cnt*sysClkRateGet())+5)/tickDiff; - } - tickBeg = tickNow; - plink->intr_cnt = 0; - plink->bt_cnt = 0; - } - for (adapter = 0; adapter < AB_MAX_ADAPTERS; adapter++){ - padapter = plink->papadapter[adapter]; - if(!padapter) continue; - read_ab_adapter(plink,padapter); - padapter->adapter_status_change = FALSE; - } - if(plink->initialCallback) { - plink->initialCallback = FALSE; - madeInitialCallback = TRUE; - } - } -} - -LOCAL void read_ab_adapter(ab_link *plink, ab_adapter *padapter) -{ - unsigned short card; - unsigned long value; - ab_card *pcard; - scanInfo *pscanInfo; - btInfo *pbtInfo; - abStatus btStatus=0; - - /* each card */ - for (card = 0; card < AB_MAX_CARDS; card++){ - pcard = padapter->papcard[card]; - if (!pcard) continue; - if(!pcard->active) continue; - if(pcard->type==typeBt) { - pbtInfo = pcard->pbtInfo; - semTake(pcard->card_sem,WAIT_FOREVER); - if(pcard->active && pbtInfo->btStatus != abBtqueued) { - pcard->active = FALSE; - pcard->status = pbtInfo->btStatus; - if(pcard->callback) (*pcard->callback) ((void *)pcard); - } - semGive(pcard->card_sem); - continue; - } - if(pcard->type==typeBi || pcard->type==typeBo || pcard->type==typeBiBo){ - if(pcard->type==typeBi || pcard->type==typeBiBo) { - di_read(pcard,&value); - if ((value != pcard->diprev)||padapter->adapter_status_change){ - pcard->diprev = value; - if(pcard->callback) (*pcard->callback)((void *)pcard); - } - } - if(pcard->type==typeBo || pcard->type==typeBiBo) { - if(padapter->adapter_status_change) { - if(pcard->bocallback) (*pcard->bocallback)((void *)pcard); - } - } - if(plink->initialCallback) { - if(pcard->callback) (*pcard->callback)((void *)pcard); - if(pcard->bocallback) (*pcard->bocallback)((void *)pcard); - } - continue; - } - /*If we get here card is typeAi or typeAo*/ - pscanInfo = pcard->pscanInfo; - if(!pscanInfo) continue; - pbtInfo = pcard->pbtInfo; - if(!pbtInfo) continue; - if(padapter->adapter_status_change){ - if(!padapter->adapter_online) { - pcard->status = abNotInitialized; - if(pcard->callback) (*pcard->callback)((void *)pcard); - continue; - } - pscanInfo->state = stateInit; - } - if(!padapter->adapter_online) continue; - switch(pscanInfo->state) { - case stateInit: - if(pcard->status !=abNotInitialized) { - pcard->status = abNotInitialized; - if(pcard->callback) (*pcard->callback)((void *)pcard); - } - if(pcard->type==typeAo) { - btStatus = bt_queue(AB_READ,pcard,pscanInfo->pread_msg, - pscanInfo->read_msg_len); - }else { - btStatus = bt_queue(AB_WRITE,pcard,pscanInfo->pwrite_msg, - pscanInfo->write_msg_len); - } - if(btStatus==abBtqueued) { - pscanInfo->state_cnt = 0; - pscanInfo->state = stateInitBTwait; - pscanInfo->init_ctr++; - } else { - pscanInfo->bt_fail++; - pscanInfo->state_cnt++; - } - break; - case stateInitBTwait: - if(pbtInfo->btStatus==abBtqueued) { - pscanInfo->state_cnt++; - if(pscanInfo->state_cnt < 15) break; - } - if(pbtInfo->btStatus!=abSuccess) { - if(btStatus==abTimeout) pscanInfo->bt_to++; - else pscanInfo->bt_fail++; - pscanInfo->state_cnt = 0; - pscanInfo->state = stateInit; - break; - } - pscanInfo->state_cnt = 0; - pscanInfo->state = stateBT; - if(pcard->type==typeAi) { - pcard->needsUpdate = TRUE; - } else { - /*Give device support time to set output words*/ - pscanInfo->down_cnt = pscanInfo->update_rate; - } - /*break left out on purpose*/ -repeat_countdown: - case stateCountdown: - if(pcard->needsUpdate) { - pscanInfo->down_cnt = 0; - pcard->needsUpdate = FALSE; - } - if(pscanInfo->down_cnt>0) pscanInfo->down_cnt--; - if(pscanInfo->down_cnt>0) continue; - pscanInfo->state_cnt = 0; - pscanInfo->state = stateBT; - /*break left out on purpose*/ - case stateBT: - if(pcard->type==typeAi) { - btStatus = bt_queue(AB_READ,pcard,pscanInfo->pread_msg, - pscanInfo->read_msg_len); - }else { - btStatus = bt_queue(AB_WRITE,pcard,pscanInfo->pwrite_msg, - pscanInfo->write_msg_len); - } - if(btStatus!=abBtqueued) { - pscanInfo->state_cnt++; - /*After 15 trys reinitialize*/ - if(pscanInfo->state_cnt > 15) { - pcard->status = abFailure; - pscanInfo->bt_fail++; - pscanInfo->state_cnt = 0; - pscanInfo->state = stateInit; - } - break; - } - pscanInfo->state_cnt = 0; - pscanInfo->state = stateBTwait; - break; - case stateBTwait: - if(pbtInfo->btStatus==abBtqueued) { - pscanInfo->state_cnt++; - if(pscanInfo->state_cnt < 30) break; - } - if(pbtInfo->btStatus!=abSuccess) { - pcard->status = abFailure; - if(btStatus==abTimeout) pscanInfo->bt_to++; - else pscanInfo->bt_fail++; - pscanInfo->state_cnt = 0; - pscanInfo->state = stateInit; - break; - } - pcard->status = abSuccess; - pscanInfo->state_cnt = 0; - pscanInfo->down_cnt = pscanInfo->update_rate; - pscanInfo->state = stateCountdown; - if(pcard->callback) (*pcard->callback)((void *)pcard); - goto repeat_countdown; - } - } -} - -LOCAL void abDoneTask(ab_link *plink) -{ - unsigned short adapter; - unsigned short card; - ab_adapter *padapter; /* adapter data structure */ - ab_card *pcard; /* card data structure */ - btInfo *pbtInfo; - dp_mbox *pmb = &plink->vme_addr->mail; - unsigned short *pmb_msg = &pmb->msg[0]; - - while(TRUE) { - semTake(plink->ab_data_sem,WAIT_FOREVER); - /* Must check all data returned by hardware interface*/ - card = pmb->address & 0x0f; - adapter = (pmb->address & 0x70) >> 4; - if(card >= MAX_CARDS_PER_ADAPTER || adapter>=MAX_AB_ADAPTERS) { - if(ab_debug) - printf("drvAb: scanner returned bad address %4x\n", - pmb->address); - pmb->fl_lock = 0; - continue; - } - padapter = plink->papadapter[adapter]; - if(!padapter) { - if(ab_debug) - printf("abDrv:abDoneTask padapter=NULL adapter=%d\n", - adapter); - pmb->fl_lock = 0; - continue; - } - pcard = padapter->papcard[card]; - if(!pcard) { - if(ab_debug) - printf("abDrv: abDoneTask pcard=NULL card=%d adapter=%d\n", - card,adapter); - pmb->fl_lock = 0; - continue; - } - plink->bt_cnt++; - pbtInfo = pcard->pbtInfo; - /* block transfer failure */ - if (pmb->conf_stat != 0){ - if (pmb->conf_stat == BT_TIMEOUT) { - pbtInfo->btStatus = abTimeout; - }else{ - pbtInfo->btStatus = abFailure; - } - }else{ - /* successful */ - pbtInfo->btStatus = abSuccess; - /* was it the response to a read command */ - if (pbtInfo->cmd == AB_READ){ - ustrans(pmb_msg,pbtInfo->pmsg,pbtInfo->msg_len); - } - } - pmb->fl_lock = 0; - if(pcard->type==typeBt) { - semTake(pcard->card_sem,WAIT_FOREVER); - if(pcard->active) { - pcard->active = FALSE; - wdCancel(pbtInfo->wdId); - pcard->status = pbtInfo->btStatus; - if(pcard->callback) (*pcard->callback) ((void *)pcard); - } - semGive(pcard->card_sem); - } - } -} - -LOCAL void ab_reset_task(ab_link *plink) -{ - unsigned short link,adapter,card,ab_reset_wait; - ab_adapter *padapter; - ab_region *pab_region=0; - ab_card *pcard; - btInfo *pbtInfo; - - link = plink->link; - pab_region = plink->vme_addr; - plink->ab_disable = 1; - printf("Disabled AB Scanner Task\n"); - taskDelay(sysClkRateGet()*2); - /* Signal the Scanner to Reset */ - pab_region->sys_fail_set2 = 0xa0a0; - pab_region->sys_fail_set1 = 0x0080; - printf("Card %d Reset\n",link); - /*mark all block transfer cards for initialization*/ - for(adapter = 0; adapter < AB_MAX_ADAPTERS; adapter++){ - padapter = plink->papadapter[adapter]; - if(!padapter) continue; - for (card = 0; card < AB_MAX_CARDS; card++){ - pcard = padapter->papcard[card]; - if(!pcard) continue; - pbtInfo = pcard->pbtInfo; - if(pcard->type==typeAo || pcard->type==typeAi) - pcard->needsUpdate = TRUE; - } - } - ab_reset_wait = 0; - while((pab_region->mail.conf_stat != SCANNER_POWERUP) - && (ab_reset_wait < 600)){ - taskDelay(1); - ab_reset_wait++; - } - if (ab_reset_wait < 600) - printf("Link %d Power Up After %d Ticks\n",link,ab_reset_wait); - else - printf("Link %d Failed to Reinitialize After %d Ticks\n", - link,ab_reset_wait); - - link_init(plink); - /* enable the scanner */ - plink->ab_disable = 0; -} - -int ab_reset_link(int link) -{ - ab_link *plink; - - if(link>=max_ab_6008s) return(0); - plink = pab_links[link]; - if(!plink) return(0); - taskSpawn("ab_reset",38,0,8000,(FUNCPTR)ab_reset_task,(int)plink, - 0,0,0,0,0,0,0,0,0); - return(0); -} - -int ab_reset(void) -{ - int link; - - for(link=0; linkinitialized) { - printf("AB-6008SV link %hu not initialized\n",link); - continue; - } - printf("AB-6008SV link: %hu osw %4.4x vme: %p\n", - link,plink->vme_addr->osw,plink->vme_addr); - if(plink->firmware_info[0]) printf(" %s\n",plink->firmware_info); - printf(" Mailbox lock timeouts %hu\n",plink->sclock_to); - printf(" Command timeouts %hu\n", plink->sccmd_to); - printf(" Command Failure %hu\n", plink->sc_fail); - printf(" Interrupts per second %hu\n", plink->intrSec); - printf(" Block Transfers per second %hu\n", plink->btSec); - if(level>2) { - ab_link_status *plink_status = plink->plink_status; - - printf(" Adapter Status Words"); - for(i=0; i<32; i++) { - if((i%8)==0) printf("\n "); - printf("%4.4x ",plink_status->status[i]); - } - printf("\n scan list"); - for(i=0; ilist_len; i++) { - if((i%16)==0) printf("\n "); - printf("%2.2x ",plink_status->list[i]); - } - printf("\n"); - } - /* adapter information */ - for (adapter = 0; adapter < AB_MAX_ADAPTERS; adapter++){ - padapter = plink->papadapter[adapter]; - if (!padapter) continue; - if (padapter->adapter_online) - printf(" Adapter %hu ONLINE\n",adapter); - else - printf(" Adapter %hu OFFLINE\n",adapter); - - /* card information */ - for (card = 0; card < AB_MAX_CARDS; card++){ - pcard = padapter->papcard[card]; - if(!pcard) continue; - pscanInfo = pcard->pscanInfo; - switch (pcard->type){ - case (typeBi): - di_read(pcard,&divalue); - printf(" CARD %hu: BI %s %s 0x%x\n", - card,abNumBitsMessage[pcard->nBits], - activeMessage[pcard->active],divalue); - break; - case (typeBo): - do_read(pcard,&dovalue); - printf(" CARD %hu: BO %s %s 0x%x\n", - card,abNumBitsMessage[pcard->nBits], - activeMessage[pcard->active],dovalue); - break; - case (typeBiBo): - di_read(pcard,&divalue); - do_read(pcard,&dovalue); - printf(" CARD %hu: BIBO %s %s in 0x%x out 0x%x\n", - card,abNumBitsMessage[pcard->nBits], - activeMessage[pcard->active],divalue,dovalue); - break; - case (typeAi): - case (typeAo): - if(pcard->type==typeAi) - printf(" CARD %hu: AI ",card); - else - printf(" CARD %hu: AO ",card); - if(!pscanInfo || pscanInfo->state==stateInit) - printf(" NOT INITIALIZED "); - printf(" %s %s",activeMessage[pcard->active], - pcard->card_name); - /* error reporting */ - if(!pscanInfo) { - printf("\n"); - break; - } - if (pscanInfo->bt_to) - printf(" bt timeout: %hu",pscanInfo->bt_to); - if (pscanInfo->bt_fail) - printf(" bt fail: %hu",pscanInfo->bt_fail); - if (pscanInfo->init_ctr) - printf(" initialized %hu times",pscanInfo->init_ctr); - printf("\n"); - if (level > 0){ - if(pcard->type==typeAo || level>1) { - printf("\tWrite"); - for (i=0; iwrite_msg_len; i++) { - if((i%10)==0) printf("\n\t"); - printf("%4.4x ",pscanInfo->pwrite_msg[i]); - } - printf("\n"); - } - if(pcard->type==typeAi || level>1) { - printf("\tRead"); - for (i=0; iread_msg_len; i++) { - if((i%10)==0) printf("\n\t"); - printf("%4.4x ",pscanInfo->pread_msg[i]); - } - printf("\n"); - } - } - break; - case (typeBt): - printf(" CARD %hu: BT %s %s\n", card, - activeMessage[pcard->active],pcard->card_name); - break; - default: - continue; - } - } - } - } - return(0); - -} - -LOCAL abStatus registerCard( - unsigned short link,unsigned short adapter, unsigned short card, - cardType type, const char *card_name, void (*callback)(void *drvPvt), - void **pdrvPvt) -{ - ab_adapter *padapter; - ab_card *pcard = NULL; - ab_link *plink; - ab_card **ppcard = (ab_card **)pdrvPvt; - - - if(link>=max_ab_6008s) { - if(ab_debug>0) - printf("abDrv(registerCard) bad link %hu\n",link); - return(abNoCard); - } - if(adapter>=MAX_AB_ADAPTERS) { - if(ab_debug>0) - printf("abDrv(registerCard) bad adapter %hu\n",adapter); - return(abNoCard); - } - if(card>=MAX_CARDS_PER_ADAPTER) { - if(ab_debug>0) - printf("abDrv(registerCard) bad card %hu\n",card); - return(abNoCard); - } - if(!pab_links || !(plink = pab_links[link]) || !plink->initialized) { - if(ab_debug>0) - printf("abDrv(registerCard) link %hu not initialized\n",link); - return(abNoCard); - } - padapter = plink->papadapter[adapter]; - if(padapter) pcard = padapter->papcard[card]; - if(pcard) { - if(strcmp(pcard->card_name,card_name)!=0) return(abCardConflict); - if(pcard->type==type) { - *ppcard = pcard; - return(abSuccess); - } - if(type==typeBi || type==typeBo) { - if(pcard->type==typeBo || pcard->type==typeBi - || pcard->type==typeBiBo) { - if(!pcard->callback && type==typeBi ) - pcard->callback = callback; - if(!pcard->bocallback && type==typeBo ) - pcard->bocallback = callback; - pcard->type = typeBiBo; - *ppcard = pcard; - return(abSuccess); - } - } - return(abCardConflict); - } - /*New Card*/ - pcard = abCalloc(1,sizeof(ab_card)); - pcard->link = link; - pcard->adapter = adapter; - pcard->card = card; - pcard->type = type; - pcard->card_name = card_name; - if(!(pcard->card_sem = semBCreate(SEM_Q_FIFO,SEM_FULL))){ - printf("abDrv register card: semBcreate failed\n"); - taskSuspend(0); - } - if(type==typeBo) pcard->bocallback = callback; - else pcard->callback = callback; - if(type==typeAi || type ==typeAo || type == typeBt) { - pcard->pbtInfo = abCalloc(1,sizeof(btInfo)); - if(type == typeBt) { - if(!(pcard->pbtInfo->wdId = wdCreate()) ) { - printf("abDrv register card: wdCreate failed\n"); - taskSuspend(0); - } - } - } - *ppcard = pcard; - if(!padapter) { - padapter = abCalloc(1,sizeof(ab_adapter)); - padapter->papcard = abCalloc(MAX_CARDS_PER_ADAPTER,sizeof(ab_card *)); - if(!(padapter->adapter_sem = semBCreate(SEM_Q_FIFO,SEM_FULL))){ - printf("abDrv: abRegister: semBcreate failed\n"); - taskSuspend(0); - } - padapter->adapter = adapter; - } - padapter->papcard[card] = pcard; - if(!plink->papadapter[adapter]) plink->papadapter[adapter] = padapter; - link_status(plink); - return(abNewCard); -} - -LOCAL void getLocation(void *drvPvt,unsigned short *link, - unsigned short *adapter,unsigned short *card) -{ - ab_card *pcard = drvPvt; - - *link = pcard->link; - *adapter = pcard->adapter; - *card = pcard->card; - return; -} - -LOCAL abStatus setNbits(void *drvPvt, abNumBits nBits) -{ - ab_card *pcard = drvPvt; - - if(pcard->nBits == abBitNotdefined) { - pcard->nBits = nBits; - pcard->active = TRUE; - return(abSuccess); - } - if(pcard->nBits == nBits) return(abSuccess); - return(abFailure); -} - -LOCAL void setUserPvt(void *drvPvt,void *userPvt) -{ - ab_card *pcard = drvPvt; - - pcard->userPvt = userPvt; - return; -} - -LOCAL void *getUserPvt(void *drvPvt) -{ - ab_card *pcard = drvPvt; - - return(pcard->userPvt); -} - -LOCAL abStatus getStatus(void *drvPvt) -{ - ab_card *pcard = drvPvt; - - unsigned short link = pcard->link; - unsigned short adapter = pcard->adapter; - ab_adapter *padapter = pab_links[link]->papadapter[adapter]; - - if(!padapter->adapter_online) return(abAdapterDown); - return(pcard->status); -} - -LOCAL abStatus startScan(void *drvPvt, unsigned short update_rate, - unsigned short *pwrite_msg, unsigned short write_msg_len, - unsigned short *pread_msg, unsigned short read_msg_len) -{ - ab_card *pcard = drvPvt; - scanInfo *pscanInfo; - - pscanInfo = pcard->pscanInfo; - if(!pscanInfo) pcard->pscanInfo = pscanInfo = abCalloc(1,sizeof(scanInfo)); - pscanInfo->update_rate = update_rate; - pscanInfo->pwrite_msg = pwrite_msg; - pscanInfo->write_msg_len = write_msg_len; - pscanInfo->pread_msg = pread_msg; - pscanInfo->read_msg_len = read_msg_len; - pscanInfo->state = stateInit; - pcard->active = TRUE; - pcard->status = abNotInitialized; - return(abSuccess); -} - -LOCAL abStatus updateAo(void *drvPvt) -{ - ab_card *pcard = drvPvt; - - pcard->needsUpdate = TRUE; - return(getStatus(drvPvt)); -} - -LOCAL abStatus updateBo(void *drvPvt,unsigned long value,unsigned long mask) -{ - ab_card *pcard = drvPvt; - unsigned long imagevalue; - - semTake(pcard->card_sem,WAIT_FOREVER); - do_read(pcard,&imagevalue); - imagevalue = (imagevalue & ~mask) | (value & mask); - do_write(pcard,imagevalue); - semGive(pcard->card_sem); - if(pcard->bocallback) (*pcard->bocallback)((void *)pcard); - return(getStatus(drvPvt)); -} - -LOCAL abStatus readBo(void *drvPvt,unsigned long *pvalue,unsigned long mask) -{ - ab_card *pcard = drvPvt; - unsigned long value; - - do_read(pcard,&value); - *pvalue = value & mask; - return(getStatus(drvPvt)); -} - -LOCAL abStatus readBi(void *drvPvt,unsigned long *pvalue,unsigned long mask) -{ - ab_card *pcard = drvPvt; - unsigned long value; - - di_read(pcard,&value); - *pvalue = value & mask; - return(getStatus(drvPvt)); -} - -static void btTimeoutCallback(ab_card *pcard) -{ - pcard->pbtInfo->btStatus = abFailure; - if(ab_debug) logMsg("btTimeoutCallback link %d adapter %d card %d\n", - pcard->link,pcard->adapter,pcard->card,0,0,0); - return; -} - -LOCAL abStatus btReadWrite(unsigned short cmd, void *drvPvt, - unsigned short *pread_msg, unsigned short read_msg_len) -{ - ab_card *pcard = drvPvt; - int btStatus; - STATUS wdStatus; - - if(!pcard) return(abFailure); - semTake(pcard->card_sem,WAIT_FOREVER); - if(pcard->active) { - btStatus = abBusy; - } else { - pcard->active = TRUE; - btStatus=bt_queue(cmd,pcard,pread_msg,read_msg_len); - if(btStatus==abBtqueued) { - /* Set timeout for 1 second more than 68008 SV block */ - /* transfer timout, which is 4 seconds */ - wdStatus = wdStart(pcard->pbtInfo->wdId, - sysClkRateGet()*5, - (FUNCPTR)btTimeoutCallback,(int)pcard); - if(wdStatus==ERROR) { - printf("abDrv btReadWrite : wdStart failure\n"); - btStatus = abFailure; - } - } - if(btStatus!=abBtqueued) pcard->active = FALSE; - } - semGive(pcard->card_sem); - return(btStatus); -} - -LOCAL abStatus btRead(void *drvPvt, - unsigned short *pread_msg, unsigned short read_msg_len) -{ - return(btReadWrite(AB_READ,drvPvt,pread_msg,read_msg_len)); -} - -LOCAL abStatus btWrite(void *drvPvt, - unsigned short *pwrite_msg, unsigned short write_msg_len) -{ - return(btReadWrite(AB_WRITE,drvPvt,pwrite_msg,write_msg_len)); -} - -LOCAL abStatus adapterStatus(unsigned short link,unsigned short adapter) -{ - ab_adapter *padapter; - ab_link *plink; - - if(link>=max_ab_6008s) return(abFailure); - if(adapter>=MAX_AB_ADAPTERS) return(abFailure); - plink = pab_links[link]; - if(!plink || !plink->initialized) return(abFailure); - padapter = plink->papadapter[adapter]; - if(!padapter->adapter_online) return(abAdapterDown); - return(abSuccess); -} - -LOCAL abStatus cardStatus( - unsigned short link,unsigned short adapter,unsigned short card) -{ - ab_adapter *padapter; - ab_link *plink; - ab_card *pcard; - - if(link>=max_ab_6008s) return(abFailure); - if(adapter>=MAX_AB_ADAPTERS) return(abFailure); - if(card>=MAX_CARDS_PER_ADAPTER) return(abFailure); - plink = pab_links[link]; - if(!plink || !plink->initialized) return(abFailure); - padapter = plink->papadapter[adapter]; - if(!padapter->adapter_online) return(abAdapterDown); - pcard = padapter->papcard[card]; - if(!pcard) return(abNoCard); - if(!padapter->adapter_online) return(abAdapterDown); - return(pcard->status); -} - -LOCAL abDrv abDrvTable= { - registerCard,getLocation,setNbits,setUserPvt,getUserPvt, - getStatus,startScan,updateAo,updateBo,readBo,readBi,btRead,btWrite, - adapterStatus,cardStatus -}; -abDrv *pabDrv = &abDrvTable; - - -/*Time how long it takes to issue link_status */ -int ab_time_link_status(int link) -{ - ab_link *plink = pab_links[link]; - int startTicks; - int stopTicks; - int pass; - double tdiff; - - if(!plink) return(-1); - startTicks = tickGet(); - for (pass=0; pass<100; pass++) link_status(plink); - stopTicks = tickGet(); - tdiff = (stopTicks - startTicks)/60.0; - printf("pass/sec %f\n",(float)pass/tdiff); - return(0); -} diff --git a/src/drv/ansi/drvAb.h b/src/drv/ansi/drvAb.h deleted file mode 100644 index 6d96a904c..000000000 --- a/src/drv/ansi/drvAb.h +++ /dev/null @@ -1,93 +0,0 @@ -/* drvAb.h */ -/* header file for the Allen-Bradley Remote Serial IO - * This defines interface between driver and device support - * - * Author: Marty Kraimer - * Date: 03-06-95 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * 01 03-06-95 mrk Moved all driver specific code to drvAb.c - */ - -#ifndef INCdrvAbh -#define INCdrvAbh 1 -#include "dbScan.h" - - -/* interface types */ -typedef enum {typeNotAssigned,typeBi,typeBo,typeBiBo,typeAi,typeAo,typeBt} - cardType; -/* status values*/ -typedef enum{abSuccess,abNewCard,abCardConflict,abNoCard,abNotInitialized, - abBtqueued,abBusy,abTimeout,abAdapterDown,abFailure} abStatus; -extern char **abStatusMessage; - -typedef enum{abBitNotdefined,abBit8,abBit16,abBit32} abNumBits; -extern char **abNumBitsMessage; - -/*entry table for dev to drv routines*/ -typedef struct { - abStatus (*registerCard) - (unsigned short link,unsigned short adapter, unsigned short card, - cardType type, const char *card_name, - void (*callback)(void *drvPvt), - void **drvPvt); - void (*getLocation) - (void *drvPvt, - unsigned short *link, unsigned short *adapter,unsigned short *card); - abStatus (*setNbits)(void *drvPvt, abNumBits nbits); - void (*setUserPvt)(void *drvPvt, void *userPvt); - void *(*getUserPvt)(void *drvPvt); - abStatus (*getStatus)(void *drvPvt); - abStatus(*startScan) - (void *drvPvt, unsigned short update_rate, - unsigned short *pwrite_msg, unsigned short write_msg_len, - unsigned short *pread_msg, unsigned short read_msg_len); - abStatus(*updateAo)(void *drvPvt); - abStatus(*updateBo) (void *drvPvt,unsigned long value,unsigned long mask); - abStatus(*readBo) (void *drvPvt,unsigned long *value,unsigned long mask); - abStatus(*readBi) (void *drvPvt,unsigned long *value,unsigned long mask); - abStatus(*btRead)(void *drvPvt,unsigned short *pread_msg, - unsigned short read_msg_len); - abStatus(*btWrite)(void *drvPvt,unsigned short *pwrite_msg, - unsigned short write_msg_len); - abStatus (*adapterStatus) - (unsigned short link,unsigned short adapter); - abStatus (*cardStatus) - (unsigned short link,unsigned short adapter, unsigned short card); -}abDrv; - -extern abDrv *pabDrv; - -int ab_reset(void); -int ab_reset_link(int link); -int abConfigNlinks(int nlinks); -int abConfigVme(int link, int base, int vector, int level); -int abConfigBaud(int link, int baud); -int abConfigScanList(int link, int scan_list_len, char *scan_list); -int abConfigScanListAscii(int link, char *filename,int setRackSize); -int abConfigAuto(int link); - -#endif /*INCdrvAbh*/ diff --git a/src/drv/old/drvBB232.c b/src/drv/old/drvBB232.c deleted file mode 100644 index 658d8b836..000000000 --- a/src/drv/old/drvBB232.c +++ /dev/null @@ -1,590 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * Author: John Winans - * Date: 05-21-92 - * EPICS BITBUS -> R/S-232 driver - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 09-30-91 jrw created - * - */ - -#define DRVBB232_C - -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -int drvBB232Debug = 0; -int softBB232 = 0; - -extern struct drvBitBusEt drvBitBus; - -/****************************************************************************** - * - ******************************************************************************/ -#define BB232LINK_PRI 50 -#define BB232LINK_OPT VX_FP_TASK|VX_STDIO -#define BB232LINK_STACK 5000 - - -/****************************************************************************** - * - ******************************************************************************/ -static long -report() -{ - printf("Report for BITBUS -> RS-232 driver\n"); - return(OK); -} - -/****************************************************************************** - * - ******************************************************************************/ -static long -init(pparms) -msgDrvIniParm *pparms; -{ - if (drvBB232Debug) - printf("Init for BITBUS -> RS-232 driver\n"); - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgXact structure. - * - * It is also responsible for filling in the msgXact.phwpvt pointer. - * - ******************************************************************************/ -static long -genXact(p) -msgDrvGenXParm *p; -{ - long stat = -1; - char message[100]; - drvBB232Link *pdrvBB232Link; - struct dpvtBitBusHead *pdpvtBitBusHead; - - if (p->plink->type != BITBUS_IO) - { - p->pmsgXact->prec->pact = TRUE; - sprintf("%s: invalid device type in devSup.ascii (%d)\n", p->pmsgXact->prec->name, p->plink->type); - errMessage(S_db_badField, message); - return(ERROR); - } - - if (drvBB232Debug) - printf("BB232 genXact entered for link %d, bug %d, port %d, parm %s\n", p->plink->value.bitbusio.link, p->plink->value.bitbusio.node, p->plink->value.bitbusio.port, p->plink->value.bitbusio.parm); - - p->pmsgXact->phwpvt = p->pmsgXact->pparmBlock->pmsgHwpvt; - - /* try to find the hwpvt structure for the required link, bug, and port */ - while ((p->pmsgXact->phwpvt != NULL) && (stat == -1)) - { - pdrvBB232Link = (drvBB232Link *)(p->pmsgXact->phwpvt->pmsgLink->p); - - if ((pdrvBB232Link->link == p->plink->value.bitbusio.link) - && (pdrvBB232Link->node == p->plink->value.bitbusio.node) - && (pdrvBB232Link->port == p->plink->value.bitbusio.port)) - { - if (pdrvBB232Link->pparmBlock != p->pmsgXact->pparmBlock) - { - sprintf(message, "%s: Two different devices on same BB232 port\n", p->pmsgXact->prec->name); - errMessage(S_db_badField, message); - return(ERROR); - } - else - stat = 0; /* Found the correct hwpvt structure */ - } - else - p->pmsgXact->phwpvt = p->pmsgXact->phwpvt->next; - } - if (stat != 0) - { /* Could not find a msgHwpvt for the right link, create a new one */ - if ((p->pmsgXact->phwpvt = drvMsg_genHwpvt(p->pmsgXact->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - /* Set again in case hwpvt was just allocated (and to make compiler happy) */ - pdrvBB232Link = (drvBB232Link *)(p->pmsgXact->phwpvt->pmsgLink->p); - - p->pmsgXact->callback.callback = NULL; - p->pmsgXact->psyncSem = NULL; - - /* Create the skeleton bitbus driver message */ - pdpvtBitBusHead = (struct dpvtBitBusHead *) malloc(sizeof(struct dpvtBitBusHead)); - (struct dpvtBitBusHead *)(p->pmsgXact->p) = pdpvtBitBusHead; - - pdpvtBitBusHead->finishProc = NULL; - pdpvtBitBusHead->psyncSem = malloc(sizeof(SEM_ID)); - *(pdpvtBitBusHead->psyncSem) = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - pdpvtBitBusHead->link = pdrvBB232Link->link; - - pdpvtBitBusHead->txMsg.route = BB_STANDARD_TX_ROUTE; - pdpvtBitBusHead->txMsg.node = pdrvBB232Link->node; - pdpvtBitBusHead->txMsg.tasks = BB_232_TASK; - pdpvtBitBusHead->txMsg.cmd = 0xff; - - pdpvtBitBusHead->rxMsg.data = (unsigned char *) malloc(BB_MAX_DAT_LEN); - - /* in case I read before write */ - pdpvtBitBusHead->rxMsg.cmd = 0; - pdpvtBitBusHead->rxMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->status = BB_OK; - - pdpvtBitBusHead->rxMaxLen = 0; - pdpvtBitBusHead->ageLimit = 0; - - if (sscanf(p->plink->value.bitbusio.parm,"%d", &(p->pmsgXact->parm)) != 1) - { - p->pmsgXact->prec->pact = TRUE; - sprintf("%s: invalid parameter string >%s<\n", p->pmsgXact->prec->name, p->plink->value.bitbusio.parm); - errMessage(S_db_badField, message); - return(ERROR); - } - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgHwpvt structure. - * - * It is also responsible for filling in the msgHwpvt.pmsgLink pointer. - * - ******************************************************************************/ -static long -genHwpvt(p) -msgDrvGenHParm *p; -{ - int stat = ERROR; - - if (drvBB232Debug) - printf("BB232 genHwpvt entered\n"); - - p->pmsgHwpvt->pmsgLink = drvBB232Block.pmsgLink; - while ((p->pmsgHwpvt->pmsgLink != NULL) && (stat == ERROR)) - { - if ((((drvBB232Link *)(p->pmsgHwpvt->pmsgLink->p))->link == p->plink->value.bitbusio.link) - && (((drvBB232Link *)(p->pmsgHwpvt->pmsgLink->p))->node == p->plink->value.bitbusio.node) - && (((drvBB232Link *)(p->pmsgHwpvt->pmsgLink->p))->port == p->plink->value.bitbusio.port)) - stat = OK; - else - p->pmsgHwpvt->pmsgLink = p->pmsgHwpvt->pmsgLink->next; - } - if (stat != OK) - { - if ((p->pmsgHwpvt->pmsgLink = drvMsg_genLink(p->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgLink structure. - * - ******************************************************************************/ -static long -genLink(p) -msgDrvGenLParm *p; -{ - char message[100]; - drvBB232Link *pdrvBB232Link; - - if (drvBB232Debug) - printf("BB232 genLink, link = %d, node = %d port = %d\n", - p->plink->value.bitbusio.link, p->plink->value.bitbusio.node, - p->plink->value.bitbusio.port); - - switch (p->op) { - case MSG_GENLINK_CREATE: - -/* BUG -- verify that the link and node numbers are within range! */ - - if (p->plink->value.bitbusio.port & (~DD_232_PORT)) - { - sprintf(message, "drvBB232: port number %d out of range\n", p->plink->value.bitbusio.port); - errMessage(S_db_badField, message); - return(ERROR); - } - - if ((p->pmsgLink->p = malloc(sizeof(drvBB232Link))) == NULL) - return(ERROR); - - pdrvBB232Link = (drvBB232Link *)(p->pmsgLink->p); - - pdrvBB232Link->link = p->plink->value.bitbusio.link; - pdrvBB232Link->node = p->plink->value.bitbusio.node; - pdrvBB232Link->port = p->plink->value.bitbusio.port; - pdrvBB232Link->pparmBlock = p->pparmBlock; - - - return(OK); - - case MSG_GENLINK_ABORT: - - if (drvBB232Debug) - printf("BB232 genLink: called with abort status\n"); - - pdrvBB232Link = (drvBB232Link *)(p->pmsgLink->p); - /* BUG - free(p->pmsgLink->p); Don't forget to take it out of the list */ - return(OK); - } - return(ERROR); -} - -/****************************************************************************** - * - * This function is called to allow the device to indicate that a device-related - * event has occurred. If an event had occurred, it would have to place the - * address of a valid transaction structure in pxact. This xact structure - * will then be processed by the message link task as indicated by the - * return code of this function. - * - * MSG_EVENT_NONE = no event has occurred, pxact not filled in. - * MSG_EVENT_WRITE = event occurred, process the writeOp assoc'd w/pxact. - * MSG_EVENT_READ = event occurred, process the readOp assoc'd w/pxact. - * - * Note that MSG_EVENT_READ only makes sense when returned with a transaction - * that has deferred readback specified for its readOp function. Because if - * it is NOT a deferred readback, it will be done immediately after the writeOp. - * Even if that writeOp was due to a MSG_EVENT_WRITE from this function. - * - ******************************************************************************/ -static long -checkEvent(p) -msgChkEParm *p; -{ - return(MSG_EVENT_NONE); -} -/****************************************************************************** - * - * This IOCTL function is used to handle non-I/O related operations required - * to operate the RS-232 interface. - * - ******************************************************************************/ -static long -command(p) -ioctlCommand *p; -{ - msgXact *pxact; - struct dpvtBitBusHead *pdpvtBitBusHead; - drvBB232Link *pdrvBB232Link; - - switch (p->cmd) { - case IOCTL232_BREAK: /* send a BREAK signal to the serial port. */ - /* Build a break message to send */ - pxact = (msgXact *) (p->pparm); - pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - pdrvBB232Link = (drvBB232Link *)(pxact->phwpvt->pmsgLink->p); - pdpvtBitBusHead->status = BB_OK; - pdpvtBitBusHead->rxMaxLen = 0; - pdpvtBitBusHead->txMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->txMsg.cmd = BB_232_BREAK + pdrvBB232Link->port; - pdpvtBitBusHead->rxMsg.cmd = 0; - - if (drvBB232Debug > 7) - { - printf("drvBB232.control (tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); - - if ((pdpvtBitBusHead->status == BB_OK) && !(pdpvtBitBusHead->rxMsg.cmd & 1)) - return(OK); - else - return(ERROR); - } - - if (drvBB232Debug) - printf("drvBB232.control: bad command 0x%2.2X\n", p->cmd); - return(ERROR); -} - -/****************************************************************************** - * - * This function is used to write a string of characters out to an RS-232 - * device. - * - * Note that the BUGs reply to the write messages with the first 13 bytes - * of the machine's response string (if there is one.) This response string - * will be left in the pdpvtBitBusHead->rxMsg buffer when the drvRead() - * function is called later. - * - ******************************************************************************/ -static long -drvWrite(pxact, pwrParm) -msgXact *pxact; -msgStrParm *pwrParm; -{ - int len; - drvBB232Link *pdrvBB232Link = (drvBB232Link *)(pxact->phwpvt->pmsgLink->p); - struct dpvtBitBusHead *pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - unsigned char loopLen; - - /* build a bitbus message and call the bitbus driver */ - - if (pwrParm->len == -1) - len = strlen(pwrParm->buf); - else - len = pwrParm->len; - - pdpvtBitBusHead->txMsg.data = (unsigned char *) pwrParm->buf; - pdpvtBitBusHead->status = BB_OK; - pdpvtBitBusHead->rxMaxLen = BB_MAX_MSG_LENGTH; - - pdpvtBitBusHead->txMsg.cmd = BB_232_CMD + pdrvBB232Link->port; - pdpvtBitBusHead->rxMsg.cmd = 0; - - while (len && (pdpvtBitBusHead->status == BB_OK) && - !(pdpvtBitBusHead->rxMsg.cmd & 1)) - { - if (len > BB_MAX_DAT_LEN) - loopLen = BB_MAX_DAT_LEN; - else - loopLen = len; - - pdpvtBitBusHead->txMsg.length = loopLen + BB_MSG_HEADER_SIZE; - if (softBB232) - { - printf("drvBB232.drvWrite(tx L%d N%d P%d):\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - else - { - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); /* do it */ - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); /* wait for completion */ - if (drvBB232Debug > 10) - { - printf("drvBB232.drvWrite (tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - } - - pdpvtBitBusHead->txMsg.data += loopLen; - len -= loopLen; - } - - if ((pdpvtBitBusHead->status != BB_OK) || (pdpvtBitBusHead->rxMsg.cmd & 1)) - { - if (drvBB232Debug) - printf("BB232 write error on link %d, node %d, port %d, driver %2.2X, message %2.2X\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port, pdpvtBitBusHead->status, pdpvtBitBusHead->rxMsg.cmd); - - pxact->status = XACT_IOERR; - } - - return(pxact->status); -} - -/****************************************************************************** - * - * This function is used to read a string of characters from an RS-232 device. - * - * It is assumed that pdpvtBitBusHead->rxMsg has already got up to 13 - * bytes of the response data already filled in (left there by the prior - * call to drvWrite().) If a call to this function is made when there is - * garbage in the initial pdpvtBitBusHead->rxMsg buffer, set the length field - * to 0 and the status field to BB_OK. - * - ******************************************************************************/ -static long -drvRead(pxact, prdParm) -msgXact *pxact; -msgStrParm *prdParm; -{ - drvBB232Link *pdrvBB232Link = (drvBB232Link *)(pxact->phwpvt->pmsgLink->p); - struct dpvtBitBusHead *pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - int len = prdParm->len; - int loopLen = 0; - - /* check if data already loaded into pdpvtBitBusHead->rxMsg */ - if ((pdpvtBitBusHead->rxMsg.length > BB_MSG_HEADER_SIZE) && (pdpvtBitBusHead->status == BB_OK)) - { - loopLen = pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - - if (prdParm->len < loopLen) - loopLen = prdParm->len; - - if (drvBB232Debug > 9) - { - printf("drvBB232.drvRead (rx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - bcopy(pdpvtBitBusHead->rxMsg.data, prdParm->buf, loopLen); - len -= loopLen; - } - - pdpvtBitBusHead->txMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->txMsg.cmd = BB_232_CMD + pdrvBB232Link->port; - - pdpvtBitBusHead->rxMsg.data = (unsigned char *) (&(prdParm->buf[loopLen])); - - if (!(pdpvtBitBusHead->rxMsg.cmd & BB_232_EOI)) - { /* If we did not hit EOI yet, keep reading */ - - while (len && (pdpvtBitBusHead->status == BB_OK)) - { - if (len > BB_MAX_DAT_LEN) - loopLen = BB_MAX_DAT_LEN; - else - loopLen = len; - - pdpvtBitBusHead->rxMaxLen = loopLen + BB_MSG_HEADER_SIZE; - if (softBB232) - { - printf("drvBB232.drvRead(tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - pdpvtBitBusHead->status = BB_232_EOI; - } - else - { - if (drvBB232Debug > 10) - { - printf("drvBB232.drvRead(tx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); /* do it */ - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); /* wait for completion */ - - if (drvBB232Debug > 9) - { - printf("drvBB232.drvRead (rx L%d N%d P%d)\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - } - - if (pdpvtBitBusHead->rxMsg.cmd & (~BB_232_EOI)) - { /* Something is wrong... */ - if (drvBB232Debug > 6) - { - printf("drvBB232.drvRead (rx L%d N%d P%d) Error response from BUG\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - pxact->status = XACT_IOERR; - break; /* note that we will fall thru to the null-term code */ - } - if (pdpvtBitBusHead->rxMsg.cmd & BB_232_EOI) - { - pdpvtBitBusHead->rxMsg.data += pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - len -= pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - break; - } - - pdpvtBitBusHead->rxMsg.data += loopLen; - len -= loopLen; - } - } - /* Null-terminate the input string (if there is room) */ - if (len) - *(pdpvtBitBusHead->rxMsg.data) = '\0'; - else - pxact->status = XACT_LENGTH; - - /* Note that the following error check, takes priority over a length error */ - if (pdpvtBitBusHead->status != BB_OK) - { - if (drvBB232Debug) - printf("BB232 read error on link %d, node %d, port %d\n", pdrvBB232Link->link, pdrvBB232Link->node, pdrvBB232Link->port); - pxact->status = XACT_IOERR; - } - -/* BUG -- this can print unterminated strings !! */ - if (drvBB232Debug > 7) - printf("drvRead: got >%s<\n", prdParm->buf); - - pdpvtBitBusHead->rxMsg.length = BB_MSG_HEADER_SIZE; /* in case keep reading */ - return(pxact->status); -} - -/****************************************************************************** - * - * This handles any IOCTL calls made to BB-232 devices. - * - ******************************************************************************/ -static long -drvIoctl(cmd, pparm) -int cmd; -void *pparm; -{ - switch (cmd) { - case MSGIOCTL_REPORT: - return(report()); - case MSGIOCTL_INIT: - return(init(pparm)); - case MSGIOCTL_INITREC: - if (drvBB232Debug) - printf("drvBB232Block.drvIoctl got a MSGIOCTL_INITREC request!\n"); - return(ERROR); - case MSGIOCTL_GENXACT: - return(genXact(pparm)); - case MSGIOCTL_GENHWPVT: - return(genHwpvt(pparm)); - case MSGIOCTL_GENLINK: - return(genLink(pparm)); - case MSGIOCTL_CHECKEVENT: - return(checkEvent(pparm)); - case MSGIOCTL_COMMAND: - return(command(pparm)); - } - return(ERROR); -} - - -msgDrvBlock drvBB232Block = { - "BB232", /* taskName */ - BB232LINK_PRI, /* taskPri */ - BB232LINK_OPT, /* taskOpt */ - BB232LINK_STACK, /* taskStack */ - NULL, /* pmsgLink (linked list header) */ - drvWrite, /* drvWrite */ - drvRead, /* drvRead */ - drvIoctl /* drvIoctl */ -}; diff --git a/src/drv/old/drvBB232.h b/src/drv/old/drvBB232.h deleted file mode 100644 index d90bb1a69..000000000 --- a/src/drv/old/drvBB232.h +++ /dev/null @@ -1,69 +0,0 @@ -/* share/epicsH $Id$ */ -/* - * Author: John Winans - * Date: 5-21-92 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1988, 1989, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * All rights reserved. No part of this publication may be reproduced, - * stored in a retrieval system, transmitted, in any form or by any - * means, electronic, mechanical, photocopying, recording, or otherwise - * without prior written permission of Los Alamos National Laboratory - * and Argonne National Laboratory. - * - * Modification Log: - * ----------------- - * .01 05-21-92 jrw Initial release - * .02 02-19-92 joh cpu independent clk rate - */ - -#ifndef DRVBB232_H -#define DRVBB232_H - -/****************************************************************************** - * - * Additional fields needed for the msgParmBlock structure. - * - ******************************************************************************/ -typedef struct { - int dmaTimeout; /* Clock ticks to wait for DMA to complete */ - int baud; /* baud rate to run the interface */ -} drvBB232ParmBlock; - -typedef struct { - int link; /* The BB card/link number */ - int node; /* the bug's node number */ - int port; /* The tty port number on that card */ - /* The pparmBlock is used to make sure only 1 device type is requested */ - /* on one single port. */ - msgParmBlock *pparmBlock; -} drvBB232Link; - -#ifndef DRVBB232_C -extern -#endif -msgDrvBlock drvBB232Block; - -#define BB232_DEFAULT_AGE (sysClkRateGet()) /* 1 second */ - -#define BB_232_EOI 0x20 -#endif diff --git a/src/drv/old/drvBBMsg.c b/src/drv/old/drvBBMsg.c deleted file mode 100644 index e1976fe9c..000000000 --- a/src/drv/old/drvBBMsg.c +++ /dev/null @@ -1,590 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * Author: John Winans - * Date: 05-21-92 - * EPICS BITBUS driver for message based I/O - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 08-10-92 jrw created - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -int drvBBMsgDebug = 0; - -extern struct drvBitBusEt drvBitBus; - -/****************************************************************************** - * - ******************************************************************************/ -#define BBMSGLINK_PRI 50 -#define BBMSGLINK_OPT VX_FP_TASK|VX_STDIO -#define BBMSGLINK_STACK 5000 - - -/****************************************************************************** - * - ******************************************************************************/ -static long -report() -{ - printf("Report for BITBUS message driver\n"); - return(OK); -} - -/****************************************************************************** - * - ******************************************************************************/ -static long -init(pparms) -msgDrvIniParm *pparms; -{ - if (drvBBMsgDebug) - printf("Init for BITBUS message driver\n"); - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgXact structure. - * - * It is also responsible for filling in the msgXact.phwpvt pointer. - * - ******************************************************************************/ -static long -genXact(p) -msgDrvGenXParm *p; -{ - long stat = -1; - char message[100]; - drvBBMsgLink *pdrvBBMsgLink; - struct dpvtBitBusHead *pdpvtBitBusHead; - - if (p->plink->type != BITBUS_IO) - { - p->pmsgXact->prec->pact = TRUE; - sprintf("%s: invalid device type in devSup.ascii (%d)\n", p->pmsgXact->prec->name, p->plink->type); - errMessage(S_db_badField, message); - return(ERROR); - } - - if (drvBBMsgDebug) - printf("BBMsg genXact entered for link %d, bug %d, port %d, parm %s\n", p->plink->value.bitbusio.link, p->plink->value.bitbusio.node, p->plink->value.bitbusio.port, p->plink->value.bitbusio.parm); - - p->pmsgXact->phwpvt = p->pmsgXact->pparmBlock->pmsgHwpvt; - - /* try to find the hwpvt structure for the required link, bug, and port */ - while ((p->pmsgXact->phwpvt != NULL) && (stat == -1)) - { - pdrvBBMsgLink = (drvBBMsgLink *)(p->pmsgXact->phwpvt->pmsgLink->p); - - if ((pdrvBBMsgLink->link == p->plink->value.bitbusio.link) - && (pdrvBBMsgLink->node == p->plink->value.bitbusio.node) - && (pdrvBBMsgLink->port == p->plink->value.bitbusio.port)) - { - if (pdrvBBMsgLink->pparmBlock != p->pmsgXact->pparmBlock) - { - sprintf(message, "%s: Two different devices on same BBMsg port\n", p->pmsgXact->prec->name); - errMessage(S_db_badField, message); - return(ERROR); - } - else - stat = 0; /* Found the correct hwpvt structure */ - } - else - p->pmsgXact->phwpvt = p->pmsgXact->phwpvt->next; - } - if (stat != 0) - { /* Could not find a msgHwpvt for the right link, create a new one */ - if ((p->pmsgXact->phwpvt = drvMsg_genHwpvt(p->pmsgXact->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - /* Set again in case hwpvt was just allocated (and to make compiler happy) */ - pdrvBBMsgLink = (drvBBMsgLink *)(p->pmsgXact->phwpvt->pmsgLink->p); - - p->pmsgXact->callback.callback = NULL; - p->pmsgXact->psyncSem = NULL; - - /* Create the skeleton bitbus driver message */ - pdpvtBitBusHead = (struct dpvtBitBusHead *) malloc(sizeof(struct dpvtBitBusHead)); - (struct dpvtBitBusHead *)(p->pmsgXact->p) = pdpvtBitBusHead; - - pdpvtBitBusHead->finishProc = NULL; - pdpvtBitBusHead->psyncSem = malloc(sizeof(SEM_ID)); - *(pdpvtBitBusHead->psyncSem) = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - pdpvtBitBusHead->link = pdrvBBMsgLink->link; - - pdpvtBitBusHead->txMsg.route = BB_STANDARD_TX_ROUTE; - pdpvtBitBusHead->txMsg.node = pdrvBBMsgLink->node; - pdpvtBitBusHead->txMsg.tasks = BB_MSG_TASK; - pdpvtBitBusHead->txMsg.cmd = 0xff; - - pdpvtBitBusHead->rxMsg.data = (unsigned char *) malloc(BB_MAX_DAT_LEN); - - /* in case I read before write */ - pdpvtBitBusHead->rxMsg.cmd = 0; - pdpvtBitBusHead->rxMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->status = BB_OK; - - pdpvtBitBusHead->rxMaxLen = 0; - pdpvtBitBusHead->ageLimit = 0; - - if (sscanf(p->plink->value.bitbusio.parm,"%d", &(p->pmsgXact->parm)) != 1) - { - p->pmsgXact->prec->pact = TRUE; - sprintf("%s: invalid parameter string >%s<\n", p->pmsgXact->prec->name, p->plink->value.bitbusio.parm); - errMessage(S_db_badField, message); - return(ERROR); - } - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgHwpvt structure. - * - * It is also responsible for filling in the msgHwpvt.pmsgLink pointer. - * - ******************************************************************************/ -static long -genHwpvt(p) -msgDrvGenHParm *p; -{ - int stat = ERROR; - - if (drvBBMsgDebug) - printf("BBMSG genHwpvt entered\n"); - - p->pmsgHwpvt->pmsgLink = drvBBMSGBlock.pmsgLink; - while ((p->pmsgHwpvt->pmsgLink != NULL) && (stat == ERROR)) - { - if ((((drvBBMsgLink *)(p->pmsgHwpvt->pmsgLink->p))->link == p->plink->value.bitbusio.link) - && (((drvBBMsgLink *)(p->pmsgHwpvt->pmsgLink->p))->node == p->plink->value.bitbusio.node) - && (((drvBBMsgLink *)(p->pmsgHwpvt->pmsgLink->p))->port == p->plink->value.bitbusio.port)) - stat = OK; - else - p->pmsgHwpvt->pmsgLink = p->pmsgHwpvt->pmsgLink->next; - } - if (stat != OK) - { - if ((p->pmsgHwpvt->pmsgLink = drvMsg_genLink(p->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgLink structure. - * - ******************************************************************************/ -static long -genLink(p) -msgDrvGenLParm *p; -{ - char name[20]; - char message[100]; - drvBBMsgLink *pdrvBBMsgLink; - - if (drvBBMsgDebug) - printf("BBMsg genLink, link = %d, node = %d\n", p->plink->value.bitbusio.link, p->plink->value.bitbusio.node, p->plink->value.bitbusio.port); - - switch (p->op) { - case MSG_GENLINK_CREATE: - -/* BUG -- verify that the link and node numbers are within range! */ - - if (p->plink->value.bitbusio.port & (~DD_MSG_PORT)) - { - sprintf(message, "drvBBMsg: port number %d out of range\n", p->plink->value.bitbusio.port); - errMessage(S_db_badField, message); - return(ERROR); - } - - if ((p->pmsgLink->p = malloc(sizeof(drvBBMsgLink))) == NULL) - return(ERROR); - - pdrvBBMsgLink = (drvBBMsgLink *)(p->pmsgLink->p); - - pdrvBBMsgLink->link = p->plink->value.bitbusio.link; - pdrvBBMsgLink->node = p->plink->value.bitbusio.node; - pdrvBBMsgLink->port = p->plink->value.bitbusio.port; - pdrvBBMsgLink->pparmBlock = p->pparmBlock; - - - return(OK); - - case MSG_GENLINK_ABORT: - - if (drvBBMsgDebug) - printf("BBMsg genLink: called with abort status\n"); - - pdrvBBMsgLink = (drvBBMsgLink *)(p->pmsgLink->p); - /* BUG - free(p->pmsgLink->p); Don't forget to take it out of the list */ - return(OK); - } - return(ERROR); -} - -/****************************************************************************** - * - * This function is called to allow the device to indicate that a device-related - * event has occurred. If an event had occurred, it would have to place the - * address of a valid transaction structure in pxact. This xact structure - * will then be processed by the message link task as indicated by the - * return code of this function. - * - * MSG_EVENT_NONE = no event has occurred, pxact not filled in. - * MSG_EVENT_WRITE = event occurred, process the writeOp assoc'd w/pxact. - * MSG_EVENT_READ = event occurred, process the readOp assoc'd w/pxact. - * - * Note that MSG_EVENT_READ only makes sense when returned with a transaction - * that has deferred readback specified for its readOp function. Because if - * it is NOT a deferred readback, it will be done immediately after the writeOp. - * Even if that writeOp was due to a MSG_EVENT_WRITE from this function. - * - ******************************************************************************/ -static long -checkEvent(p) -msgChkEParm *p; -{ - return(MSG_EVENT_NONE); -} -/****************************************************************************** - * - * This IOCTL function is used to handle non-I/O related operations required - * to operate the RS-MSG interface. - * - ******************************************************************************/ -static long -command(p) -ioctlCommand *p; -{ - msgXact *pxact; - struct dpvtBitBusHead *pdpvtBitBusHead; - drvBBMsgLink *pdrvBBMsgLink; - - switch (p->cmd) { - case IOCTLMSG_BREAK: /* send a BREAK signal to the serial port. */ - /* Build a break message to send */ - pxact = (msgXact *) (p->pparm); - pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - pdrvBBMsgLink = (drvBBMsgLink *)(pxact->phwpvt->pmsgLink->p); - pdpvtBitBusHead->status = BB_OK; - pdpvtBitBusHead->rxMaxLen = 0; - pdpvtBitBusHead->txMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->txMsg.cmd = BB_MSG_BREAK + pdrvBBMsgLink->port; - pdpvtBitBusHead->rxMsg.cmd = 0; - - if (drvBBMsgDebug > 7) - { - printf("drvBBMsg.control (tx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); - - if ((pdpvtBitBusHead->status == BB_OK) && !(pdpvtBitBusHead->rxMsg.cmd & 1)) - return(OK); - else - return(ERROR); - } - - if (drvBBMsgDebug) - printf("drvBBMsg.control: bad command 0x%02.2X\n", p->cmd); - return(ERROR); -} - -/****************************************************************************** - * - * This function is used to write a string of characters out to an BB_MSG - * device. - * - * Note that the BUGs reply to the write messages with the first 13 bytes - * of the machine's response string (if there is one.) This response string - * will be left in the pdpvtBitBusHead->rxMsg buffer when the drvRead() - * function is called later. - * - ******************************************************************************/ -static long -drvWrite(pxact, pwrParm) -msgXact *pxact; -msgStrParm *pwrParm; -{ - int len; - drvBBMsgLink *pdrvBBMsgLink = (drvBBMsgLink *)(pxact->phwpvt->pmsgLink->p); - struct dpvtBitBusHead *pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - unsigned char loopLen; - - /* build a bitbus message and call the bitbus driver */ - - if (pwrParm->len == -1) - len = strlen(pwrParm->buf); - else - len = pwrParm->len; - - pdpvtBitBusHead->txMsg.data = (unsigned char *) pwrParm->buf; - pdpvtBitBusHead->status = BB_OK; - pdpvtBitBusHead->rxMaxLen = BB_MAX_MSG_LENGTH; - - pdpvtBitBusHead->txMsg.cmd = BB_MSG_CMD + pdrvBBMsgLink->port; - pdpvtBitBusHead->rxMsg.cmd = 0; - - while (len && (pdpvtBitBusHead->status == BB_OK) && - !(pdpvtBitBusHead->rxMsg.cmd & 1)) - { - if (len > BB_MAX_DAT_LEN) - loopLen = BB_MAX_DAT_LEN; - else - loopLen = len; - - pdpvtBitBusHead->txMsg.length = loopLen + BB_MSG_HEADER_SIZE; - if (softBBMsg) - { - printf("drvBBMsg.drvWrite(tx L%d N%d P%d):\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - else - { - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); /* do it */ - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); /* wait for completion */ - if (drvBBMsgDebug > 10) - { - printf("drvBBMsg.drvWrite (tx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - } - - pdpvtBitBusHead->txMsg.data += loopLen; - len -= loopLen; - } - - if ((pdpvtBitBusHead->status != BB_OK) || (pdpvtBitBusHead->rxMsg.cmd & 1)) - { - if (drvBBMsgDebug) - printf("BBMsg write error on link %d, node %d, port %d, driver %02.2X, message %02.2X\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port, pdpvtBitBusHead->status, pdpvtBitBusHead->rxMsg.cmd); - - pxact->status = XACT_IOERR; - } - - return(pxact->status); -} - -/****************************************************************************** - * - * This function is used to read a string of characters from an RS-Msg device. - * - * It is assumed that pdpvtBitBusHead->rxMsg has already got up to 13 - * bytes of the response data already filled in (left there by the prior - * call to drvWrite().) If a call to this function is made when there is - * garbage in the initial pdpvtBitBusHead->rxMsg buffer, set the length field - * to 0 and the status field to BB_OK. - * - ******************************************************************************/ -static long -drvRead(pxact, prdParm) -msgXact *pxact; -msgStrParm *prdParm; -{ - drvBBMsgLink *pdrvBBMsgLink = (drvBBMsgLink *)(pxact->phwpvt->pmsgLink->p); - struct dpvtBitBusHead *pdpvtBitBusHead = (struct dpvtBitBusHead *) pxact->p; - int len = prdParm->len; - int loopLen = 0; - unsigned char *tmp = pdpvtBitBusHead->rxMsg.data; - - /* check if data already loaded into pdpvtBitBusHead->rxMsg */ - if ((pdpvtBitBusHead->rxMsg.length > BB_MSG_HEADER_SIZE) && (pdpvtBitBusHead->status == BB_OK)) - { - loopLen = pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - - if (prdParm->len < loopLen) - loopLen = prdParm->len; - - if (drvBBMsgDebug > 9) - { - printf("drvBBMsg.drvRead (rx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - bcopy(pdpvtBitBusHead->rxMsg.data, prdParm->buf, loopLen); - len -= loopLen; - } - - pdpvtBitBusHead->txMsg.length = BB_MSG_HEADER_SIZE; - pdpvtBitBusHead->txMsg.cmd = BB_MSG_CMD + pdrvBBMsgLink->port; - - pdpvtBitBusHead->rxMsg.data = (unsigned char *) (&(prdParm->buf[loopLen])); - - if (!(pdpvtBitBusHead->rxMsg.cmd & BB_MSG_EOI)) - { /* If we did not hit EOI yet, keep reading */ - - while (len && (pdpvtBitBusHead->status == BB_OK)) - { - if (len > BB_MAX_DAT_LEN) - loopLen = BB_MAX_DAT_LEN; - else - loopLen = len; - - pdpvtBitBusHead->rxMaxLen = loopLen + BB_MSG_HEADER_SIZE; - if (softBBMsg) - { - printf("drvBB232.drvRead(tx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - pdpvtBitBusHead->status = BB_232_EOI; - } - else - { - if (drvBBMsgDebug > 10) - { - printf("drvBB232.drvRead(tx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->txMsg)); - } - - (*(drvBitBus.qReq))(pdpvtBitBusHead, BB_Q_LOW); /* do it */ - semTake(*(pdpvtBitBusHead->psyncSem), WAIT_FOREVER); /* wait for completion */ - - if (drvBBMsgDebug > 9) - { - printf("drvBB232.drvRead (rx L%d N%d P%d)\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - } - - if (pdpvtBitBusHead->rxMsg.cmd & (~BB_232_EOI)) - { /* Something is wrong... */ - if (drvBBMsgDebug > 6) - { - printf("drvBB232.drvRead (rx L%d N%d P%d) Error response from BUG\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - drvBitBusDumpMsg(&(pdpvtBitBusHead->rxMsg)); - } - pxact->status = XACT_IOERR; - break; /* note that we will fall thru to the null-term code */ - } - if (pdpvtBitBusHead->rxMsg.cmd & BB_232_EOI) - { - pdpvtBitBusHead->rxMsg.data += pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - len -= pdpvtBitBusHead->rxMsg.length - BB_MSG_HEADER_SIZE; - break; - } - - pdpvtBitBusHead->rxMsg.data += loopLen; - len -= loopLen; - } - } - /* Null-terminate the input string (if there is room) */ - if (len) - *(pdpvtBitBusHead->rxMsg.data) = '\0'; - else - pxact->status = XACT_LENGTH; - - /* Note that the following error check, takes priority over a length error */ - if (pdpvtBitBusHead->status != BB_OK) - { - if (drvBBMsgDebug) - printf("BB232 read error on link %d, node %d, port %d\n", pdrvBBMsgLink->link, pdrvBBMsgLink->node, pdrvBBMsgLink->port); - pxact->status = XACT_IOERR; - } - -/* BUG -- this can print unterminated strings !! */ - if (drvBBMsgDebug > 7) - printf("drvRead: got >%s<\n", prdParm->buf); - - pdpvtBitBusHead->rxMsg.length = BB_MSG_HEADER_SIZE; /* in case keep reading */ - return(pxact->status); -} - -/****************************************************************************** - * - * This handles any IOCTL calls made to BB-MSG devices. - * - ******************************************************************************/ -static long -drvIoctl(cmd, pparm) -int cmd; -void *pparm; -{ - switch (cmd) { - case MSGIOCTL_REPORT: - return(report()); - case MSGIOCTL_INIT: - return(init(pparm)); - case MSGIOCTL_INITREC: - if (drvBBMsgDebug) - printf("drvBBMsgBlock.drvIoctl got a MSGIOCTL_INITREC request!\n"); - return(ERROR); - case MSGIOCTL_GENXACT: - return(genXact(pparm)); - case MSGIOCTL_GENHWPVT: - return(genHwpvt(pparm)); - case MSGIOCTL_GENLINK: - return(genLink(pparm)); - case MSGIOCTL_CHECKEVENT: - return(checkEvent(pparm)); - case MSGIOCTL_COMMAND: - return(command(pparm)); - } - return(ERROR); -} - - -msgDrvBlock drvBBMsgBlock = { - "BBMSG", /* taskName */ - BBMSGLINK_PRI, /* taskPri */ - BBMSGLINK_OPT, /* taskOpt */ - BBMSGLINK_STACK, /* taskStack */ - NULL, /* pmsgLink (linked list header) */ - drvWrite, /* drvWrite */ - drvRead, /* drvRead */ - drvIoctl /* drvIoctl */ -}; diff --git a/src/drv/old/drvMsg.c b/src/drv/old/drvMsg.c deleted file mode 100644 index afd77d4aa..000000000 --- a/src/drv/old/drvMsg.c +++ /dev/null @@ -1,1422 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * Author: John Winans - * Date: 04-14-92 - * EPICS Generic message based I/O driver - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 04-14-92 jrw created - * .02 05-26-92 jrw changed enumeration of the record types - * .03 08-02-93 mrk Added call to taskwdInsert - * - */ - -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -int msgDebug = 0; - -#ifndef INVALID_ALARM -#define INVALID_ALARM VALID_ALARM -#endif - -static long drvMsg_write(), drvMsg_AiFmt(); -static long drvMsg_AoFmt(); -long drvMsg_proc(); -static long drvMsg_BiFmt(), drvMsg_BoFmt(), drvMsg_MiFmt(), drvMsg_MoFmt(); -static long drvMsg_LiFmt(), drvMsg_LoFmt(), drvMsg_SiFmt(), drvMsg_SoFmt(); -static long drvMsg_SiRaw(), drvMsg_SoRaw(); -static long drvMsg_CheckAck(); - -static void drvMsg_callbackFunc(); -static int msgTask(); - -static long (*(msgSupFun[]))() = { - NULL, /* MSG_OP_NOP */ - drvMsg_write, /* MSG_OP_WRITE */ - drvMsg_AiFmt, /* MSG_OP_FAI */ - drvMsg_AoFmt, /* MSG_OP_FAO */ - drvMsg_BiFmt, /* MSG_OP_FBI */ - drvMsg_BoFmt, /* MSG_OP_FBO */ - drvMsg_MiFmt, /* MSG_OP_FMI */ - drvMsg_MoFmt, /* MSG_OP_FMO */ - drvMsg_LiFmt, /* MSG_OP_FLI */ - drvMsg_LoFmt, /* MSG_OP_FLO */ - drvMsg_SiFmt, /* MSG_OP_FSI */ - drvMsg_SoFmt, /* MSG_OP_FSO */ - drvMsg_SiRaw, /* MSG_OP_RSI */ - drvMsg_SoRaw, /* MSG_OP_RSO */ - drvMsg_CheckAck /* MSG_OP_ACK */ -}; -#define NUM_VALID_OPS sizeof(msgSupFun)/sizeof(msgSupFun[0]) - -/****************************************************************************** - * - * These are the msgRecEnum structures that are used to define the - * types of records supported by the message based driver system. - * - * This list may be extended by the application developer in the device support - * module if necessary. - * - ******************************************************************************/ -msgRecEnum drvMsgAi = { "Analog In" }; -msgRecEnum drvMsgAo = { "Analog Out" }; -msgRecEnum drvMsgBi = { "Binary In" }; -msgRecEnum drvMsgBo = { "Binary Out" }; -msgRecEnum drvMsgMi = { "Multibit In" }; -msgRecEnum drvMsgMo = { "Multibit Out" }; -msgRecEnum drvMsgLi = { "Long In" }; -msgRecEnum drvMsgLo = { "Long Out" }; -msgRecEnum drvMsgSi = { "String In" }; -msgRecEnum drvMsgSo = { "String Out" }; -msgRecEnum drvMsgWf = { "Waveform" }; - -/****************************************************************************** - * - * Driver entry table for the message based I/O driver - * - ******************************************************************************/ -struct drvet drvMsg = { 2, drvMsg_reportMsg, drvMsg_initMsg }; - -/****************************************************************************** - * - ******************************************************************************/ -long -drvMsg_reportMsg(pdset) -msgDset *pdset; -{ - printf("Message driver report\n"); - - if (pdset->pparmBlock->pdrvBlock->drvIoctl != NULL) - return((*(pdset->pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_REPORT, NULL)); - - return(OK); -} - - -/****************************************************************************** - * - ******************************************************************************/ -long -drvMsg_initMsg(parm, pdset) -int parm; -msgDset *pdset; -{ - - msgDrvIniParm initParms; - - initParms.parm = parm; - initParms.pdset = pdset; - - if (msgDebug) - printf("Message init routine entered %d, %p\n", parm, pdset); - - if(pdset->pparmBlock->pdrvBlock->drvIoctl != NULL) - return((*(pdset->pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_INIT, &initParms)); - - return(OK); -} - -/****************************************************************************** - * - ******************************************************************************/ -int drvMsg_xactListAddHead(plist, pnode) -xactQueue *plist; -msgXact *pnode; -{ - pnode->prev = NULL; - pnode->next = plist->head; - - if (plist->head != NULL) - plist->head->prev = pnode; - - if (plist->tail == NULL) - plist->tail = pnode; - - plist->head = pnode; - - return(0); -} -/****************************************************************************** - * - ******************************************************************************/ -int drvMsg_xactListAddTail(plist, pnode) -xactQueue *plist; -msgXact *pnode; -{ - pnode->next = NULL; /* No next node if this is the TAIL */ - pnode->prev = plist->tail; /* previous node is the 'old' TAIL node */ - - if (plist->tail != NULL) - plist->tail->next = pnode; /* link the 'old' tail to the 'new' tail node */ - - if (plist->head == NULL) - plist->head = pnode; - - plist->tail = pnode; /* this is the 'new' tail node */ - - return(0); -} -/****************************************************************************** - * - ******************************************************************************/ -int drvMsg_xactListDel(plist, pnode) -xactQueue *plist; -msgXact *pnode; -{ - if (pnode->next != NULL) - pnode->next->prev = pnode->prev; - - if (pnode->prev != NULL) - pnode->prev->next = pnode->next; - - if (plist->head == pnode) - plist->head = pnode->next; - - if (plist->tail == pnode) - plist->tail = pnode->prev; - - return(0); -} - -/****************************************************************************** - * - * Generate a transaction structure and initialize it. - * - ******************************************************************************/ -msgXact * -drvMsg_genXact(pparmBlock, plink, prec) -msgParmBlock *pparmBlock; -struct link *plink; /* I/O link structure from record */ -struct dbCommon *prec; -{ - msgXact *pmsgXact; - msgDrvGenXParm genXactParm; - char message[200]; - - /* allocate and fill in msg specific part */ - if ((pmsgXact = malloc(sizeof (msgXact))) == NULL) - { - sprintf(message, "drvMsg_genXact:%s out of memory\n", prec->name); - errMessage(S_db_badField, message); - return(NULL); - } - pmsgXact->pparmBlock = pparmBlock; - pmsgXact->prec = prec; - - genXactParm.plink = plink; - genXactParm.pmsgXact = pmsgXact; - - /* fill in communication-link specific portion and phwpvt */ - if ((*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENXACT, &genXactParm) == ERROR) - { - /* free-up the xact structure and clean up */ - - /* errMessage() */ - printf("(Message driver): An error occurred while initializing %s\n", prec->name); - return(NULL); - } - /* Verify that the parm number is within range */ - if (pmsgXact->parm >= pparmBlock->numCmds) - { - sprintf(message, "(Message driver) %s parm number %d invalid\n", prec->name, pmsgXact->parm); - errMessage(S_db_badField, message); - return(NULL); - } - - /* Make a simple check to see if the parm entry makes sense */ - if ((pparmBlock->pcmds[pmsgXact->parm].flags & READ_DEFER) && (pparmBlock->pcmds[pmsgXact->parm].readOp.p == NULL)) - { - sprintf(message, "(Message driver) %s parm number %d specifies a deferred read, but no read operation\n", prec->name, pmsgXact->parm); - errMessage(S_db_badField, message); - return(NULL); - } - return(pmsgXact); -} - -/****************************************************************************** - * - * Generate a hardware private structure and initialize it. - * This is called by pparmBlock->pdrvBlock->drvIoctl(MSGIOCTL_GENXACT) when it - * finds that a hardware private structure is not present when a transaction - * structure is being initialized for it. - * - ******************************************************************************/ -msgHwpvt * -drvMsg_genHwpvt(pparmBlock, plink) -msgParmBlock *pparmBlock; -struct link *plink; /* I/O link structure from record */ -{ - msgHwpvt *pmsgHwpvt; - msgDrvGenHParm genHParms; - - if (msgDebug) - printf("In drvMsg_genHwpvt\n"); - - /* allocate and fill in msg specific part */ - if((pmsgHwpvt = malloc(sizeof(msgHwpvt))) == NULL) - return(NULL); - - /* Link it into the msgParmBlock list */ - pmsgHwpvt->next = pparmBlock->pmsgHwpvt; - pparmBlock->pmsgHwpvt = pmsgHwpvt; - - pmsgHwpvt->tmoVal = 0; - pmsgHwpvt->tmoCount = 0; - - genHParms.pparmBlock = pparmBlock; - genHParms.plink = plink; - genHParms.pmsgHwpvt = pmsgHwpvt; - - if ((*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENHWPVT, &genHParms) == ERROR) - { - /* Free up the hardware private structure and clean up */ - /* It is still first on the list, so don't have to look for it */ - return(NULL); - } - - return(pmsgHwpvt); -} - -/****************************************************************************** - * - * Generate a message queue link structure and start a task to manage it. - * This is called by pparmBlock->pdrvBlock->drvIoctl(MSGIOCTL_GENHWPVT) when - * it finds that a specific link structure is not present that is needed when - * initializing a hardware private structure. - * - ******************************************************************************/ -msgLink * -drvMsg_genLink(pparmBlock, plink) -msgParmBlock *pparmBlock; -struct link *plink; /* I/O link structure from record */ -{ - msgDrvGenLParm genlParms; - msgLink *pmsgLink; - char name[20]; - long status; - int j; - int taskId; - - if (msgDebug) - printf("In drvMsg_genLink\n"); - - /* Allocate and fill in the msg specific part */ - if ((pmsgLink = malloc(sizeof(msgLink))) == NULL) - return(NULL); - - /* init all the prioritized transaction queues */ - for(j=0; jqueue[j].head = NULL; - pmsgLink->queue[j].tail = NULL; - FASTLOCKINIT(&(pmsgLink->queue[j].lock)); - } - pmsgLink->linkEventSem = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY); - - genlParms.pmsgLink = pmsgLink; - genlParms.plink = plink; - genlParms.op = MSG_GENLINK_CREATE; - genlParms.pparmBlock = pparmBlock; - - /* do the driver-specific init */ - if ((*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENLINK, &genlParms) == ERROR) - { - /* free the pmsgLink structure and clean up */ - return(NULL); - } - sprintf(name, "%s", pparmBlock->pdrvBlock->taskName); - if ((taskId = taskSpawn(name, pparmBlock->pdrvBlock->taskPri, pparmBlock->pdrvBlock->taskOpt, pparmBlock->pdrvBlock->taskStack, msgTask, pparmBlock->pdrvBlock, pmsgLink)) == ERROR) - { - printf("Message driver: Failed to start link task %s\n", name); -/* BUG --delete the FASTLOCK in here */ - status = ERROR; - } else { - taskwdInsert(taskId,NULL,NULL); - status = OK; - } - - if (status == ERROR) - { - genlParms.op = MSG_GENLINK_ABORT; - - (*(pparmBlock->pdrvBlock->drvIoctl))(MSGIOCTL_GENLINK, &genlParms); - free(pmsgLink); - return(NULL); - } - return(pmsgLink); -} - -/****************************************************************************** - * - * Check to verify that a given parameter number is within range for the - * given device type. - * - ******************************************************************************/ -long -drvMsg_checkParm(prec, recTyp) -struct dbCommon *prec; -char *recTyp; -{ - unsigned int parm; - char message[100]; - - if (prec->dpvt != NULL) - { - parm = ((msgXact *)(prec->dpvt))->parm; - if ((((msgXact *)(prec->dpvt))->pparmBlock->pcmds)[parm].recTyp != ((struct msgDset *)(prec->dset))->precEnum) - { - sprintf(message, "Message driver-checkParm: %s parm number %d not valid for %s record type\n", prec->name, parm, recTyp); - errMessage(S_db_badField, message); - prec->pact = TRUE; - return(S_db_badField); - } - return(0); - } - return(S_db_badField); -} - -/****************************************************************************** - * - * Callback function used to complete async-record processing. - * - ******************************************************************************/ -static void -drvMsg_callbackFunc(pcallback) -CALLBACK *pcallback; -{ - dbScanLock(((msgXact *)(pcallback->user))->prec); - (*(struct rset *)(((msgXact *)(pcallback->user))->prec->rset)).process(((msgXact *)(pcallback->user))->prec); - dbScanUnlock(((msgXact *)(pcallback->user))->prec); -} - -/****************************************************************************** - * - * Function used to initialize the callback structure within the transaction - * structure. This sets it up so that it is used to perform the completion - * phase of the async record processing. - * - ******************************************************************************/ -long -drvMsg_initCallback(prec) -struct dbCommon *prec; -{ - ((msgXact *)(prec->dpvt))->callback.callback = drvMsg_callbackFunc; - /* ((msgXact *)(prec->dpvt))->callback.priority = prec->prio; */ - ((msgXact *)(prec->dpvt))->callback.user = (void *)(prec->dpvt); - - return(OK); -} - -/****************************************************************************** - * - * Queue a transaction for the link task. - * - ******************************************************************************/ -long -drvMsg_qXact(xact, prio) -msgXact *xact; -int prio; -{ - msgLink *pmsgLink = xact->phwpvt->pmsgLink; - - /* The link verification is done at record-init time & not needed here. */ - - if ((prio < 0) || (prio >= NUM_CALLBACK_PRIORITIES)) - { - xact->status = XACT_BADPRIO; - return(ERROR); - } - - xact->callback.priority = prio; /* Callback processing priority */ - - FASTLOCK(&(pmsgLink->queue[prio].lock)); - drvMsg_xactListAddTail(&(pmsgLink->queue[prio]), xact); - FASTUNLOCK(&(pmsgLink->queue[prio].lock)); - semGive(pmsgLink->linkEventSem); - - return(OK); -} - -/****************************************************************************** - * - * Message-driver link-task. - * - * This function is spawned as a task during iocInit(). It waits on a semaphore - * that is given when either a message (transaction) is queued for a device - * associated with the link, or an event of some kind was detected from a device - * associated with the link. - * - * When the task wakes up, it checks to see if it was due to an event. If so, - * the support function that identified the event will also specify a - * transaction structure to process. If no event occurred, then the - * transaction request queues are checked. - * - * If a transaction was found, either due to an event or the work queues, it - * is processed. Processing a transaction consists of two optional phases. - * These phases are called the write and read phases, but either of them - * may do either writing, reading, or nothing. In the typical case, the - * first phase will do some writing (either setting a condition or soliciting a - * response) and the second phase will do some reading (reading back a solicited - * response) or nothing (in cases where no response will be generated to some - * write command.) - * - ******************************************************************************/ -static int msgTask(pdrvBlock, pmsgLink) -msgDrvBlock *pdrvBlock; -msgLink *pmsgLink; -{ - int working; - int prio; - msgXact *xact; - int event; - msgCmd *pmsgCmd; - msgChkEParm checkEventParms; - - if (msgDebug) - printf("Message driver link task %s started\n", pdrvBlock->taskName); - - checkEventParms.pdrvBlock = pdrvBlock; - checkEventParms.pmsgLink = pmsgLink; - checkEventParms.pxact = &xact; - - working = 1; /* Force a first time check on events and xact queues */ - - while (1) - { - if (!working) - semTake(pmsgLink->linkEventSem, WAIT_FOREVER); - - working = 0; - xact = NULL; - - /* Check to see if we woke up because of a device event */ - event = (*(pdrvBlock->drvIoctl))(MSGIOCTL_CHECKEVENT, &checkEventParms); - - if (event == MSG_EVENT_NONE) - { /* No device events pending, check the request queues for work */ - prio = 0; - while ((xact == NULL) && prio < NUM_CALLBACK_PRIORITIES) - { - FASTLOCK(&(pmsgLink->queue[prio].lock)); - if ((xact = pmsgLink->queue[prio].head) != NULL) - { - drvMsg_xactListDel(&(pmsgLink->queue[prio]), xact); - FASTUNLOCK(&(pmsgLink->queue[prio].lock)); - } - else - FASTUNLOCK(&(pmsgLink->queue[prio].lock)); - - prio++; - } - } - if (xact != NULL) - { - working = 1; - xact->status = XACT_OK; /* All well, so far */ - pmsgCmd = &(xact->pparmBlock->pcmds[xact->parm]); - - if ((pmsgCmd->writeOp.op != MSG_OP_NOP) && ((event == MSG_EVENT_NONE)||(event & MSG_EVENT_WRITE))) - { /* Perform the write portion of a transaction operation */ - (*(xact->pparmBlock->doOp))(xact, &(pmsgCmd->writeOp)); - } - - if ((xact->status == XACT_OK) && (pmsgCmd->readOp.op != MSG_OP_NOP)) - { /* There is a read opertaion spec'd, check to see if I can do it now */ - if (((pmsgCmd->flags & READ_DEFER) == 0)||(event & MSG_EVENT_READ)) - { /* Not a deferred readback parm -or- it is and is time to read */ - (*(xact->pparmBlock->doOp))(xact, &(pmsgCmd->readOp)); - - if (xact->callback.callback != NULL) - callbackRequest(xact); - - if (xact->psyncSem != NULL) - semGive(*(xact->psyncSem)); - } - /* else -- is a defered readback, must wait for readback event */ - } - else - { /* There is no read operation specified, finish the xact opetation */ - if (xact->callback.callback != NULL) - callbackRequest(xact); - - if (xact->psyncSem != NULL) - semGive(*(xact->psyncSem)); - } - } - } -} - -/****************************************************************************** - * - * These functions encapsulates the calls made to the device-specific read and - * write functions. The idea here is that we can monitor and/or buffer I/O - * operations from here. - * - * At the moment, this is used to do cehcks on the read-cache's time-to-live. - * - ******************************************************************************/ -long -drvMsg_drvWrite(pxact, pparm) -msgXact *pxact; -msgStrParm *pparm; -{ - return(pxact->pparmBlock->pdrvBlock->drvWrite(pxact, pparm)); -} - -/****************************************************************************** - * - ******************************************************************************/ -long -drvMsg_drvRead(pxact, pparm) -msgXact *pxact; -msgStrParm *pparm; -{ - return((*(pxact->pparmBlock->pdrvBlock->drvRead))(pxact, pparm)); -} - -/****************************************************************************** - * - * This function is called to handle the processing of a transaction. - * The idea here is that xact->pparmBlock->doOp could point to this - * function if there are not any custom operations, or to it's own - * function that could check to see if the operation is local/custom and - * then call this if it is not. - * - ******************************************************************************/ -long -drvMsg_xactWork(pxact, pop) -msgXact *pxact; -msgCmdOp *pop; -{ - if ((pop->op > 0) && (pop->op < NUM_VALID_OPS)) - return((*(msgSupFun[pop->op]))(pxact, pop->p)); - - printf("drvMsg_xactWork: Invalid operation code %d encountered\n", pop->op); - pxact->status = XACT_BADCMD; - return(XACT_BADCMD); -} - -/****************************************************************************** - * - * Write a string to the device w/o any formatting. - * - ******************************************************************************/ -static long -drvMsg_write(pxact, pparm) -msgXact *pxact; -msgStrParm *pparm; -{ - return(drvMsg_drvWrite(pxact, pparm)); -} - -/****************************************************************************** - * - * Read a string and see if it contains the substring provided in the - * msgAkParm structure. This is useful to check the ack string from a - * device because it will cause the record to go into a INVALID alarm - * state if the ACK does not match the provided string. - * - * If the provided substring is a zero-length string, it will match - * any possible ACK string. - * - ******************************************************************************/ -static long -drvMsg_CheckAck(pxact, packParm) -msgXact *pxact; -msgAkParm *packParm; -{ - msgStrParm strParm; -/* BUG -- the buffer size will have to be configurable */ - char buf[100]; - char *ach; - char *rch; - - strParm.buf = buf; - strParm.len = packParm->len; - - drvMsg_drvRead(pxact, &strParm); - if (msgDebug > 5) - printf("drvMsg_CheckAck comparing >%s< at %d against >%s<\n", buf, packParm->index, packParm->str); - - if (pxact->status == XACT_OK) - { - ach = &(packParm->str[packParm->index]); - rch = buf; - while (*ach != '\0') - { - if (*ach != *rch) - { - *ach = '\0'; /* stop the while loop */ - pxact->status = XACT_IOERR; - } - else - { - ach++; - rch++; - } - } - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - ******************************************************************************/ -static long -drvMsg_AiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct aiRecord *)(pxact->prec))->val)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - * NOTE: The rval is filled in for the BI record so that conversion may - * take place in record support. - * - ******************************************************************************/ -static long -drvMsg_BiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct biRecord *)(pxact->prec))->rval)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - * NOTE: The rval is filled in for the MBBI record so that conversion may - * take place in record support. - * - ******************************************************************************/ -static long -drvMsg_MiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct mbbiRecord *)(pxact->prec))->rval)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - ******************************************************************************/ -static long -drvMsg_LiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), &(((struct longinRecord *)(pxact->prec))->val)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string and use the format string to extract the value field - * - ******************************************************************************/ -static long -drvMsg_SiFmt(pxact, pfiParm) -msgXact *pxact; -msgFiParm *pfiParm; -{ - msgStrParm strParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - strParm.buf = buf; - strParm.len = pfiParm->len; - - drvMsg_drvRead(pxact, &strParm); - - if (pxact->status == XACT_OK) - { - if (sscanf(buf, &(pfiParm->format[pfiParm->startLoc]), (((struct stringinRecord *)(pxact->prec))->val)) != 1) - pxact->status = XACT_IOERR; - } - return(pxact->status); -} - -/****************************************************************************** - * - * Read a string - * - ******************************************************************************/ -static long -drvMsg_SiRaw(pxact, parm) -msgXact *pxact; -void *parm; -{ - msgStrParm strParm; - - strParm.buf = ((struct stringinRecord *)(pxact->prec))->val; - strParm.len = sizeof(((struct stringinRecord *)(pxact->prec))->val); - - drvMsg_drvRead(pxact, &strParm); - - return(pxact->status); -} - -/****************************************************************************** - * - * This function is used to write a string that includes the VAL field of an - * analog output record, to an RS-232 device. - * - ******************************************************************************/ -static long -drvMsg_AoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; -/* BUG -- some how the buffer length will have to be made configurable */ - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct aoRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_BoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct boRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -/****************************************************************************** - * - * NOTE: The formatting of the MBBO value uses the RVAL field so that the - * conversion from VAL to RVAL in the record (the movement of one of the - * onvl, twvl,... fields to the rval field during record processing.) - * - ******************************************************************************/ -static long -drvMsg_MoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct mbboRecord *)(pxact->prec))->rval); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_LoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct longoutRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_SoFmt(pxact, pfoParm) -msgXact *pxact; -msgFoParm *pfoParm; -{ - msgStrParm wrParm; - char buf[100]; - - wrParm.buf = buf; - - sprintf(buf, pfoParm->format, ((struct stringoutRecord *)(pxact->prec))->val); - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -static long -drvMsg_SoRaw(pxact, parm) -msgXact *pxact; -void *parm; -{ - msgStrParm wrParm; - - wrParm.buf = ((struct stringoutRecord *)(pxact->prec))->val; - wrParm.len = -1; /* write until reach NULL character */ - - drvMsg_drvWrite(pxact, &wrParm); - return(pxact->status); -} - -/****************************************************************************** - * - * The following functions are called from record support. - * They are used to initialize a record's DPVT (xact structure) for - * processing by the message driver later when the record is processed. - * - ******************************************************************************/ -/****************************************************************************** - * - * Init record routine for AI - * - ******************************************************************************/ -long -drvMsg_initAi(pai) -struct aiRecord *pai; -{ - long status; - - pai->dpvt = drvMsg_genXact(((struct msgDset *)(pai->dset))->pparmBlock, &(pai->inp), pai); - - if (pai->dpvt != NULL) - { - status = drvMsg_checkParm(pai, "AI"); - if (status == 0) - drvMsg_initCallback(pai); /* Init for async record completion callback */ - else - pai->pact = 1; /* mark so is never scanned */ - - return(status); - } - pai->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * Init record routine for AO - * - ******************************************************************************/ -long -drvMsg_initAo(pao) -struct aoRecord *pao; -{ - long status; - - pao->dpvt = drvMsg_genXact(((struct msgDset *)(pao->dset))->pparmBlock, &(pao->out), pao); - - if (pao->dpvt != NULL) - { - status = drvMsg_checkParm(pao, "AO"); - if (status == 0) - { - drvMsg_initCallback(pao); /* Init for async record completion callback */ - return(2); /* Don't convert RVAL to VAL at this time */ - } - else - pao->pact = 1; /* mark so is never scanned */ - - return(status); - } - pao->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for BI - * - ******************************************************************************/ -long -drvMsg_initBi(pbi) -struct biRecord *pbi; -{ - long status; - - pbi->dpvt = drvMsg_genXact(((struct msgDset *)(pbi->dset))->pparmBlock, &(pbi->inp), pbi); - - if (pbi->dpvt != NULL) - { - status = drvMsg_checkParm(pbi, "BI"); - if (status == 0) - drvMsg_initCallback(pbi); /* Init for async record completion callback */ - else - pbi->pact = 1; /* mark so is never scanned */ - - return(status); - } - pbi->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * Init record routine for BO - * - ******************************************************************************/ -long -drvMsg_initBo(pbo) -struct boRecord *pbo; -{ - long status; - - pbo->dpvt = drvMsg_genXact(((struct msgDset *)(pbo->dset))->pparmBlock, &(pbo->out), pbo); - - if (pbo->dpvt != NULL) - { - status = drvMsg_checkParm(pbo, "BO"); - if (status == 0) - { - drvMsg_initCallback(pbo); /* Init for async record completion callback */ - return(2); /* Don't convert RVAL to VAL at this time */ - } - else - pbo->pact = 1; /* mark so is never scanned */ - - return(status); - } - pbo->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for MI - * - ******************************************************************************/ -long -drvMsg_initMi(pmi) -struct mbbiRecord *pmi; -{ - long status; - - pmi->dpvt = drvMsg_genXact(((struct msgDset *)(pmi->dset))->pparmBlock, &(pmi->inp), pmi); - - if (pmi->dpvt != NULL) - { - status = drvMsg_checkParm(pmi, "MBBI"); - if (status == 0) - drvMsg_initCallback(pmi); /* Init for async record completion callback */ - else - pmi->pact = 1; /* mark so is never scanned */ - - return(status); - } - pmi->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * Init record routine for MO - * - ******************************************************************************/ -long -drvMsg_initMo(pmo) -struct mbboRecord *pmo; -{ - long status; - - pmo->dpvt = drvMsg_genXact(((struct msgDset *)(pmo->dset))->pparmBlock, &(pmo->out), pmo); - - if (pmo->dpvt != NULL) - { - status = drvMsg_checkParm(pmo, "MBBO"); - if (status == 0) - { - drvMsg_initCallback(pmo); /* Init for async record completion callback */ - return(2); /* Don't convert RVAL to VAL at this time */ - } - else - pmo->pact = 1; /* mark so is never scanned */ - - return(status); - } - pmo->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for LI - * - ******************************************************************************/ -long -drvMsg_initLi(pli) -struct longinRecord *pli; -{ - long status; - - pli->dpvt = drvMsg_genXact(((struct msgDset *)(pli->dset))->pparmBlock, &(pli->inp), pli); - - if (pli->dpvt != NULL) - { - status = drvMsg_checkParm(pli, "LI"); - if (status == 0) - drvMsg_initCallback(pli); /* Init for async record completion callback */ - else - pli->pact = 1; /* mark so is never scanned */ - - return(status); - } - pli->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * init record routine for LO - * - ******************************************************************************/ -long -drvMsg_initLo(plo) -struct longoutRecord *plo; -{ - long status; - - plo->dpvt = drvMsg_genXact(((struct msgDset *)(plo->dset))->pparmBlock, &(plo->out), plo); - - if (plo->dpvt != NULL) - { - status = drvMsg_checkParm(plo, "LO"); - if (status == 0) - drvMsg_initCallback(plo); /* Init for async record completion callback */ - else - plo->pact = 1; /* mark so is never scanned */ - - return(status); - } - plo->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for SI - * - ******************************************************************************/ -long -drvMsg_initSi(psi) -struct stringinRecord *psi; -{ - long status; - - psi->dpvt = drvMsg_genXact(((struct msgDset *)(psi->dset))->pparmBlock, &(psi->inp), psi); - - if (psi->dpvt != NULL) - { - status = drvMsg_checkParm(psi, "SI"); - if (status == 0) - drvMsg_initCallback(psi); /* Init for async record completion callback */ - else - psi->pact = 1; /* mark so is never scanned */ - - return(status); - } - psi->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} -/****************************************************************************** - * - * init record routine for SO - * - ******************************************************************************/ -long -drvMsg_initSo(pso) -struct stringoutRecord *pso; -{ - long status; - - pso->dpvt = drvMsg_genXact(((struct msgDset *)(pso->dset))->pparmBlock, &(pso->out), pso); - - if (pso->dpvt != NULL) - { - status = drvMsg_checkParm(pso, "SI"); - if (status == 0) - drvMsg_initCallback(pso); /* Init for async record completion callback */ - else - pso->pact = 1; /* mark so is never scanned */ - - return(status); - } - pso->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * init record routine for WF - * - ******************************************************************************/ -long -drvMsg_initWf(pwf) -struct waveformRecord *pwf; -{ - long status; - - pwf->dpvt = drvMsg_genXact(((struct msgDset *)(pwf->dset))->pparmBlock, &(pwf->inp), pwf); - - if (pwf->dpvt != NULL) - { - status = drvMsg_checkParm(pwf, "WAVEFORM"); - if (status == 0) - drvMsg_initCallback(pwf); /* Init for async record completion callback */ - else - pwf->pact = 1; /* mark so is never scanned */ - - return(status); - } - pwf->pact = 1; /* mark so is never scanned */ - return(S_db_badField); -} - -/****************************************************************************** - * - * These functions are called by record support. - * - * Service routines to process a input records. - * - ******************************************************************************/ -long -drvMsg_procAi(pai) -struct aiRecord *pai; -{ - return(drvMsg_proc(pai, 2)); /* no conversion */ -} -long -drvMsg_procBi(pbi) -struct biRecord *pbi; -{ - return(drvMsg_proc(pbi, 0)); /* convert RVAL to VAL */ -} -long -drvMsg_procMi(pmi) -struct mbbiRecord *pmi; -{ - return(drvMsg_proc(pmi, 0)); /* convert RVAL to VAL */ -} -long -drvMsg_procLi(pli) -struct longinRecord *pli; -{ - return(drvMsg_proc(pli, 2)); /* no conversion */ -} -long -drvMsg_procSi(psi) -struct stringinRecord *psi; -{ - return(drvMsg_proc(psi, 2)); /* no conversion */ -} -long -drvMsg_procWf(pwf) -struct waveformRecord *pwf; -{ - return(drvMsg_proc(pwf, 2)); /* no conversion */ -} - -/****************************************************************************** - * - * These functions are called by record support. - * - * Service routine to process output records. - * - * It does not make sense to return a conversion code to record support from - * processing an output record. - * - ******************************************************************************/ -long -drvMsg_procAo(pao) -struct aoRecord *pao; -{ - return(drvMsg_proc(pao, 0)); -} -long -drvMsg_procBo(pbo) -struct boRecord *pbo; -{ - return(drvMsg_proc(pbo, 0)); -} -long -drvMsg_procMo(pmo) -struct mbboRecord *pmo; -{ - return(drvMsg_proc(pmo, 0)); -} -long -drvMsg_procLo(plo) -struct longoutRecord *plo; -{ - return(drvMsg_proc(plo, 0)); -} -long -drvMsg_procSo(pso) -struct stringoutRecord *pso; -{ - return(drvMsg_proc(pso, 0)); -} - -/****************************************************************************** - * - * Generic service routine to process a record. - * - ******************************************************************************/ - -/* - * BUG -- I should probably figure out the return code from the conversion - * routine. Not from a hard-coded value passed in from above. - */ - -long -drvMsg_proc(prec, ret) -struct dbCommon *prec; /* record to process */ -int ret; /* If all goes well, return this value */ -{ - if (prec->pact) /* if already actively processing, finish up */ - { - if (((msgXact *)(prec->dpvt))->status != XACT_OK) - { /* something went wrong during I/O processing */ - if (msgDebug) - printf("Setting an alarm on record %s\n", prec->name); - - recGblSetSevr(prec, READ_ALARM, INVALID_ALARM); - } - else - if (ret == 2) - prec->udf = FALSE; /* Set only if I return 2 (I filled in VAL) */ - - return(ret); - } - /* Not already actively processing, start things going */ - - prec->pact = TRUE; - if (drvMsg_qXact(prec->dpvt, prec->prio) == ERROR) - printf("Error during drvMsg_qXact\n"); - - return(ret); -} diff --git a/src/drv/old/drvMsg.h b/src/drv/old/drvMsg.h deleted file mode 100644 index c2c66a69b..000000000 --- a/src/drv/old/drvMsg.h +++ /dev/null @@ -1,485 +0,0 @@ -/* share/epicsH $Id$ */ -/* - * Author: John Winans - * Date: 11-19-91 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1988, 1989, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * All rights reserved. No part of this publication may be reproduced, - * stored in a retrieval system, transmitted, in any form or by any - * means, electronic, mechanical, photocopying, recording, or otherwise - * without prior written permission of Los Alamos National Laboratory - * and Argonne National Laboratory. - * - * Modification Log: - * ----------------- - * .02 05-26-92 jrw added enumeration of record types - * .03 08-10-92 jrw cleaned up the documentation - * & removed multi-parm stuff - */ - -#ifndef DEVXXMSG_H -#define DEVXXMSG_H -/****************************************************************************** - * - * This structure holds device-related data on a per-device basis and is - * referenced by the xact structures. They are built using a linked - * list starting from parmBlock.phwpvt. There is one linked list for each - * specific device type. - * - * Different types of device links could have different formatted hwpvt structs. - * The msgHwpvt structure includes those fields that are common to all device - * types. The customized part should be attached to msgHwpvt.p during the - * genHwpvt phase if the initilization process. - * - ******************************************************************************/ -struct msgHwpvt { - struct msgHwpvt *next; /* Next structure for same type device */ - - struct msgLink *pmsgLink; /* Associated link structure */ - - unsigned long tmoVal; /* Time last timeout occurred */ - unsigned long tmoCount; /* Total timeouts since boot time */ - - void *p; /* Place to add device-specific fields */ -}; -typedef struct msgHwpvt msgHwpvt; -/****************************************************************************** - * - * Any I/O request made must consist of the msgXact structure defined below. - * - * In general, one EPICS database record will have one and only one of these - * msgXact attached to it's dbCommon.dpvt field. - * - * The message driver system does not reference any database record fields that - * are not in dbCommon -- unless a user-provided function calls a - * record-specific support function. - * - ******************************************************************************/ -struct msgXact { - CALLBACK callback; - SEM_ID *psyncSem; /* if not NULL, points to sem given w/RX */ - - struct msgXact *next; /* used to link dpvt's together */ - struct msgXact *prev; /* used to link dpvt's together */ - - struct msgHwpvt *phwpvt; /* assoc'd hwpvt structure */ - struct msgParmBlock *pparmBlock; /* assoc'd parm block */ - struct dbCommon *prec; /* useful to msg based device support */ - unsigned int parm; /* operation parm number */ - int status; /* transaction completion status */ - - void *p; /* A place to add on device specific data */ -}; -typedef struct msgXact msgXact; -/****************************************************************************** - * - * Valid msgXact.status values are: - * - ******************************************************************************/ -#define XACT_OK 0 /* all went as expected */ -#define XACT_LENGTH 1 /* received message overflowed the buffer */ -#define XACT_TIMEOUT 3 /* response took too long from node */ -#define XACT_BADLINK 4 /* request sent to an invalid link number */ -#define XACT_BADPRIO 5 /* request had bad queueing priority */ -#define XACT_IOERR 6 /* some sort of I/O error occurred */ -#define XACT_BADCMD 7 /* bad command ID-number */ - -/****************************************************************************** - * - * Transaction requests are placed on queues (by the drvMsg_qXact() function) - * when submitted. These queues are described with the xactQueue structure. - * - ******************************************************************************/ -struct xactQueue { - struct msgXact *head; /* head of the linked list */ - struct msgXact *tail; /* tail of the linked list */ - FAST_LOCK lock; /* semaphore for the queue list */ -}; -typedef struct xactQueue xactQueue; -/****************************************************************************** - * - * A task is started to manage each message based link. It uses the msgLink - * structure to access the queues of work. - * - * A link is defined by the device-specific part of the genHwpvt() function. - * A link task will be started if the genHwpvt() function invokes the genLink() - * function to define a new link. - * - ******************************************************************************/ -struct msgLink{ - struct xactQueue queue[NUM_CALLBACK_PRIORITIES]; /* prioritized request queues */ - struct msgLink *next; /* next in msgDrvBlock list */ - SEM_ID linkEventSem; - void *p; /* A place to add on device specific data */ -}; -typedef struct msgLink msgLink; -/****************************************************************************** - * - * The msgParmBlock is defined by the user-contributed device support module. - * It is used to tell the message-driver what device driver to used to perform - * the I/O operations as well as to provide access to the command table, and - * other parameters. - * - * The msgParmBlock contains those parts that are common to all device types. - * Some devices may require more operating parameters. These additional - * parameters should be added via msgParmBlock.p. - * - ******************************************************************************/ -struct msgParmBlock{ - int *debugFlag; /* pointer to debug flag */ - struct msgHwpvt *pmsgHwpvt; /* pointer to the hwpvt list for device type */ - struct msgCmd *pcmds; /* pointer to command list */ - int numCmds; /* number of elements in the command list */ - char *name; /* pointer to a string containing device name */ - struct msgDrvBlock *pdrvBlock; /* link to the driver hook data structure */ - DRVSUPFUN doOp; /* user spec'd operation wedge function */ - void *p; /* A place to add device specific data */ -}; -typedef struct msgParmBlock msgParmBlock; - -/****************************************************************************** - * - * The msgCmd structure is used to define each entry in the command table. - * This table is used to define all the commands that a specific device type - * can handle. - * - * When a transaction is processed, the following happens: - * - * 1) if A defered read event has occurred, cmd.readOp is called. - * otherwise: - * 1) if cmd.writeOp is non-NULL, it is called and passed wrParm - * The job of writeOp is to send a string to the instrument - * 2) if cmd.readOp is non-NULL, it is called and passed rdParm - * The job of readOp is to read a string from the instrument - * - ******************************************************************************/ -struct msgCmdOp { - unsigned int op; - void *p; -}; -typedef struct msgCmdOp msgCmdOp; - -struct msgCmd{ - struct msgRecEnum *recTyp;/* used to indicate record type supported */ - unsigned int flags; /* 1 if readback is deferred, 0 if not */ - - struct msgCmdOp writeOp; - struct msgCmdOp readOp; - - struct devMsgNames *namelist;/* pointer to name strings */ - int companion; -}; -typedef struct msgCmd msgCmd; - -/* Possible values for msgCmd.flags (OR the set required together) */ -#define READ_NDLY 0 /* Do read now */ -#define READ_DEFER 1 /* Defer read, an event will signal it */ - -/****************************************************************************** - * - * Valid writeOp and readOp values. - * - * Any user-add-on codes start at MSG_OP_USER and continue upward. - * - ******************************************************************************/ -#define MSG_OP_NOP 0 /* Do nothing */ -#define MSG_OP_WRITE 1 /* Unformatted character write */ - -#define MSG_OP_FAI 2 /* Read and parse an analog input */ -#define MSG_OP_FAO 3 /* Format and output an analog output */ -#define MSG_OP_FBI 4 /* Read and parse */ -#define MSG_OP_FBO 5 /* Format and output */ -#define MSG_OP_FMI 6 /* Read and parse */ -#define MSG_OP_FMO 7 /* Format and output */ -#define MSG_OP_FLI 8 /* Read and parse */ -#define MSG_OP_FLO 9 /* Format and output */ -#define MSG_OP_FSI 10 /* Read and parse */ -#define MSG_OP_FSO 11 /* Format and output */ - -#define MSG_OP_RSI 12 /* Read a string raw */ -#define MSG_OP_RSO 13 /* Write a string raw */ - -#define MSG_OP_ACK 14 /* Read string and set alarm if not match */ - -#define MSG_OP_SBI 15 /* Read string, set BI on substring comparison */ - -/* NOT CURRENTLY SUPPORTED OPERATIONS */ -#if FALSE -#define MSG_OP_EBI /* enumerated operations */ -#define MSG_OP_EBO -#define MSG_OP_EMI -#define MSG_OP_EMO -#endif - -#define MSG_OP_USER 200 /* Start of user added operation codes */ - -/****************************************************************************** - * - * The following represent the op-codes that can be passed to the - * msgDrvBlock.genlink function. - * - ******************************************************************************/ -#define MSG_GENLINK_CREATE 0 /* Create structures for a new link */ -#define MSG_GENLINK_ABORT 1 /* Link failed init */ - -/****************************************************************************** - * - * Codes that can be returned from event checker routines. - * - ******************************************************************************/ -#define MSG_EVENT_NONE 0 -#define MSG_EVENT_READ 1 -#define MSG_EVENT_WRITE 2 - -/****************************************************************************** - * - * This is used to define the strings that are used for button labels. - * These strings are put into the record's znam & onam foelds if the - * record is a BI or BO type and into the zrst, onst... fields of an - * MBBI or MBBO record. - * - * Before these strings are placed into the record, the record is - * check to see if there is already a string defined (could be user-entered - * with DCT.) If there is already a string present, it will be preserved. - * - * There MUST ALWAYS be 2 and only 2 entries in the names.item list - * for BI and BO records if a name list is being specified for them here. - * The names.count field is ignored for BI and BO record types, but - * should be properly specified as 2 for future compatibility. - * - * NOTE: - * If a name string is filled in an an MBBI/MBBO record, it's corresponding - * value will be filled in as well. For this reason, there MUST be - * a value array and a valid nobt value for every MBBI/MBBO record that - * contains an item array! - * - ******************************************************************************/ - -struct drvMsgNames { - int count; /* CURRENTLY only used for MBBI and MBBO */ - char **item; - unsigned long *value; /* CURRENTLY only used for MBBI and MBBO */ - short nobt; /* CURRENTLY only used for MBBI and MBBO */ -}; -typedef struct drvMsgNames drvMsgNames; -/****************************************************************************** - * - * Public functions available from the message driver. - * - ******************************************************************************/ -msgXact *drvMsg_genXact(); -msgHwpvt *drvMsg_genHwpvt(); -msgLink *drvMsg_genLink(); -long drvMsg_qXact(); -long drvMsg_reportMsg(); -long drvMsg_initMsg(); -long drvMsg_xactWork(); -long drvMsg_initCallback(); -long drvMsg_checkParm(); -long drvMsg_drvWrite(); -long drvMsg_drvRead(); - -long drvMsg_initAi(), drvMsg_initAo(); -long drvMsg_initBi(), drvMsg_initBo(); -long drvMsg_initMi(), drvMsg_initMo(); -long drvMsg_initLi(), drvMsg_initLo(); -long drvMsg_initSi(), drvMsg_initSo(); -long drvMsg_initWf(); - -long drvMsg_procAi(), drvMsg_procAo(); -long drvMsg_procBi(), drvMsg_procBo(); -long drvMsg_procMi(), drvMsg_procMo(); -long drvMsg_procLi(), drvMsg_procLo(); -long drvMsg_procSi(), drvMsg_procSo(); -long drvMsg_procWf(); - -long drvMsg_proc(); - -/****************************************************************************** - * - * The msgDrvBlock is used by a message driver designer to specify functions - * that are to be invoked to initialize structures and to check for events - * that might have caused the link task to wake up. This is where hooks to - * device specific functions and data structures are added to the message - * based driver. - * - ******************************************************************************/ -struct msgDrvBlock{ - char *taskName; /* Used for the taskSpawn and messages */ - int taskPri; /* Used for the taskSpawn */ - int taskOpt; /* Used for the taskSpawn */ - int taskStack; /* Used for the taskSpawn */ - struct msgLink *pmsgLink; /* associated msgLink list head */ - - DRVSUPFUN drvWrite; /* Write string from buffer */ - DRVSUPFUN drvRead; /* Read string into buffer */ - DRVSUPFUN drvIoctl; /* perform device specific control function */ -}; -typedef struct msgDrvBlock msgDrvBlock; - -/* IOCTL functions that each message driver MUST support */ -#define MSGIOCTL_REPORT 0 -#define MSGIOCTL_INIT 1 -#define MSGIOCTL_INITREC 2 -#define MSGIOCTL_GENXACT 3 -#define MSGIOCTL_GENHWPVT 4 -#define MSGIOCTL_GENLINK 5 -#define MSGIOCTL_CHECKEVENT 6 -#define MSGIOCTL_COMMAND 7 /* device-type specific */ - -/****************************************************************************** - * - * The parameter passed to the IOCTL function is different depending on the - * function-code used in the IOCTL call. These parameters are defined below. - * - ******************************************************************************/ -struct msgDrvIniParm { - int parm; - struct msgDset *pdset; -}; -typedef struct msgDrvIniParm msgDrvIniParm; - -struct msgDrvGenXParm { - struct link *plink; - struct msgXact *pmsgXact; -}; -typedef struct msgDrvGenXParm msgDrvGenXParm; - -struct msgDrvGenHParm { - struct msgParmBlock *pparmBlock; - struct link *plink; - struct msgHwpvt *pmsgHwpvt; -}; -typedef struct msgDrvGenHParm msgDrvGenHParm; - -struct msgDrvGenLParm { - struct msgLink *pmsgLink; - struct link *plink; - int op; - struct msgParmBlock *pparmBlock; -}; -typedef struct msgDrvGenLParm msgDrvGenLParm; - -struct msgChkEParm { - struct msgDrvBlock *pdrvBlock; - struct msgLink *pmsgLink; - struct msgXact **pxact; -}; -typedef struct msgChkEParm msgChkEParm; - -/****************************************************************************** - * - * Each DSET ppoints to a msgRecEnum structure. This structure defines the - * type of record the dset represents. The idea here is that the address - * of this structure represents the enumeration value for a given record type. - * - * New record types may be added by the application developer - * by defining a msgRecEnum structure and then using its address in the - * DSET for the new record type. - * - * In the future it is intended that this structure be used to describe - * the locations and types of the I/O sensitive fields within a record. - * - ******************************************************************************/ -struct msgRecEnum{ - char recType[20]; /* Holds string describing record type */ -}; -typedef struct msgRecEnum msgRecEnum; - -extern msgRecEnum drvMsgAi; -extern msgRecEnum drvMsgAo; -extern msgRecEnum drvMsgBi; -extern msgRecEnum drvMsgBo; -extern msgRecEnum drvMsgMi; -extern msgRecEnum drvMsgMo; -extern msgRecEnum drvMsgLi; -extern msgRecEnum drvMsgLo; -extern msgRecEnum drvMsgSi; -extern msgRecEnum drvMsgSo; -extern msgRecEnum drvMsgWf; - -/****************************************************************************** - * - * This is a modified DSET that is used by device support modules that use - * the message driver's services. It starts the same as a regular DSET, and - * then includes 2 extra pointers. One to the parmBlock structure for the - * device type being defined. And one that points to the record-type - * enumeration structure. - * - ******************************************************************************/ -struct msgDset{ - long number; - DEVSUPFUN funPtr[10]; - msgParmBlock *pparmBlock; - msgRecEnum *precEnum; -}; -typedef struct msgDset msgDset; - -/****************************************************************************** - * - * This represents the parameters that are passed to the raw read and raw - * write physical device drivers when data is to be transferred. - * - * It is assumed that the 'len' values found in the following structures - * is the number of valid characters to transfer. There is always a '\0' - * added to the ens of this buffer, so the actual buffer size must be at - * least len+1 bytes long. - * - ******************************************************************************/ -typedef struct { - char *buf; /* Buffer to hold the data bytes */ - int len; /* Max number of bytes to read/write */ - int actual; /* actual number of bytes transfered */ -} msgStrParm; - -/****************************************************************************** - * - * The following are the parameters that are passed to the record-specific - * conversion functions. These functions are provided by the message driver - * for convenience only. They are only invoked if the command table contains - * the proper op-codes and/or if the user-supplied code calls them. - * - ******************************************************************************/ -typedef struct { - char *format; /* Format string for the sprintf function */ -} msgFoParm; - -typedef struct { - char *format; /* Format string for the sscanf function */ - int startLoc; /* where to start scanning the input string from */ - int len; /* Max number of bytes to read in */ -} msgFiParm; - -typedef struct { - char *str; /* value to compare response against */ - int index; /* index to start location of comparison */ - int len; /* max number of chars to read from device */ -} msgAkParm; - -typedef struct { - char *str; /* string to compare */ - int index; /* character position to start comparison */ - int len; /* max bytes to read from device */ -} msgSBIParm; - -#endif diff --git a/src/drv/old/drvRs232.c b/src/drv/old/drvRs232.c deleted file mode 100644 index 831b22282..000000000 --- a/src/drv/old/drvRs232.c +++ /dev/null @@ -1,541 +0,0 @@ -/* base/src/drv $Id$ */ -/* - * Author: John Winans - * Date: 04-13-92 - * EPICS R/S-232 driver for the VxWorks's tty driver - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1991, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * Modification Log: - * ----------------- - * .01 09-30-91 jrw created - * - */ - -#define DRVRS232_C - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -int drv232Debug = 0; - -static void callbackAbortSerial(); -static void dogAbortSerial(); - -/****************************************************************************** - * - ******************************************************************************/ -#define RSLINK_PRI 50 -#define RSLINK_OPT VX_FP_TASK|VX_STDIO -#define RSLINK_STACK 5000 - - -/****************************************************************************** - * - ******************************************************************************/ -static long -report() -{ - printf("Report for RS-232 driver\n"); - return(OK); -} - -/****************************************************************************** - * - ******************************************************************************/ -static long -init(pparms) -msgDrvIniParm *pparms; -{ - if (drv232Debug) - printf("Init for RS-232 driver\n"); - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgXact structure. - * - * It is also responsible for filling in the msgXact.phwpvt pointer. - * - ******************************************************************************/ -static long -genXact(p) -msgDrvGenXParm *p; -{ - long stat = -1; - char message[100]; - devTy232Link *pdevTy232Link; - - if (drv232Debug) - printf("RS-232 genXact entered for link %d, addr %d, parm %s\n", p->plink->value.gpibio.link, p->plink->value.gpibio.addr, p->plink->value.gpibio.parm); - - p->pmsgXact->phwpvt = p->pmsgXact->pparmBlock->pmsgHwpvt; - - - while ((p->pmsgXact->phwpvt != NULL) && (stat == -1)) - { - pdevTy232Link = (devTy232Link *)(p->pmsgXact->phwpvt->pmsgLink->p); - - if ((pdevTy232Link->link == p->plink->value.gpibio.link) - && (pdevTy232Link->port == p->plink->value.gpibio.addr)) - { - if (pdevTy232Link->pparmBlock != p->pmsgXact->pparmBlock) - { - sprintf(message, "%s: Two different devices on same RS-232 port\n", p->pmsgXact->prec->name); - errMessage(S_db_badField, message); - return(ERROR); - } - else - stat = 0; /* Found the correct hwpvt structure */ - } - else - p->pmsgXact->phwpvt = p->pmsgXact->phwpvt->next; - } - if (stat != 0) - { /* Could not find a msgHwpvt for the right link, create a new one */ - if ((p->pmsgXact->phwpvt = drvMsg_genHwpvt(p->pmsgXact->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - p->pmsgXact->callback.callback = NULL; - p->pmsgXact->psyncSem = NULL; - if (sscanf(p->plink->value.gpibio.parm,"%d", &(p->pmsgXact->parm)) != 1) - { - p->pmsgXact->prec->pact = TRUE; - sprintf("%s: invalid parameter string >%s<\n", p->pmsgXact->prec->name, p->plink->value.gpibio.parm); - errMessage(S_db_badField, message); - return(ERROR); - } - - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgHwpvt structure. - * - * It is also responsible for filling in the msgHwpvt.pmsgLink pointer. - * - ******************************************************************************/ -static long -genHwpvt(p) -msgDrvGenHParm *p; -{ - int stat = ERROR; - - if (drv232Debug) - printf("rs232-genHwpvt entered\n"); - - p->pmsgHwpvt->pmsgLink = drv232Block.pmsgLink; - while ((p->pmsgHwpvt->pmsgLink != NULL) && (stat == ERROR)) - { - if ((((devTy232Link *)(p->pmsgHwpvt->pmsgLink->p))->link == p->plink->value.gpibio.link) - && (((devTy232Link *)(p->pmsgHwpvt->pmsgLink->p))->port == p->plink->value.gpibio.addr)) - stat = OK; - else - p->pmsgHwpvt->pmsgLink = p->pmsgHwpvt->pmsgLink->next; - } - if (stat != OK) - { - if ((p->pmsgHwpvt->pmsgLink = drvMsg_genLink(p->pparmBlock, p->plink)) == NULL) - return(ERROR); - } - return(OK); -} - -/****************************************************************************** - * - * This function is called to allocate any structures needed to hold - * device-specific data that is added to the msgLink structure. - * - ******************************************************************************/ -static long -genLink(p) -msgDrvGenLParm *p; -{ - char name[20]; - char message[100]; - devTy232Link *pdevTy232Link; - - if (drv232Debug) - printf("In RS-232's genLink, link = %d, addr = %d\n", p->plink->value.gpibio.link,p->plink->value.gpibio.addr); - - switch (p->op) { - case MSG_GENLINK_CREATE: - - if ((p->pmsgLink->p = malloc(sizeof(devTy232Link))) == NULL) - return(ERROR); - - pdevTy232Link = (devTy232Link *)(p->pmsgLink->p); - - pdevTy232Link->link = p->plink->value.gpibio.link; - pdevTy232Link->port = p->plink->value.gpibio.addr; - pdevTy232Link->pparmBlock = p->pparmBlock; - - if ((pdevTy232Link->doggie = wdCreate()) == NULL) - { - printf("RS-232 driver can't create a watchdog\n"); - /* errMessage(******, message); */ - return(ERROR); - } - - sprintf(name, "/tyCo/%d", p->plink->value.gpibio.addr); - - if (drv232Debug) - printf ("in genlink opening >%s<, baud %d\n", name, ((devTy232ParmBlock *)(p->pparmBlock->p))->baud); - - if ((((devTy232Link *)(p->pmsgLink->p))->ttyFd = open(name, O_RDWR, 0)) != -1) - { - if (drv232Debug) - printf("Successful open w/fd=%d\n", pdevTy232Link->ttyFd); - - /* set baud rate and unbuffered mode */ - (void) ioctl (pdevTy232Link->ttyFd, FIOBAUDRATE, ((devTy232ParmBlock *)(p->pparmBlock->p))->baud); - (void) ioctl (pdevTy232Link->ttyFd, FIOSETOPTIONS, ((devTy232ParmBlock *)(p->pparmBlock->p))->ttyOptions); - - pdevTy232Link->callback.callback = callbackAbortSerial; - pdevTy232Link->callback.priority = priorityHigh; - pdevTy232Link->callback.user = (void *) pdevTy232Link; - - return(OK); - } - else - { - printf("RS-232 genLink failed to open the tty port\n"); - free(p->pmsgLink->p); - return(ERROR); - } - - case MSG_GENLINK_ABORT: - if (drv232Debug) - printf("RS-232 genLink called with abort status\n"); - - pdevTy232Link = (devTy232Link *)(p->pmsgLink->p); - /* free(p->pmsgLink->p); Don't forget to take it out of the list */ - return(OK); - } - return(ERROR); -} - -/****************************************************************************** - * - * This function is called to allow the device to indicate that a device-related - * event has occurred. If an event had occurred, it would have to place the - * address of a valid transaction structure in pxact. This xact structure - * will then be processed by the message link task as indicated by the - * return code of this function. - * - * MSG_EVENT_NONE = no event has occurred, pxact not filled in. - * MSG_EVENT_WRITE = event occurred, process the writeOp assoc'd w/pxact. - * MSG_EVENT_READ = event occurred, process the readOp assoc'd w/pxact. - * - * Note that MSG_EVENT_READ only makes sense when returned with a transaction - * that has deferred readback specified for its readOp function. Because if - * it is NOT a deferred readback, it will be done immediately after the writeOp. - * Even if that writeOp was due to a MSG_EVENT_WRITE from this function. - * - ******************************************************************************/ -static long -checkEvent(p) -msgChkEParm *p; -{ - return(MSG_EVENT_NONE); -} - - -static void -dogAbortSerial(pdevTy232Link) -devTy232Link *pdevTy232Link; -{ - logMsg("RS-232 driver watch-dog timeout on link %d, port %d, fd=%d\n", pdevTy232Link->link, pdevTy232Link->port, pdevTy232Link->ttyFd); - - /* Annoying vxWorks implementation... can't IOCTL from here */ - callbackRequest(&(pdevTy232Link->callback)); -} - -static void -callbackAbortSerial(p) -CALLBACK *p; -{ - ((devTy232Link *)(p->user))->dogAbort = TRUE; - - ioctl(((devTy232Link *)(p->user))->ttyFd, FIOCANCEL); - /* I am not sure if I should really do this, but... */ - ioctl(((devTy232Link *)(p->user))->ttyFd, FIOFLUSH); -} - -/****************************************************************************** - * - * This function is used to write a string of characters out to an RS-232 - * device. - * - ******************************************************************************/ -static long -drvWrite(pxact, pwrParm) -msgXact *pxact; -msgStrParm *pwrParm; -{ - devTy232Link *pdevTy232Link = (devTy232Link *)(pxact->phwpvt->pmsgLink->p); - int len; - char *out; - char in; - - if (wdStart(pdevTy232Link->doggie, ((devTy232ParmBlock *)(pxact->pparmBlock->p))->dmaTimeout, dogAbortSerial, pdevTy232Link) == ERROR) - { - printf("RS-232 driver can not start watchdog timer\n"); - /* errMessage(***,message); */ - pxact->status = XACT_IOERR; - return(pxact->status); - } - - if (((devTy232ParmBlock *)(pxact->pparmBlock->p))->flags & ECHO) - { /* ping-pong the characters out */ - - /*BUG ??? This will only work if we are sure that the RX buffer is clean */ - ioctl(pdevTy232Link->ttyFd, FIORFLUSH); - - out = pwrParm->buf; - while ((*out != '\0') && (pxact->status == XACT_OK)) - { - if (drv232Debug > 5) - printf("out >%c<\n", *out); - if (write(pdevTy232Link->ttyFd, out, 1) != 1) - { - printf("RS-232 write error on link %d, port %d\n", pdevTy232Link->link, pdevTy232Link->port); - pxact->status = XACT_IOERR; - } - else - { - if (read(pdevTy232Link->ttyFd, &in, 1) != 1) - { -printf("Read problem encountered in echo reading mode of a write operation\n"); - if (pdevTy232Link->dogAbort) - pxact->status = XACT_TIMEOUT; - else - pxact->status = XACT_IOERR; - } - else - { - if (*out != in) - printf("echo response out of sync! sent >%c< got >%c<\n", *out, in); - - if (drv232Debug > 5) - printf("in >%c<\n", in); - - if ((*out == '\r') && (((devTy232ParmBlock *)(pxact->pparmBlock->p))->flags & CRLF)) - { - if (read(pdevTy232Link->ttyFd, &in, 1) != 1) - { -printf("Read problem encountered in echo reading mode of a write operation\n"); - if (pdevTy232Link->dogAbort) - pxact->status = XACT_TIMEOUT; - else - pxact->status = XACT_IOERR; - } - else - { - if (drv232Debug > 5) - printf("in >%c<\n", in); - } - } - } - } - out++; - } - } - else - { - if (pwrParm->len == -1) - len = strlen(pwrParm->buf); - else - len = pwrParm->len; - - if (drv232Debug > 4) - printf("block-writing >%s<\n", pwrParm->buf); - - if (write(pdevTy232Link->ttyFd, pwrParm->buf, len) != len) - { - printf("RS-232 write error on link %d, port %d\n", pdevTy232Link->link, pdevTy232Link->port); - pxact->status = XACT_IOERR; - } - } - if (wdCancel(pdevTy232Link->doggie) == ERROR) - printf("Can not cancel RS-232 watchdog timer\n"); - - return(pxact->status); -} - -/****************************************************************************** - * - * This function is used to read a string of characters from an RS-232 device. - * - ******************************************************************************/ -static long -drvRead(pxact, prdParm) -msgXact *pxact; -msgStrParm *prdParm; -{ - devTy232Link *pdevTy232Link = (devTy232Link *)(pxact->phwpvt->pmsgLink->p); - int len; - int clen; - char *ch; - int flags; - int eoi; - devTy232ParmBlock *pdevTy232ParmBlock = (devTy232ParmBlock *)(pxact->pparmBlock->p); - - pdevTy232Link->dogAbort = FALSE; - if (wdStart(pdevTy232Link->doggie, pdevTy232ParmBlock->dmaTimeout, dogAbortSerial, pdevTy232Link) == ERROR) - { - printf("RS-232 driver can not start watchdog timer\n"); - /* errMessage(***,message); */ - pxact->status = XACT_IOERR; - return(pxact->status); - } - - ch = prdParm->buf; - len = prdParm->len - 1; - - flags = pdevTy232ParmBlock->flags; -/* BUG -- This should have a timeout check specified in here */ - if ((pdevTy232ParmBlock->eoi != -1) || (flags & KILL_CRLF)) - { - eoi = 0; - while ((!eoi) && (len > 0)) - { - if (read(pdevTy232Link->ttyFd, ch, 1) != 1) - { -printf("Read problem encountered in eoi/KILL_CRLF reading mode\n"); - if (pdevTy232Link->dogAbort) - pxact->status = XACT_TIMEOUT; - else - pxact->status = XACT_IOERR; - eoi = 1; - } - else - { - if (drv232Debug > 6) - printf("in >%c<\n", *ch); - - if (*ch == pdevTy232ParmBlock->eoi) - eoi = 1; - - if (!(flags & KILL_CRLF) || ((*ch != '\n') && (*ch != '\r'))) - { - ch++; - len--; /* To count the \n's and \r's or not to count... */ - } - } - } - if (len == 0) - { - printf("buffer length overrun during read operation\n"); - pxact->status = XACT_LENGTH; - } - - *ch = '\0'; - } - else - { /* Read xact->rxLen bytes from the device */ - while(len) - { - clen = read(pdevTy232Link->ttyFd, ch, len); - if (pdevTy232Link->dogAbort) - { -printf("Read problem encountered in raw mode\n"); - pxact->status = XACT_TIMEOUT; - len = 0; - } - else - { - len -= clen; - ch += clen; - } - } - *ch = '\0'; - } - if (drv232Debug) - printf("drvRead: got >%s<\n", prdParm->buf); - - if (wdCancel(pdevTy232Link->doggie) == ERROR) - printf("Can not cancel RS-232 watchdog timer, dogAbort=%d \n", pdevTy232Link->dogAbort); - - return(pxact->status); -} - -static long -drvIoctl(cmd, pparm) -int cmd; -void *pparm; -{ - switch (cmd) { - case MSGIOCTL_REPORT: - return(report()); - case MSGIOCTL_INIT: - return(init(pparm)); - case MSGIOCTL_INITREC: - printf("drv232Block.drvIoctl got a MSGIOCTL_INITREC request!\n"); - return(ERROR); - case MSGIOCTL_GENXACT: - return(genXact(pparm)); - case MSGIOCTL_GENHWPVT: - return(genHwpvt(pparm)); - case MSGIOCTL_GENLINK: - return(genLink(pparm)); - case MSGIOCTL_CHECKEVENT: - return(checkEvent(pparm)); - case MSGIOCTL_COMMAND: /* BUG -- finish this routine! */ - return(ERROR); - } - return(ERROR); -} - - -msgDrvBlock drv232Block = { - "RS232", - RSLINK_PRI, - RSLINK_OPT, - RSLINK_STACK, - NULL, - drvWrite, - drvRead, - drvIoctl -}; diff --git a/src/drv/old/drvRs232.h b/src/drv/old/drvRs232.h deleted file mode 100644 index 14b75deb0..000000000 --- a/src/drv/old/drvRs232.h +++ /dev/null @@ -1,51 +0,0 @@ -/* share/epicsH $Id$ */ -/* - * Author: John Winans - * Date: 04-16-92 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1988, 1989, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * All rights reserved. No part of this publication may be reproduced, - * stored in a retrieval system, transmitted, in any form or by any - * means, electronic, mechanical, photocopying, recording, or otherwise - * without prior written permission of Los Alamos National Laboratory - * and Argonne National Laboratory. - * - * Modification Log: - * ----------------- - * .01 04-16-92 jrw Initial release - * .02 07-04-92 jrw Moved tty-specific stuff to devTy232.h - * - * This file contains the common parts of the RS-232 device support info. - */ - -#ifndef EPICS_DRVRS232_H -#define EPICS_DRVRS232_H - -typedef struct { - int cmd; - void *pparm; -} ioctlCommand; - -#define IOCTL232_BREAK 1 - -#endif diff --git a/src/drv/old/drvTy232.h b/src/drv/old/drvTy232.h deleted file mode 100644 index 07704d7b8..000000000 --- a/src/drv/old/drvTy232.h +++ /dev/null @@ -1,77 +0,0 @@ -/* share/epicsH $Id$ */ -/* - * Author: John Winans - * Date: 04-16-92 - * - * Experimental Physics and Industrial Control System (EPICS) - * - * Copyright 1988, 1989, the Regents of the University of California, - * and the University of Chicago Board of Governors. - * - * This software was produced under U.S. Government contracts: - * (W-7405-ENG-36) at the Los Alamos National Laboratory, - * and (W-31-109-ENG-38) at Argonne National Laboratory. - * - * Initial development by: - * The Controls and Automation Group (AT-8) - * Ground Test Accelerator - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Co-developed with - * The Controls and Computing Group - * Accelerator Systems Division - * Advanced Photon Source - * Argonne National Laboratory - * - * All rights reserved. No part of this publication may be reproduced, - * stored in a retrieval system, transmitted, in any form or by any - * means, electronic, mechanical, photocopying, recording, or otherwise - * without prior written permission of Los Alamos National Laboratory - * and Argonne National Laboratory. - * - * Modification Log: - * ----------------- - * .01 04-16-92 jrw Initial release - */ - -#ifndef EPICS_DEVTY232_H -#define EPICS_DEVTY232_H - -/****************************************************************************** - * - * Additional fields needed for the msgParmBlock structure. - * - ******************************************************************************/ -typedef struct { - int timeWindow; /* Clock ticks to skip after a timeout */ - int dmaTimeout; /* Clock ticks to wait for DMA to complete */ - int flags; /* set to FALSE if does NOT echo characters */ - int eoi; /* eoi char value or -1 if none */ - int baud; /* baud rate to run the interface */ - int ttyOptions; /* ioctl options for the serial port */ -} devTy232ParmBlock; - -#define ECHO 1 /* Device echos characters sent to it */ - /* The CRLF option is only valid when ECHO is set */ -#define CRLF 2 /* Device does CR -> CR LF expansion */ -#define KILL_CRLF 4 /* Remove all CR and LF characters from input */ - -typedef struct { - CALLBACK callback; /* Used to do the ioctl when the dog wakes up */ - WDOG_ID doggie; /* For I/O timing */ - int dogAbort; /* Used to flag a timeout */ - int link; /* The tty card/link number */ - int port; /* The tty port number on that card */ - int ttyFd; /* The open file descriptor */ - /* The pparmBlock is used to make sure only 1 device type is requested */ - /* on one single port. */ - msgParmBlock *pparmBlock; -} devTy232Link; - -#ifndef DRVTY232_C -extern -#endif -msgDrvBlock drv232Block; - -#endif