libedt.c

00001 /* #pragma ident "@(#)libedt.c  1.462 12/08/10 EDT" */
00002 
00003 #include "edtinc.h"
00004 
00005 #if defined(__linux__) || defined(__APPLE__)
00006 #include <unistd.h>
00007 #include <sys/mman.h>
00008 #include <sys/time.h>
00009 #include <sys/resource.h>
00010 #endif
00011 
00012 #include <stdlib.h>
00013 #include <ctype.h>
00014 
00015 #ifndef _NT_
00016 #include <sys/ioctl.h>
00017 #endif
00018 
00019 #ifdef VXWORKS
00020 #include "vmLib.h"
00021 #include "cacheLib.h"
00022 extern int sysGetVmPageSize();
00023 /* #include <strings.h>*/
00024 #include <string.h>
00025 #endif
00026 
00027 #ifdef _NT_
00028 
00029 #include <process.h>
00030 
00031 #else
00032 
00033 #ifndef VXWORKS
00034 #include <sys/errno.h>
00035 #endif
00036 
00037 #endif
00038 
00039 #ifdef __sun
00040 #include <thread.h>
00041 #endif
00042 #ifdef __sun
00043 #include <sys/mman.h>
00044 #endif
00045 #ifdef __sun
00046 #include <sys/priocntl.h>
00047 #include <sys/rtpriocntl.h>
00048 #include <sys/tspriocntl.h>
00049 #endif
00050 
00051 #if defined(_NT_)
00052 #include <process.h>
00053 #elif defined(__sun) || defined(__linux__) || defined(__APPLE__)
00054 #include <sys/wait.h>
00055 #endif
00056 
00057 
00058 #ifndef PAGE_SHIFT
00059 #define PAGE_SHIFT (12)
00060 #endif
00061 
00062 #ifndef PAGE_SIZE
00063 #define PAGE_SIZE (1UL << PAGE_SHIFT)
00064 #endif
00065 
00066 #ifndef PAGE_MASK
00067 #define PAGE_MASK (PAGE_SIZE-1)
00068 #endif
00069 
00070 
00071 /*
00072 * EDT Library
00073 * 
00074 * Copyright (c) 1998, 2005 by Engineering Design Team, Inc.
00075 * 
00076 * DESCRIPTION Provides a 'C' language   interface to the EDT PCI DMA cards
00077 * to simplify the       ring buffer method of reading data.
00078 * 
00079 * All routines access a specific device, whose handle is created and returned
00080 * by    the edt_open() routine.
00081 * 
00082 */
00083 
00084 /* support for dmy device */
00085 static u_int dmy_started = 0 ;
00086 
00087 
00088 int dump_reg_access = 0;
00089 
00090 void edt_set_dump_reg_access(int on)
00091 
00092 {
00093     dump_reg_access = on;
00094 }
00095 
00096 #ifndef _NT_
00097 
00098 extern int errno;
00099 
00100 static void
00101 edt_set_errno(int val)
00102 
00103 {
00104     errno = val;
00105 }
00106 
00107 #else
00108 
00109 #define edt_set_errno(val)
00110 
00111 #endif
00112 
00113 
00114 
00115 int edt_clear_wait_status(EdtDev *edt_p);
00116 
00117 #ifndef SECTOR_SIZE
00118 #define SECTOR_SIZE 512
00119 #endif
00120 
00121 #ifndef PAGESIZE
00122 #define PAGESIZE 4096
00123 #endif
00124 
00125 #define DEFAULT_BUFFER_GRANULARITY PAGESIZE
00126 #define MINHEADERSIZE SECTOR_SIZE
00127 /* shorthand debug level */
00128 #define EDTDEBUG EDTLIB_MSG_INFO_2
00129 #define EDTFATAL EDTLIB_MSG_FATAL
00130 #define EDTWARN EDTLIB_MSG_WARNING
00131 
00132 #if defined(__APPLE__)
00133 void *edt_mac_open(char *classname, int unit, int channel);
00134 void *edt_mac_ioctl(void *dataPort, int code, void *eis);
00135 #endif
00136 
00137 #ifdef _NT_
00138 static u_int WINAPI 
00139 edt_wait_event_thread(void *);
00140 
00141 int
00142 edt_get_kernel_event(EdtDev *edt_p, int event_num);
00143 static
00144 void
00145 edt_clear_event_func(EdtEventHandler * p);
00146 
00147 #else
00148 #ifndef VXWORKS
00149 static void *
00150 edt_wait_event_thread(void *);
00151 #endif
00152 
00153 #endif
00154 
00155 #ifndef VXWORKS
00156 static char *BaseEventNames[] =
00157 {
00158     NULL,
00159     EDT_EODMA_EVENT_NAME,
00160     EDT_BUF_EVENT_NAME,
00161     EDT_STAT_EVENT_NAME,
00162     EDT_P16D_DINT_EVENT_NAME,
00163     EDT_P11W_ATTN_EVENT_NAME,
00164     EDT_P11W_CNT_EVENT_NAME,
00165     EDT_PDV_ACQUIRE_EVENT_NAME,
00166     EDT_EVENT_PCD_STAT1_NAME,
00167     EDT_EVENT_PCD_STAT2_NAME,
00168     EDT_EVENT_PCD_STAT3_NAME,
00169     EDT_EVENT_PCD_STAT4_NAME,
00170     EDT_PDV_STROBE_EVENT_NAME,
00171     EDT_EVENT_P53B_SRQ_NAME,
00172     EDT_EVENT_P53B_INTERVAL_NAME,
00173     EDT_EVENT_P53B_MODECODE_NAME,
00174     EDT_EVENT_P53B_DONE_NAME,
00175     EDT_PDV_EVENT_FVAL_NAME,
00176     EDT_PDV_EVENT_TRIGINT_NAME,
00177     EDT_EVENT_TEMP_NAME,
00178     NULL
00179 };
00180 #endif
00181 
00182 #ifdef USB
00183 
00191 u_int
00192 usb_reg_read (EdtDev *edt_p, u_int desc)
00193 {
00194     int i, addr;
00195     u_int retval = 0 ;
00196     unsigned char setup[3];
00197     unsigned char buf[5];
00198     int bytes;
00199 
00200     if (usb_claim_interface(edt_p->usb_p, 0) < 0)
00201     {
00202         edt_set_errno(EBUSY); ;
00203         return 0 ;
00204     }
00205 
00206     addr = EDT_REG_ADDR(desc) ;
00207 
00208     for (i = 0; i < EDT_REG_SIZE(desc); i++)
00209     {
00210         setup[0] = 0x03 ;
00211         setup[1] = addr ;
00212 
00213         /* Send setup bytes */
00214         if ((usb_bulk_write(edt_p->usb_p, 0x01, setup, 2,
00215             edt_p->usb_rtimeout)) < 0) 
00216         {
00217             usb_release_interface(edt_p->usb_p, 0);
00218             edt_set_errno(EINVAL); ;
00219             return 0 ;
00220         }
00221 
00222         /* Read back setup bytes to verify */
00223         bytes = usb_bulk_read(edt_p->usb_p, 0x81, buf, 1, edt_p->usb_rtimeout);
00224 
00225         if (bytes < 1)
00226         {
00227             extern int errno ;
00228             usb_release_interface(edt_p->usb_p, 0);
00229             edt_set_errno(EINVAL); ;
00230             return 0 ;
00231         }
00232 
00233         ++addr ;
00234         retval |= ((u_int) buf[0] << (i * 8)) ;
00235     }
00236 
00237     usb_release_interface(edt_p->usb_p, 0);
00238 
00239     return retval ;
00240 }
00241 
00249 void
00250 usb_reg_write(EdtDev *edt_p, u_int desc, u_int value)
00251 {
00252     int i, addr, size;
00253     unsigned char setup[4];
00254     unsigned char buf[4];
00255 
00256     if (usb_claim_interface(edt_p->usb_p, 0) < 0)
00257     {
00258         edt_set_errno(EBUSY); ;
00259         return ;
00260     }
00261 
00262     addr = EDT_REG_ADDR(desc) ;
00263 
00264     for (i = 0; i < EDT_REG_SIZE(desc); i++)
00265     {
00266         if (EDT_REG_TYPE(desc) == REMOTE_USB_TYPE)
00267         {
00268             setup[0] = 0x04;
00269             setup[1] = addr ;
00270             setup[2] = value & 0xff ;
00271             size = 3 ;
00272         }
00273         else if (EDT_REG_TYPE(desc) == LOCAL_USB_TYPE)
00274         {
00275             setup[0] = 0x01;
00276             setup[1] = value & 0xff ;
00277             size = 2 ;
00278         }
00279 
00280         /* Send setup bytes */
00281         if ((usb_bulk_write(edt_p->usb_p, 0x01, setup, size,
00282             edt_p->usb_wtimeout)) < 0) 
00283         {
00284             usb_release_interface(edt_p->usb_p, 0);
00285             edt_set_errno(EINVAL); ;
00286             return ;
00287         }
00288 
00289         addr++ ;
00290         value >>= 8 ;
00291     }
00292 
00293     usb_release_interface(edt_p->usb_p, 0);
00294 }
00295 
00296 
00297 /*
00298 * find the EDT USB board attached
00299 */
00300 struct usb_device *edt_find_usb_board(int unit)
00301 {
00302     struct usb_bus *p;
00303     struct usb_device *q;
00304 
00305     for (p = usb_busses; p; p = p->next)
00306     {
00307         q = p->devices;
00308         while(q)
00309         {
00310             if ((q->descriptor.idVendor==0x04b4) &&
00311                 (q->descriptor.idProduct=0x8613))
00312                 return q;
00313             else
00314                 q = q->next;
00315         }
00316     }
00317 
00318     return NULL;
00319 }
00320 #endif /* USB */
00321 
00322 
00323 static int             edt_parse_devname(EdtDev *edt_p, char *edt_devname, int unit, int channel);
00324 
00325 
00326 EdtDev *edt_open_device(char *device_name, int unit, int channel, int verbose)
00327 
00328 {
00329     EdtDev *edt_p;              /* ptr video device struct */
00330     static char *debug_env = NULL;
00331     u_int   dmy;
00332     int edt_debug;
00333     static char *debug_file = NULL;
00334     int level;
00335 
00336     if ((debug_env == NULL)
00337         && ((debug_env = (char *) getenv("EDTDEBUG")) != NULL)
00338         && *debug_env != '0')
00339     {
00340         edt_debug = atoi(debug_env);
00341         level = edt_msg_default_level();
00342         if (edt_debug > 0) 
00343         {
00344             level |= EDTLIB_MSG_INFO_1;
00345             level |= EDTLIB_MSG_INFO_2;
00346         }
00347         edt_msg_set_level(edt_msg_default_handle(), level);
00348 
00349         if ((debug_file == NULL)
00350             && ((debug_file = (char *) getenv("EDTDEBUGFILE")) != NULL)
00351             && *debug_file != '0')
00352         {
00353             edt_msg_set_name(edt_msg_default_handle(), debug_file);
00354         }
00355 
00356         edt_msg(EDTDEBUG, "environment DEBUG set to %d: enabling debug in edtlib\n", edt_debug);
00357     }
00358 
00359     if ((edt_p = (EdtDev *) calloc(1, sizeof(EdtDev))) == NULL)
00360     {
00361         char errstr[128];
00362         sprintf(errstr, "edtlib: malloc (%x) in edt_open failed\n", (int)sizeof(EdtDev));
00363         edt_msg_perror(EDTWARN, errstr);
00364         return (NULL);
00365     }
00366 
00367     if(verbose)
00368         edt_msg(EDTDEBUG, "edt_open_device(%s, %d)\n", device_name, unit);
00369 
00370     if ((strncmp(device_name, "dmy", 3) == 0) || (strncmp(device_name, "DMY", 3) == 0))
00371         edt_p->devid = DMY_ID;
00372 #ifdef USB
00373     else if (strncasecmp(device_name, "usb", 3) == 0)
00374         edt_p->devtype = USB_ID; /* Set until true ID retrieved from device */
00375 #endif
00376 
00377 
00378     if (edt_parse_devname(edt_p, device_name, unit, channel) != 0)
00379     {
00380         edt_msg(EDTFATAL, "Illegal EDT device name (edt_open_device):  %s\n", device_name);
00381         return NULL;
00382     }
00383 
00384     edt_p->unit_no = unit;
00385     edt_p->channel_no = channel;
00386 
00387 #ifdef USB
00388     if (edt_p->devtype == USB_ID)
00389     {
00390         struct usb_device *current_device = NULL;
00391 
00392         usb_init();
00393         usb_find_busses();
00394         usb_find_devices();
00395 
00396         current_device = edt_find_usb_board(unit);
00397 
00398         if(current_device==NULL)
00399         {
00400             edt_set_errno(ENODEV); ;
00401             return NULL;
00402         } 
00403 
00404         edt_p->usb_p = usb_open(current_device);
00405 
00406         /*
00407         * The following assume that large buffer reads occur
00408         * on endpoints 82, 84, 86, and 88.  82 is channel 2,
00409         * 84 channel 1, etc.  Large buffer writes occur on
00410         * endpoints 2, 4, 6, and 8.
00411         */
00412         edt_p->usb_bulk_read_endpoint = 0x80 + (channel * 2) + 2 ;
00413         edt_p->usb_bulk_write_endpoint = (channel * 2) + 2 ;
00414 
00415     }
00416     else
00417 #endif
00418     {
00419 
00420 #ifdef _NT_
00421         edt_p->fd = CreateFile(edt_p->edt_devname,
00422             GENERIC_READ | GENERIC_WRITE,
00423             FILE_SHARE_READ | FILE_SHARE_WRITE,
00424             NULL,
00425             edt_p->devid == (DMY_ID) ? OPEN_ALWAYS 
00426             : OPEN_EXISTING,
00427             FILE_ATTRIBUTE_NORMAL,
00428             NULL);
00429 
00430         if (edt_p->fd == INVALID_HANDLE_VALUE)
00431         {
00432             if (verbose)
00433                 edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", device_name);
00434 
00435             return (NULL);
00436         }
00437 #else
00438 #if defined (__APPLE__)
00439         /* dataPort = edt_mac_open("pcd",0) ;*/
00440         if (verbose)
00441             edt_msg(EDTWARN, "edt_devname %s unit %d channel %d\n",edt_p->edt_devname,unit,channel) ;
00442         if (edt_p->devid != DMY_ID)
00443         {
00444             if ((edt_p->fd = edt_mac_open(edt_p->edt_devname, unit, channel)) <= 0 )
00445             {
00446                 if (verbose)
00447                     edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", edt_p->edt_devname);
00448                 return (NULL);
00449             }
00450             {
00451                 edt_ioctl(edt_p, EDTG_DEVID, &edt_p->devid);
00452                 if (edt_is_pdv(edt_p))
00453                 {
00454                     if (strncmp(device_name, "pdv", 3) != 0)
00455                     {
00456                         if (verbose)
00457                             printf("%s not match for pdv\n",edt_p->edt_devname) ;
00458                         close(edt_p->fd) ;
00459                         return(NULL);
00460                     }
00461                 }
00462                 else if (edt_is_pcd(edt_p))
00463                 {
00464                     if (strncmp(device_name, "pcd", 3) != 0)
00465                     {
00466                         if (verbose)
00467                             printf("%s not match for pcd\n",edt_p->edt_devname) ;
00468                         close(edt_p->fd) ;
00469                         return(NULL);
00470                     }
00471                 }
00472             }
00473         }
00474         else
00475         {
00476             if (!edt_p->fd)
00477             {
00478                 if ((edt_p->fd = open(edt_p->edt_devname, O_RDWR|O_CREAT, 0666)) < 0 )
00479                 {
00480                     if (verbose)
00481                         edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", edt_p->edt_devname);
00482                     return (NULL);
00483                 }
00484             }
00485             /* printf("skipping open with fd already open\n") ;*/
00486         }
00487 #else
00488 
00489         if ((edt_p->fd = open(edt_p->edt_devname, O_RDWR, 0666)) < 0 )
00490         {
00491             if (verbose)
00492                 edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", edt_p->edt_devname);
00493             return (NULL);
00494         }
00495         /* make sure fd not carried across exec */
00496 #if defined( __linux__) || defined(__sun)
00497         fcntl(edt_p->fd, F_SETFD, FD_CLOEXEC);
00498 #endif
00499 
00500 #endif /* not apple */
00501 #endif
00502     }
00503 
00504 
00505 
00506     edt_msg(EDTDEBUG, "edt_open for %s unit %d succeeded\n", device_name, unit);
00507 
00508     if (edt_p->devid != DMY_ID)
00509     {
00510         edt_ioctl(edt_p, EDTG_DEVID, &edt_p->devid);
00511         edt_ioctl(edt_p, EDTS_RESETCOUNT, &dmy);
00512         dmy = edt_p->channel_no ;
00513         edt_ioctl(edt_p, EDTS_RESETSERIAL, &dmy);
00514         edt_p->DMA_channels = edtdev_channels_from_type(edt_p);
00515 
00516 #ifdef _NT_
00517         edt_get_kernel_event(edt_p, EDT_EVENT_BUF);
00518         edt_get_kernel_event(edt_p, EDT_EVENT_STAT);
00519         if (edt_p->devid == P53B_ID)
00520         {
00521             edt_get_kernel_event(edt_p, EDT_EVENT_P53B_SRQ);
00522             edt_get_kernel_event(edt_p, EDT_EVENT_P53B_INTERVAL);
00523             edt_get_kernel_event(edt_p, EDT_EVENT_P53B_MODECODE);
00524             edt_get_kernel_event(edt_p, EDT_EVENT_P53B_DONE);
00525         }
00526 #endif
00527     }
00528 
00529     edt_p->devtype = edt_devtype_from_id(edt_p->devid);
00530     edt_p->donecount = 0;
00531     edt_p->tmpbuf = 0;
00532     edt_p->dd_p = 0;
00533     edt_p->b_count = 0;
00534     edt_p->buffer_granularity = DEFAULT_BUFFER_GRANULARITY;
00535     edt_p->mezz.id = MEZZ_ID_UNKNOWN;
00536 
00537     return edt_p;
00538 }
00539 
00540 
00564 EdtDev *
00565 edt_open(char *device_name, int unit)
00566 {
00567 
00568     return edt_open_device(device_name, unit, 0, 1);
00569 }
00570 
00571 
00585 EdtDev *
00586 edt_open_quiet(char *device_name, int unit)
00587 {
00588     return edt_open_device(device_name, unit, 0, 0); 
00589 }
00590 
00618 EdtDev *
00619 edt_open_channel(char *device_name, int unit, int channel)
00620 {
00621     return edt_open_device(device_name, unit, channel, 1); 
00622 }
00623 
00632 static int
00633 edt_parse_devname(EdtDev *edt_p, char *device_name, int unit, int channel)
00634 {
00635 
00636     char *format;
00637 
00638     char dev_string[512];
00639 
00640     if (!device_name)
00641         return -1;
00642 
00643     if (device_name[0] == '\\' || device_name[0] == '/')
00644     {
00645         strcpy(edt_p->edt_devname, device_name);
00646     }
00647     else if (edt_p->devid == DMY_ID)
00648     {
00649 #ifdef _NT_
00650         format = ".\\%s%d" ;
00651 #else
00652         format = "./%s%d" ;
00653 #endif
00654         (void) sprintf(edt_p->edt_devname, format, device_name, unit) ;
00655     }
00656     else
00657     {
00658         int i;
00659 
00660         strncpy(dev_string, device_name,511);
00661 
00662         for (i=0;dev_string[i]; i++)
00663             dev_string[i] = tolower(dev_string[i]);
00664 
00665 #ifdef _NT_
00666         dev_string[0] = toupper(dev_string[0]);
00667 #endif
00668 
00669 #if defined(__linux__)
00670         if (strcmp(dev_string, "pcd") == 0)
00671             strcpy(dev_string, "pcicd");
00672 #endif
00673 
00674 
00675 #ifdef _NT_
00676         if (channel > 0)
00677         {
00678             format = "\\\\.\\%s%d_%d"; 
00679         } 
00680         else
00681         {
00682             format = "\\\\.\\%s%d";
00683         }
00684 #else
00685         if (channel > 0)
00686         {
00687             format = "/dev/%s%d_%d"; 
00688         } 
00689         else
00690         {
00691             format = "/dev/%s%d";
00692         }
00693 #endif
00694         (void) sprintf(edt_p->edt_devname, format, dev_string, unit, channel);
00695 
00696     }
00697     edt_msg(EDTDEBUG, "parse open to %s\n",edt_p->edt_devname) ;
00698 
00699     return 0;
00700 }
00701 
00712 int
00713 edt_close(EdtDev *edt_p)
00714 
00715 {
00716     u_int   i;
00717 #ifdef __sun
00718     EdtEventHandler *p;
00719 #endif
00720 
00721     edt_msg(EDTDEBUG, "edt_close()\n");
00722 
00723     for (i = 0; i < EDT_MAX_KERNEL_EVENTS; i++)
00724     {
00725 
00726 
00727 #ifdef __sun
00728         p = &edt_p->event_funcs[i];
00729         if (p->active)
00730         {
00731             p->active = 0;
00732 
00733             edt_ioctl(p->owner, EDTS_DEL_EVENT_FUNC, &i);
00734             edt_ioctl(p->owner, EDTS_CLR_EVENT, &i);
00735             sema_destroy(&p->sema_thread);
00736             thr_join(NULL, NULL, NULL);
00737         }
00738 #else
00739 #ifndef NO_PTHREAD
00740 
00741         edt_remove_event_func(edt_p, i);
00742 #endif
00743 #endif
00744     }
00745 
00746     if (edt_p->ring_buffers_configured)
00747         edt_disable_ring_buffers(edt_p);
00748 
00749     if (edt_p->fd)
00750     {
00751 #ifdef _NT_
00752         CloseHandle(edt_p->fd);
00753 #else
00754 #if defined (__APPLE__)
00755         edt_mac_close(edt_p->fd) ;
00756 #else
00757         close(edt_p->fd);
00758 #endif
00759 #endif
00760     }
00761     free(edt_p);
00762 
00763     return 0;
00764 }
00765 
00766 
00767 
00768 #ifdef __sun
00769 
00770 typedef struct
00771 {
00772     uint_t  index;
00773     uint_t  writeflag;
00774     EdtDev *edt_p;
00775 }       thr_buf_args;
00776 
00777 static void *
00778 aio_thread(   void   *arg)
00779 
00780 {
00781     thr_buf_args *bufp = (thr_buf_args *) arg;
00782     int     ret;
00783     u_char *addr;
00784     uint_t  size;
00785     int     index;
00786     EdtDev *edt_p;
00787     extern int errno;
00788 
00789     edt_p = bufp->edt_p;
00790     index = bufp->index;
00791     addr = edt_p->ring_buffers[index];
00792     size = edt_p->rb_control[index].size;
00793 
00794     /*
00795     * Start a read which will block forever in this thread. aioread() does
00796     * the same thing but won't allow as much concurrency.  Lseek orders the
00797     * buffers inside the driver. also aioread has exit problems
00798     */
00799     edt_msg(EDTDEBUG, "start %s for %d addr %x\n",
00800         bufp->writeflag ? "write" : "read", index, (u_int) addr);
00801     edt_set_errno(0);;
00802     if (bufp->writeflag)
00803         ret = pwrite(edt_p->fd, addr, size, index * 512);
00804     else
00805         ret = pread(edt_p->fd, addr, size, index * 512);
00806     if (ret == -1)
00807     {
00808         char    errstr[128];
00809 
00810         if (errno)
00811             perror("pread");
00812         sprintf(errstr, "aio buffer %d at 0x%x", index, (u_int) addr);
00813         edt_msg_perror(EDTDEBUG, errstr);
00814         edt_msg_perror(EDTDEBUG, "aiothread\n");
00815     }
00816     edt_msg(EDTDEBUG, "end aiothread for %d\n", index);
00817     return (0);
00818 }
00819 
00820 #endif
00821 
00829 int
00830 edt_use_umem_lock(EdtDev *edt_p, u_int use_lock)
00831 {
00832     int ret = 0 ;
00833     if (edt_p->ring_buffers_configured)
00834     {
00835         printf("Can't change umem lock method when ring buffers active\n") ;
00836         return(1) ;
00837     }
00838     edt_msg(EDTDEBUG, "use umem lock %d ",use_lock) ;
00839     ret = edt_ioctl(edt_p, EDTS_UMEM_LOCK, &use_lock) ;
00840     edt_msg(EDTDEBUG, "returns %d\n",ret) ;
00841     if (ret)
00842     {
00843         edt_msg(EDTDEBUG,
00844             "Can't use Umem lock expect on solaris 2.8 or above\n") ;
00845     }
00846     else
00847     {
00848         edt_msg(EDTDEBUG,"Setting umem lock\n") ;
00849     }
00850     return(ret) ;
00851 }
00852 
00853 int
00854 edt_get_umem_lock(EdtDev *edt_p)
00855 {
00856     u_int using_lock ;
00857     edt_ioctl(edt_p, EDTG_UMEM_LOCK, &using_lock) ;
00858     edt_msg(EDTDEBUG,"Using lock returns %d\n",using_lock) ;
00859     return(using_lock) ;
00860 }
00861 
00872 int
00873 edt_get_numbufs(EdtDev *edt_p)
00874 
00875 {
00876     int nb = 0;
00877     edt_ioctl(edt_p, EDTG_NUMBUFS, &nb);
00878     return nb;
00879 }
00880 
00881 /*
00882 * edt_configure_ring_buffer
00883 *
00884 * configures PCI Bus Configurable DMA Interface ring buffers
00885 *
00886 * @param edt_p: device handle returned from edt_open
00887 *      bufsize: size of each buffer
00888 *        nbufs: number of buffers
00889 *   data_direction:     indicates whether this connection is to
00890 *                      be used for output or input
00891 *     bufarray: array of pointers to application-allocated buffers
00892 *
00893 * @return 0 on success; -1 on error
00894 */
00895 
00896 static int
00897 edt_configure_ring_buffer(EdtDev * edt_p,
00898                           int index,
00899                           int bufsize,
00900                           int write_flag,
00901                           unsigned char *pdata)
00902 
00903 {
00904     buf_args sysargs;
00905     int allocated_size = bufsize;
00906     EdtRingBuffer *pring;
00907     int rc;
00908 
00909     if (index < 0 || index >= MAX_DMA_BUFFERS)
00910     {
00911         edt_set_errno(EINVAL); 
00912 
00913         fprintf(stderr,
00914             "invalid buffer index %d < 0 or >= MAX_DMA_BUFFERS (%d)\n",
00915             index, MAX_DMA_BUFFERS);
00916         return -1;
00917     }
00918 
00919     pring = &edt_p->rb_control[index];
00920 
00921 
00922 
00923     pring->size = bufsize;
00924     pring->write_flag = write_flag;
00925 
00926     if (pdata || (edt_p->mmap_buffers))
00927     {
00928         pring->owned = FALSE;
00929         if (edt_p->fullbufsize)
00930             allocated_size = edt_p->fullbufsize;
00931     }
00932     else
00933     {
00934 #ifdef _NT_
00935         /* round up to full page for fast file access */
00936         if (allocated_size & (SECTOR_SIZE-1))
00937             allocated_size = ((allocated_size / SECTOR_SIZE)+1)* SECTOR_SIZE;
00938 #endif
00939         pdata =
00940             edt_alloc(allocated_size);
00941         pring->owned = TRUE;
00942     }
00943 
00944     pring->allocated_size = allocated_size;
00945 
00946     edt_p->ring_buffers[index] = pdata;
00947 
00948     sysargs.index = index;
00949     sysargs.writeflag = write_flag;
00950 #ifdef WIN32
00951     sysargs.addr = (uint64_t) (pdata);
00952 #else
00953     sysargs.addr = (uint64_t) ((unsigned long)pdata);
00954 #endif
00955 
00956     sysargs.size = bufsize;
00957 #ifdef __hpux
00958     bzero(sysargs.addr,sysargs.size) ;
00959 #endif
00960 
00961     if (edt_p->mmap_buffers)
00962     {
00963         if ((rc = edt_ioctl(edt_p, EDTS_BUF_MMAP, &sysargs)) == 0)
00964         {
00965 #ifdef __sun
00966             int  using_lock = 0 ;
00967             int     count;
00968             thr_buf_args bufargs;
00969 
00970             using_lock = edt_get_umem_lock(edt_p) ;
00971 
00972             if (!using_lock)
00973             {
00974                 bufargs.edt_p = edt_p;
00975                 bufargs.index = index;
00976                 bufargs.writeflag = write_flag;
00977 
00978                 edt_msg(EDTDEBUG, "%d buffer thread\n", index);
00979                 if (thr_create(NULL, 0,
00980                     aio_thread,
00981                     (void *) &bufargs, THR_BOUND,
00982                     &pring->ring_tid))
00983                 {
00984                     edt_msg_perror(EDTWARN, "thr_create");
00985                 }
00986             }
00987             count = index + 1;
00988 
00989             edt_msg(EDTDEBUG, "Before WAITN");
00990             edt_ioctl(edt_p, EDTS_WAITN, &count);
00991             edt_msg(EDTDEBUG, "After WAITN");
00992 #endif
00993             return 0;
00994 
00995         }       
00996         else
00997         {
00998             edt_msg(EDT_MSG_FATAL, "Unable to configure ring buffer\n");
00999             edt_msg(EDT_MSG_FATAL, "rc = %d\n", rc);
01000             return rc;
01001         }
01002     } 
01003     else if (edt_ioctl(edt_p, EDTS_BUF, &sysargs) == 0)
01004     {
01005 #ifdef __sun
01006         int  using_lock = 0 ;
01007         int     count;
01008         thr_buf_args bufargs;
01009 
01010         using_lock = edt_get_umem_lock(edt_p) ;
01011 
01012         if (!using_lock)
01013         {
01014             bufargs.edt_p = edt_p;
01015             bufargs.index = index;
01016             bufargs.writeflag = write_flag;
01017 
01018             edt_msg(EDTDEBUG, "%d buffer thread\n", index);
01019             if (thr_create(NULL, 0,
01020                 aio_thread,
01021                 (void *) &bufargs, THR_BOUND,
01022                 &pring->ring_tid))
01023             {
01024                 edt_msg_perror(EDTWARN, "thr_create");
01025             }
01026             count = index + 1;
01027 
01028             edt_msg(EDTDEBUG, "Before WAITN");
01029             edt_ioctl(edt_p, EDTS_WAITN, &count);
01030             edt_msg(EDTDEBUG, "After WAITN");
01031         }
01032 #endif
01033         return 0;
01034     }
01035     return (-1);
01036 }
01037 
01038 /*
01039 * Obsolete - was used as a workaround for edt_set_direction().
01040 * Still used in legacy code, so keep for compatibility.
01041 * TODO: needs to be made compatible with edt_p->mmap_buffers.
01042 */
01043 int
01044 edt_add_ring_buffer(EdtDev * edt_p,
01045                     unsigned int bufsize,
01046                     int write_flag,
01047                     void *pdata)
01048 {
01049 
01050     int     index = -1;
01051 
01052     int     i;
01053 
01054     if (!edt_p->mmap_buffers)
01055     {
01056 
01057         /* allocate a slot for the data */
01058 
01059         for (i = 0; i < MAX_DMA_BUFFERS; i++)
01060             if (edt_p->ring_buffers[i] == NULL)
01061                 break;
01062 
01063         if (i == MAX_DMA_BUFFERS)
01064             return -1;
01065 
01066         index = i;
01067 
01068         edt_p->ring_buffer_numbufs++;
01069 
01070         edt_ioctl(edt_p, EDTS_NUMBUFS, &edt_p->ring_buffer_numbufs);
01071 
01072         edt_configure_ring_buffer(edt_p, index, bufsize, write_flag, pdata);
01073     }
01074 
01075     return index;
01076 }
01077 
01078 
01079 /*
01080 * Obsolete - was used as a workaround for edt_set_direction(), but
01081 * no longer needed.  Still may show up in customer code, so keep.
01082 * 
01083 * @return 0 on success, -1 on failure
01084 */
01085 int
01086 edt_configure_channel_ring_buffers(EdtDev *edt_p, int bufsize, int numbufs,
01087                                    int write_flag, unsigned char **bufarray)
01088 {
01089     return edt_configure_ring_buffers(edt_p, bufsize, numbufs,
01090         write_flag, bufarray) ;
01091 }
01092 
01093 static
01094 int edt_check_ring_buf_parms(EdtDev *edt_p, int numbufs, int bufsize, 
01095                              unsigned char *pdata, unsigned char ** bufarray)
01096 
01097 {
01098 
01099     int maxbufs;
01100 
01101     if (!edt_p)
01102     {
01103         edt_msg_perror(EDTFATAL, "Invalid edt handle\n");
01104         return -1;
01105     }
01106 
01107 
01108     /* Odd number of bytes is illegal.  Mark & Chet Oct'2000 */
01109     if (bufsize & 0x01)
01110     {
01111         edt_set_errno(EINVAL); ;
01112 
01113         edt_msg_perror(EDTFATAL, "edt_configure_ring_buffers: bufsize must be an even number of bytes\n") ;
01114         return -1 ;
01115     }
01116     maxbufs = edt_get_max_buffers(edt_p) ;
01117     if (numbufs > maxbufs)
01118     {
01119 
01120         edt_set_errno(EINVAL); ;
01121 
01122         edt_msg_perror(EDTFATAL, 
01123             "edt_configure_ring_buffers: number of bufs exceeds maximum\n") ;
01124         edt_msg_perror(EDTFATAL, 
01125             "use edt_set_max_buffers to increase max\n") ;
01126         return -1 ;
01127     }   
01128 
01129     edt_p->mmap_buffers = edt_get_mmap_buffers(edt_p);
01130 
01131     if (edt_p->mmap_buffers)
01132     {
01133         if (edt_p->buffer_granularity < PAGE_SIZE)
01134             edt_p->buffer_granularity = PAGE_SIZE;
01135 
01136     }
01137 
01138     if (edt_p->mmap_buffers && ((pdata != NULL) || (bufarray != NULL)))
01139     {
01140 
01141         edt_set_errno(EINVAL); ;
01142 
01143         edt_msg_perror(EDTFATAL, 
01144             "edt_configure_ring_buffers: can't pass in user pointer when using mmap kernel buffers\n") ;
01145 
01146         return -1;
01147     }
01148 
01149     return 0;
01150 }
01151 
01152 #define EDT_DMAMEM_OFFSET 0x10000000
01153 
01154 int
01155 edt_unmap_dmamem(EdtDev *edt_p)
01156 {
01157 
01158 #ifdef __linux__
01159 
01160     if (edt_p->base_buffer)
01161         munmap(edt_p->base_buffer, edt_p->totalsize);
01162 
01163 #endif
01164 
01165     return 0;
01166 }
01167 
01168 caddr_t
01169 edt_map_dmamem(EdtDev *edt_p)
01170 {
01171 
01172     caddr_t     ret = NULL;
01173 
01174 
01175 #ifdef __linux__
01176     int pagen = EDT_DMAMEM_OFFSET;
01177 
01178     ret = (caddr_t) mmap((caddr_t)0, edt_p->totalsize, PROT_READ|PROT_WRITE,
01179         MAP_SHARED, edt_p->fd, pagen);
01180 #endif
01181 
01182 
01183     if (ret == ((caddr_t)-1)) {
01184         perror("mmap call");
01185         return(0) ;
01186     }   
01187 
01188     return(ret) ;
01189 }
01190 
01191 static int
01192 edt_allocate_ring_buffer_memory(EdtDev *edt_p, int bufsize, int numbufs, u_char *user_mem, u_char **buffers)
01193 
01194 {
01195 
01196     unsigned char * bp;
01197     int i;
01198 
01199     edt_p->fullbufsize = edt_get_total_bufsize(edt_p, bufsize, edt_p->header_size);
01200 
01201     edt_p->totalsize = edt_p->fullbufsize * numbufs;
01202 
01203     if (edt_p->mmap_buffers)
01204     {
01205         /* don't allocate, we'll do that later */
01206         for (i=0;i<numbufs;i++)
01207             buffers[i] = NULL;
01208 
01209         return 0;
01210     }
01211 
01212     if (edt_p->base_buffer)
01213     {
01214         edt_free(edt_p->base_buffer);
01215         edt_p->base_buffer = NULL;
01216     }
01217 
01218     if (user_mem)
01219     {
01220         bp = user_mem;
01221     }
01222     else
01223     {
01224 
01225 
01226         edt_p->ring_buffers_allocated = TRUE;
01227         edt_p->base_buffer = edt_alloc(edt_p->totalsize);
01228 
01229         if (!edt_p->base_buffer)
01230         {
01231             edt_msg_perror(EDTFATAL, "Unable to allocate buffer memory\n");
01232             return -1;
01233         }
01234 
01235         bp = edt_p->base_buffer;
01236 
01237 
01238     }
01239 
01240     if (edt_p->header_offset < 0)
01241         bp += ((int) edt_p->header_size);
01242 
01243     for (i=0;i<numbufs;i++)
01244     {
01245         buffers[i] = bp;
01246         bp += edt_p->fullbufsize;
01247     }
01248 
01249 
01250     return 0;
01251 
01252 }
01253 
01254 
01255 static int
01256 edt_setup_ring_buffers(EdtDev *edt_p, int bufsize, int numbufs,
01257                        int write_flag, unsigned char *pdata, unsigned char **bufarray)
01258 {
01259     int     i;
01260     int rc;
01261 
01262     u_char *localbuf[MAX_DMA_BUFFERS];
01263     u_char ** buffers;
01264 
01265     buffers = (bufarray != NULL)?bufarray:localbuf;
01266 
01267     if ((rc = edt_check_ring_buf_parms(edt_p, numbufs, bufsize,  pdata, bufarray)) != 0)
01268         return rc;
01269 
01270     if (edt_p->ring_buffers_configured)
01271         edt_disable_ring_buffers(edt_p);
01272 
01273     edt_p->nextwbuf = 0;
01274     edt_p->donecount = 0;
01275     edt_p->ring_buffer_bufsize = bufsize;
01276     edt_p->ring_buffer_numbufs = numbufs;
01277 
01278     if (write_flag)
01279         edt_set_direction(edt_p, EDT_WRITE);
01280     else
01281         edt_set_direction(edt_p, EDT_READ);
01282 
01283     edt_p->write_flag = write_flag;
01284 
01285     edt_ioctl(edt_p, EDTS_NUMBUFS, &numbufs);
01286 
01287     if (bufarray == NULL)
01288     {
01289         edt_allocate_ring_buffer_memory(edt_p, bufsize, numbufs, pdata, buffers);
01290 
01291         edt_p->ring_buffers_allocated = !edt_p->mmap_buffers && (pdata == NULL);
01292     }
01293 
01294     for (i = 0; i < numbufs; i++)
01295     {
01296         if (edt_configure_ring_buffer(edt_p, i,
01297             bufsize,
01298             write_flag,
01299             buffers[i]) == 0)
01300         {
01301 
01302         }
01303         else
01304         {
01305             return -1;
01306         }
01307 
01308 #ifdef __hpux
01309         edt_dmasync_fordev(edt_p, i, 0, 0) ;
01310 #endif
01311 
01312     }
01313 
01314 
01315 #if defined(__hpux)
01316     {
01317         int pret ;
01318         /* pret = plock(DATLOCK) ;*/
01319         pret = plock(PROCSHLIBLOCK) ;
01320     }
01321 #elif defined(sgi)
01322     mlockall(MCL_FUTURE); 
01323 #endif
01324 
01325     if (edt_p->mmap_buffers)
01326     {
01327         u_char *bp;
01328 
01329         edt_p->base_buffer = (u_char *) edt_map_dmamem(edt_p);
01330         bp = edt_p->base_buffer;
01331 
01332         for (i=0;i<numbufs;i++)
01333         {
01334             edt_p->ring_buffers[i] = bp;
01335             bp += edt_p->fullbufsize;
01336         }
01337 
01338         /* go ahead and page it in */
01339         bp = edt_p->base_buffer;
01340         for (i=0; i<(int)edt_p->totalsize;i += PAGE_SIZE)
01341             bp[i] = 0x5a;
01342 
01343 
01344     }
01345 
01346     edt_p->ring_buffers_configured = 1;
01347 
01348     return 0;
01349 }
01350 
01351 
01352 
01353 void edt_set_buffer_granularity(EdtDev *edt_p, u_int granularity)
01354 
01355 {
01356     edt_p->buffer_granularity = granularity;
01357 }
01358 
01359 
01370 int
01371 edt_get_total_bufsize(EdtDev *edt_p,
01372                       int bufsize, 
01373                       int header_size)
01374 
01375 {
01376     int fullbufsize;
01377 
01378     fullbufsize = header_size + bufsize;
01379 
01380     if (edt_p->buffer_granularity)
01381         if (fullbufsize % edt_p->buffer_granularity)
01382             fullbufsize = ((fullbufsize / edt_p->buffer_granularity)+1)* edt_p->buffer_granularity;     
01383 
01384     return fullbufsize;
01385 }
01386 
01387 
01426 int
01427 edt_configure_ring_buffers(EdtDev *edt_p, int bufsize, int numbufs,
01428                            int write_flag, unsigned char **bufarray)
01429 {
01430     return edt_setup_ring_buffers(edt_p, bufsize, numbufs, write_flag, NULL, bufarray);
01431 
01432 }
01433 
01444 int
01445 edt_configure_block_buffers_mem(EdtDev *edt_p, 
01446                                 int bufsize, 
01447                                 int numbufs, 
01448                                 int write_flag,
01449                                 int header_size, 
01450                                 int header_before,
01451                                 u_char *user_mem)
01452 
01453 {
01454 
01455     /* check for valid arguments */
01456     if (header_before && header_size)
01457     {   
01458         if (header_size & (SECTOR_SIZE-1))
01459             header_size = ((header_size / SECTOR_SIZE)+1)* SECTOR_SIZE; 
01460     }
01461 
01462 
01463     edt_p->header_size = header_size;
01464     edt_p->header_offset = (header_before)? -header_size : bufsize;
01465 
01466 
01467     return edt_setup_ring_buffers(edt_p, bufsize, numbufs, write_flag, user_mem, NULL);
01468 
01469 }
01470 
01471 
01506 int
01507 edt_configure_block_buffers(EdtDev *edt_p, int bufsize, int numbufs, int write_flag,
01508                             int header_size, int header_before)
01509 
01510 {
01511 
01512     return edt_configure_block_buffers_mem(edt_p,
01513         bufsize,
01514         numbufs,
01515         write_flag,
01516         header_size,
01517         header_before,
01518         NULL);
01519 
01520 }
01521 
01522 
01536 int
01537 edt_disable_ring_buffer(EdtDev *edt_p, 
01538                         int whichone)
01539 
01540 {
01541     if (edt_p->ring_buffers[whichone])
01542     {
01543         /* detach buffer from DMA resources */
01544 
01545         edt_ioctl(edt_p, EDTS_FREEBUF, &whichone);
01546         edt_msg(EDTDEBUG, "free buf %d\n", whichone);
01547 
01548 #ifdef __sun
01549         {
01550             u_int using_lock ;
01551             using_lock = edt_get_umem_lock(edt_p) ;
01552             if (!using_lock)
01553             {
01554                 edt_msg(EDTDEBUG, "joining user buf %d tid %x\n", 
01555                     whichone, edt_p->rb_control[whichone].ring_tid);
01556                 thr_join(edt_p->rb_control[whichone].ring_tid, NULL, NULL);
01557 
01558                 edt_msg(EDTDEBUG, "join user buf %d done\n", whichone);
01559             }
01560         }
01561 #endif
01562         /* free data pointer if we own it */
01563         if (edt_p->rb_control[whichone].owned)
01564         {
01565             edt_msg(EDTDEBUG, "free user buf %d\n", whichone);
01566             edt_free(edt_p->ring_buffers[whichone]);
01567         }
01568 
01569         edt_p->ring_buffers[whichone] = NULL;
01570 
01571     }
01572 #if defined(__hpux)
01573     {
01574         int pret ;
01575         pret = plock(UNLOCK) ;
01576     }
01577 #endif
01578 
01579     return 0;
01580 
01581 }
01582 
01583 
01595 int
01596 edt_disable_ring_buffers(EdtDev *edt_p)
01597 
01598 {
01599     int   i;
01600 
01601     /* for (i = 0; i < edt_p->ring_buffer_numbufs; i++)*/
01602     for (i = edt_p->ring_buffer_numbufs - 1; i >= 0 ; i--)
01603     {
01604         edt_disable_ring_buffer(edt_p,i);
01605     }
01606 
01607     edt_p->ring_buffers_configured = 0;
01608     edt_p->ring_buffers_allocated = 0;
01609 #if defined(__hpux)
01610     {
01611         int pret ;
01612         pret = plock(UNLOCK) ;
01613     }
01614 #elif defined(sgi)
01615     munlockall();
01616 #endif
01617 
01618     if (edt_p->base_buffer )
01619     {
01620 
01621         if (edt_p->mmap_buffers)
01622             edt_unmap_dmamem(edt_p);
01623         else
01624             edt_free(edt_p->base_buffer);
01625         edt_p->base_buffer = NULL;
01626     }
01627     /* Steve 1/11/01 to fix pdv_setsize bug */
01628     /* added NUMBUFS to fix dmaid issue 2/19/03 */
01629     {
01630         int one = 1;
01631         edt_p->ring_buffer_numbufs = 0;
01632         edt_ioctl(edt_p, EDTS_NUMBUFS, &one);
01633         edt_ioctl(edt_p, EDTS_CLEAR_DMAID, &one);
01634     }
01635 
01636     return 0;
01637 }
01638 
01653 int
01654 edt_start_buffers(EdtDev *edt_p, uint_t count)
01655 {
01656     if (edt_p->devid == DMY_ID && edt_p->dd_p)
01657         dmy_started += count ;
01658     edt_msg(EDTDEBUG, "edt_start_buffers %d\n", count);
01659     edt_ioctl(edt_p, EDTS_STARTBUF, &count);
01660     return 0;
01661 }
01662 
01663 
01664 int
01665 edt_lockoff(EdtDev * edt_p)
01666 {
01667     int     count = 0;
01668 
01669     edt_ioctl(edt_p, EDTS_STARTBUF, &count);
01670     return 0;
01671 }
01672 
01682 unsigned int
01683 edt_allocated_size(EdtDev *edt_p, int buffer)
01684 
01685 {
01686     if (buffer >= 0 && buffer < (int) edt_p->ring_buffer_numbufs)
01687     {
01688         return edt_p->rb_control[buffer].allocated_size;
01689     }
01690     return 0;
01691 }
01692 
01714 int
01715 edt_set_buffer(EdtDev *edt_p, uint_t bufnum)
01716 {
01717     edt_ioctl(edt_p, EDTS_SETBUF, &bufnum);
01718     edt_p->donecount = bufnum;
01719     if (edt_p->ring_buffer_numbufs)
01720         edt_p->nextwbuf = bufnum % edt_p->ring_buffer_numbufs;
01721     return 0;
01722 }
01723 
01744 int
01745 edt_read(EdtDev *edt_p, 
01746          void   *buf, 
01747          uint_t  size)
01748 {
01749     int     retval;
01750 
01751 #ifdef USB
01752     if (edt_p->devtype == USB_ID)
01753     {
01754         if (usb_claim_interface(edt_p->usb_p, 0) < 0)
01755         {
01756             edt_set_errno(EBUSY); ;
01757             return -1 ;
01758         }
01759 
01760         retval = usb_bulk_read(edt_p->usb_p, edt_p->usb_bulk_read_endpoint,
01761             buf, size, edt_p->usb_rtimeout);
01762 
01763         usb_release_interface(edt_p->usb_p, 0);
01764     }
01765     else
01766 #endif /* USB */
01767     {
01768 
01769 #ifdef _NT_
01770         uint_t  Length;
01771 #endif
01772 
01773         if (size & 0x01) /* Odd no of bytes illegal.  Mark & Chet Oct'2000 */
01774             -- size ;
01775 
01776         if (edt_p->last_direction != 1)
01777             edt_set_direction(edt_p, EDT_READ);
01778 #ifdef _NT_
01779         if ((retval = ReadFile(edt_p->fd, buf, size, &Length, NULL)) == 0)
01780             edt_msg_perror(EDTFATAL, "edt_read:ReadFile");
01781         retval = Length;
01782 #else
01783 #if defined(__APPLE__)
01784         if (edt_p->devid != DMY_ID)
01785         {
01786             int retval ;
01787             unsigned char *bufarray[1] ;
01788             bufarray[0] = buf ;
01789             retval = edt_configure_ring_buffers(edt_p, size, 1, EDT_READ, bufarray) ;
01790             if (retval) return retval;
01791 
01792             edt_start_buffers(edt_p, 1) ;
01793             retval = edt_wait_for_buffers(edt_p, 1) ;
01794             if (retval < 0)
01795             {
01796                 size = edt_get_timeout_count(edt_p);
01797                 edt_msg(EDTDEBUG, "edt_read timeout with count %d\n", retval);
01798             }
01799             edt_disable_ring_buffers(edt_p) ;
01800             return(size) ;
01801         }
01802 #endif
01803         edt_p->b_count += size ;
01804         if (edt_p->b_count > 0x40000000) /* 1GB */
01805         {
01806             lseek(edt_p->fd, 0, 0) ;
01807             edt_p->b_count = 0 ;
01808         }
01809         if ((retval = read(edt_p->fd, buf, size)) < 0)
01810         {
01811 #if defined(__sun) || defined(__linux__)
01812             if (errno == ETIMEDOUT)
01813             {
01814                 retval = edt_get_timeout_count(edt_p);
01815                 edt_msg(EDTDEBUG, "edt_read timeout with count %d\n", retval);
01816             }
01817             else
01818 #endif
01819                 edt_msg_perror(EDTDEBUG, "edt_read:Read");
01820         }
01821 #endif
01822     }
01823     return (retval);
01824 }
01825 
01849 int
01850 edt_write(EdtDev *edt_p,
01851           void   *buf,
01852           uint_t  size)
01853 
01854 {
01855     uint_t  Length = 0;
01856 
01857 #ifdef USB
01858     if (edt_p->devtype == USB_ID)
01859     {
01860         if (usb_claim_interface(edt_p->usb_p, 0) < 0)
01861         {
01862             edt_set_errno(EBUSY); ;
01863             return -1 ;
01864         }
01865 
01866         Length = usb_bulk_write(edt_p->usb_p, edt_p->usb_bulk_write_endpoint,
01867             buf, size, edt_p->usb_wtimeout);
01868 
01869         usb_release_interface(edt_p->usb_p, 0);
01870     }
01871     else
01872 #endif /* USB */
01873     {
01874 
01875         if (size & 0x01) /* Odd no of bytes illegal.  Mark & Chet Oct'2000 */
01876             -- size ;
01877 
01878         if (edt_p->last_direction != (EDT_WRITE+1))
01879             edt_set_direction(edt_p, EDT_WRITE);
01880 #ifdef _NT_
01881         if (!WriteFile(edt_p->fd, buf, size, &Length, NULL))
01882             edt_msg_perror(EDTWARN, "WRITEFile");
01883 #else
01884 #if defined(__APPLE__)
01885         if (edt_p->devid != DMY_ID)
01886         {
01887             int retval ;
01888             unsigned char *bufarray[1] ;
01889             bufarray[0] = buf ;
01890             retval = edt_configure_ring_buffers(edt_p, size, 1, EDT_WRITE, bufarray) ;
01891             edt_start_buffers(edt_p, 1) ;
01892             /* edt_wait_for_buffers(edt_p, 1) ; */
01893             return(size) ;
01894         }
01895 #endif
01896         edt_p->b_count += size ;
01897         if (edt_p->b_count > 0x40000000) /* 1GB */
01898         {
01899             lseek(edt_p->fd, 0, 0) ;
01900             edt_p->b_count = 0 ;
01901         }
01902         if (write(edt_p->fd, buf, size) < 0)
01903         {
01904             edt_msg_perror(EDTDEBUG, "write");
01905             Length = -1;
01906         }
01907         else
01908             Length = size;
01909 #endif
01910     }
01911 
01912     return (Length);
01913 }
01914 
01915 int
01916 edt_write_pio(EdtDev *edt_p, u_char *buf, int size)
01917 
01918 {
01919     edt_sized_buffer argbuf;
01920 
01921     argbuf.size = size;
01922 
01923     memcpy(argbuf.data, buf, size);
01924 
01925     return edt_ioctl(edt_p, EDTS_WRITE_PIO, &argbuf);
01926 
01927 }
01928 
01929 
01941 unsigned char *
01942 edt_next_writebuf(   EdtDev *edt_p)
01943 
01944 {
01945     unsigned char *buf_p;
01946 
01947     buf_p = edt_p->ring_buffers[edt_p->nextwbuf];
01948     edt_p->nextwbuf = ++edt_p->nextwbuf % edt_p->ring_buffer_numbufs;
01949     return buf_p;
01950 }
01951 
01964 unsigned char **
01965 edt_buffer_addresses(EdtDev *edt_p)
01966 {
01967     return (edt_p->ring_buffers);
01968 }
01969 
01992 unsigned char *
01993 edt_wait_buffers_timed(EdtDev * edt_p, int count, u_int * timep)
01994 {
01995     u_char *ret;
01996 
01997     edt_msg(EDTDEBUG, "edt_wait_buffers_timed()\n");
01998 
01999     ret = edt_wait_for_buffers(edt_p, count);
02000     edt_get_timestamp(edt_p, timep, edt_p->donecount - 1);
02001 
02002     edt_msg(EDTDEBUG, "buf %d done %s (%x %x)\n",
02003         edt_p->donecount,
02004         edt_timestring(timep),
02005         timep[0], timep[1]);
02006 
02007     return (ret);
02008 }
02009 
02023 unsigned char *
02024 edt_last_buffer(EdtDev * edt_p)
02025 {
02026     u_char *ret;
02027     bufcnt_t     donecount;
02028     bufcnt_t     last_wait;
02029     int     delta;
02030 
02031     donecount = edt_done_count(edt_p);
02032     last_wait = edt_p->donecount;
02033 
02034     edt_msg(EDTDEBUG, "edt_last_buffer() last %d cur %d\n",
02035         last_wait, donecount);
02036 
02037     delta = donecount - last_wait;
02038 
02039     if (delta == 0)
02040         delta = 1;
02041 
02042     ret = edt_wait_for_buffers(edt_p, delta) ;
02043     return (ret);
02044 }
02045 
02067 unsigned char *
02068 edt_last_buffer_timed(EdtDev * edt_p, u_int * timep)
02069 {
02070     u_char *ret;
02071     bufcnt_t     donecount;
02072     bufcnt_t     last_wait;
02073     int     delta;
02074 
02075     donecount = edt_done_count(edt_p);
02076     last_wait = edt_p->donecount;
02077 
02078     edt_msg(EDTDEBUG, "edt_last_buffer_timed() last %d cur %d\n",
02079         last_wait, donecount);
02080 
02081     delta = donecount - last_wait;
02082 
02083     if (delta == 0)
02084         delta = 1;
02085 
02086     ret = edt_wait_buffers_timed(edt_p, delta, timep);
02087     return (ret);
02088 }
02089 
02090 char   *
02091 edt_timestring(u_int * timep)
02092 {
02093     static char timestr[100];
02094     struct tm *tm_p;
02095     time_t testtm ;
02096 
02097     /* timep is sec,nsec in two 32 bit ints */
02098     /* works when passed to localtime on 32 bit system, but not 64 */
02099     testtm = timep[0] ;
02100     tm_p = localtime(&testtm);
02101     timep++;
02102     sprintf(timestr, "%02d:%02d:%02d.%06d",
02103         tm_p->tm_hour,
02104         tm_p->tm_min,
02105         tm_p->tm_sec,
02106         *timep);
02107 
02108     return timestr;
02109 }
02110 
02128 int                        
02129 edt_do_timeout(EdtDev *edt_p)
02130 
02131 {
02132     int dummy;
02133 
02134     return edt_ioctl(edt_p,EDTS_DOTIMEOUT,&dummy);
02135 
02136 }
02137 
02166 unsigned char *
02167 edt_wait_for_buffers(EdtDev * edt_p, int count)
02168 {
02169     int     bufnum;
02170     int     ret = 0;
02171     bufcnt_t tmpcnt = count ;
02172 #ifdef _NT_
02173     int timeoutval = edt_get_rtimeout(edt_p);
02174 #endif
02175 
02176     edt_msg(EDTDEBUG, "edt_wait_for_buffers(%d)\n", count);
02177 
02178     if (edt_p->ring_buffer_numbufs == 0)
02179     {
02180         edt_msg(EDTDEBUG, "wait for buffers called with 0 buffers\n");
02181         return (0);
02182     }
02183     tmpcnt += edt_p->donecount;
02184 
02185 #ifdef _NT_
02186 
02187     edt_p->last_wait_ret = EDT_WAIT_OK;
02188 
02189     if (edt_get_drivertype(edt_p) != EDT_WDM_DRIVER)
02190 
02191     {
02192         HANDLE event;
02193         int rc;
02194 
02195         if (!edt_p->event_funcs[EDT_EVENT_BUF].wait_event)
02196         {
02197             edt_get_kernel_event(edt_p, EDT_EVENT_BUF);
02198         }
02199 
02200         event = edt_p->event_funcs[EDT_EVENT_BUF].wait_event;
02201 
02202         while (edt_done_count(edt_p) < tmpcnt)
02203         {
02204 
02205             /* wait for event */
02206 
02207             if (timeoutval == 0)
02208                 timeoutval = INFINITE;
02209 
02210             ret = EDT_WAIT_OK;
02211             edt_clear_wait_status(edt_p);
02212 
02213             rc = WaitForSingleObject(event, timeoutval);
02214 
02215             if (rc == WAIT_TIMEOUT)
02216             {
02217                 if (edt_get_timeout_ok(edt_p))
02218                 {
02219                     ret = EDT_WAIT_OK_TIMEOUT;
02220                 }
02221                 else
02222                 {
02223                     edt_msg(EDTDEBUG, "timeout...\n");
02224 
02225                     /* deal with timeout */
02226 
02227                     edt_do_timeout(edt_p);
02228                     ResetEvent(event) ;
02229                     ret = EDT_WAIT_TIMEOUT;
02230                 }
02231                 break;
02232             }
02233             else if (edt_had_user_dma_wakeup(edt_p))
02234             {
02235                 ret = EDT_WAIT_USER_WAKEUP;
02236 
02237             }
02238         }
02239     }
02240     else
02241     {
02242         ret = edt_ioctl(edt_p, EDTS_WAITBUF, &tmpcnt);
02243     }
02244 #else
02245 
02246     ret = edt_ioctl(edt_p, EDTS_WAITBUF, &tmpcnt);
02247     ret = edt_get_wait_status(edt_p);
02248 
02249 #endif
02250 
02251 
02252     edt_msg(EDTDEBUG, "edt_wait_for_buffers %d done ret = %d\n", count,
02253         ret);
02254     if (ret  == EDT_WAIT_OK || ret == EDT_WAIT_TIMEOUT)
02255         edt_p->donecount = tmpcnt;
02256 
02257     /* avoid error if close happened in another thread */
02258 
02259     if (edt_p->ring_buffer_numbufs)
02260         bufnum = (edt_p->donecount - 1) % edt_p->ring_buffer_numbufs;
02261     else
02262         return NULL;
02263 
02264 #ifdef VXWORKS
02265     /* TODO - move this to dma done */
02266     /* ATTN - not right - should be bytecount? */
02267     CACHE_DMA_INVALIDATE(edt_p->ring_buffers[bufnum],
02268         edt_p->rb_control[bufnum].size);
02269 #if defined(AV3_BOARD)
02270     printf("cache inv %x %x\n",
02271         edt_p->ring_buffers[bufnum], edt_p->rb_control[bufnum].size);
02272     bslPpcCacheInv(edt_p->ring_buffers[bufnum], edt_p->rb_control[bufnum].size);
02273 #endif
02274 #endif
02275 
02276         edt_p->last_wait_ret = ret;
02277         
02278         return (edt_p->ring_buffers[bufnum]);
02279 
02280 }
02281 
02306 int
02307 edt_get_timestamp(EdtDev * edt_p, u_int * timep, u_int bufnum)
02308 {
02309     /* we return sec and nsec - change to usec */
02310     u_int   timevals[3];
02311 
02312     timevals[0] = bufnum;
02313     if (edt_p->devid == DMY_ID)
02314     {
02315         u_int inttime ;
02316         double testtime ;
02317         timevals[0] = bufnum ;
02318         testtime = edt_timestamp();
02319         inttime = (u_int)testtime ;
02320         testtime -= inttime ;
02321         *timep++ = inttime ;
02322         *timep++ = (u_int)(testtime * 1000000.0) ;
02323     }
02324     else
02325     {
02326         edt_ioctl(edt_p, EDTG_TMSTAMP, timevals);
02327 
02328         edt_msg(EDTDEBUG, "%x %x %x %x ", bufnum,
02329             timevals[0],
02330             timevals[1],
02331             timevals[2]);
02332         *timep++ = timevals[1];
02333         *timep++ = timevals[2];
02334     }
02335 
02336     return (timevals[0]);
02337 }
02338 
02351 unsigned char *
02352 edt_wait_for_next_buffer(EdtDev *edt_p)
02353 
02354 {
02355     bufcnt_t count;
02356     unsigned int bufnum;
02357 #ifdef _NT_
02358     int timeoutval = edt_get_rtimeout(edt_p);
02359 #endif
02360 
02361     edt_ioctl(edt_p, EDTG_BUFDONE, &count);
02362     count++;
02363     if (edt_p->ring_buffer_numbufs == 0) {
02364         /* maybe they forgot edt_configure_ring_buffers */
02365         return NULL; 
02366     }
02367     bufnum = (count - 1) % edt_p->ring_buffer_numbufs;
02368 
02369 #ifdef _NT_
02370     if (edt_get_drivertype(edt_p) != EDT_WDM_DRIVER)
02371 
02372     {
02373         HANDLE event;
02374         int rc;
02375 
02376         if (!edt_p->event_funcs[EDT_EVENT_BUF].wait_event)
02377         {
02378             edt_get_kernel_event(edt_p, EDT_EVENT_BUF);
02379         }
02380 
02381         event = edt_p->event_funcs[EDT_EVENT_BUF].wait_event;
02382 
02383         while (edt_done_count(edt_p) < (bufcnt_t) count)
02384         {
02385 
02386             /* wait for event */
02387 
02388             if (timeoutval == 0)
02389                 timeoutval = INFINITE;
02390 
02391             rc = WaitForSingleObject(event, timeoutval);
02392 
02393             if (rc == WAIT_TIMEOUT)
02394             {
02395                 edt_msg(EDTDEBUG, "timeout...\n");
02396 
02397                 /* deal with timeout */
02398 
02399                 edt_do_timeout(edt_p);
02400                 ResetEvent(event) ;
02401 
02402                 break;
02403             }
02404 
02405         }
02406 
02407     }
02408     else
02409     {
02410         edt_ioctl(edt_p, EDTS_WAITBUF, &count);
02411     }
02412 #else
02413 
02414     edt_ioctl(edt_p, EDTS_WAITBUF, &count);
02415 
02416 #endif
02417 
02418     edt_msg(EDTDEBUG, "edt_wait_for_next_buffer %d done\n", count);
02419     edt_p->donecount = count;
02420     return (edt_p->ring_buffers[bufnum]);
02421 }
02422 
02423 
02438 unsigned char *
02439 edt_get_current_dma_buf(EdtDev * edt_p)
02440 {
02441     unsigned int count;
02442     unsigned int bufnum;
02443     unsigned int todo ;
02444     /* find out how many are done */
02445 
02446     edt_ioctl(edt_p, EDTG_BUFDONE, &count);
02447 
02448     todo = edt_get_todo(edt_p);
02449 
02450     /* if a dma is currently started
02451     * go to next buffer */
02452 
02453     if (todo == 0 || todo > count)
02454         count ++;
02455 
02456     bufnum = (count - 1) % edt_p->ring_buffer_numbufs;
02457 
02458     return (edt_p->ring_buffers[bufnum]);
02459 
02460 }
02461 
02482 unsigned char *
02483 edt_check_for_buffers(EdtDev *edt_p, uint_t count)
02484 {
02485     unsigned int driver_count;
02486     unsigned int bufnum;
02487     unsigned int target;
02488 
02489     target = count + edt_p->donecount;
02490     bufnum = (target - 1) % edt_p->ring_buffer_numbufs;
02491     edt_ioctl(edt_p, EDTG_BUFDONE, &driver_count);
02492     if (driver_count >= target)
02493     {
02494         return edt_wait_for_buffers(edt_p, count);
02495     }
02496     else
02497         return (NULL);
02498 }
02499 
02515 bufcnt_t
02516 edt_done_count(EdtDev * edt_p)
02517 {
02518     bufcnt_t  donecount = 0;
02519 
02520     if (edt_p->devid == DMY_ID)
02521     {
02522         if (edt_p->dd_p)
02523         {
02524             donecount = dmy_started;
02525         }
02526         else printf("DEBUG - dd_p not set for DMY_ID\n") ;
02527     }
02528     else
02529         edt_ioctl(edt_p, EDTG_BUFDONE, &donecount);
02530     return (donecount);
02531 }
02532 
02533 uint_t
02534 edt_overflow(EdtDev * edt_p)
02535 {
02536     uint_t  overflow;
02537 
02538     edt_ioctl(edt_p, EDTG_OVERFLOW, &overflow);
02539     return (overflow);
02540 }
02541 
02542 
02554 void
02555 edt_perror(char *errstr)
02556 {
02557 #ifdef _NT_
02558     LPVOID  lpMsgBuf;
02559 
02560     FormatMessage(
02561         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
02562         NULL,
02563         GetLastError(),
02564         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),      /* Default language */
02565         (LPTSTR) & lpMsgBuf,
02566         0,
02567         NULL
02568         );
02569 
02570     edt_msg(EDTWARN, "%s: %s\n", errstr, lpMsgBuf);
02571 #else
02572     edt_msg_perror(EDTWARN, errstr);
02573 #endif
02574 }
02575 
02592 u_int
02593 edt_errno(void)
02594 {
02595 #ifdef _NT_
02596     return GetLastError();
02597 #else 
02598     extern int errno;
02599     return errno;
02600 #endif
02601 }
02602 
02619 uint_t
02620 edt_reg_read(EdtDev * edt_p, uint_t desc)
02621 {
02622     int     ret;
02623     edt_buf buf = {0, 0};
02624 
02625 
02626 #ifdef USB
02627     if (EDT_REG_TYPE(desc) == REMOTE_USB_TYPE)
02628     {
02629         buf.value = usb_reg_read(edt_p, desc) ;
02630     }
02631     else
02632 #endif /* USB */
02633     {
02634         buf.desc = desc;
02635         ret = edt_ioctl(edt_p, EDTG_REG, &buf);
02636         if (ret < 0)
02637             return ret;
02638     }
02639 
02640     if (dump_reg_access && 
02641         desc != 0x04000084 &&
02642         desc != 0x01010040 &&
02643         desc != 0x01010042)
02644         printf("reg read %08x %08x\n", desc, (uint_t) buf.value);
02645     return (u_int) buf.value;
02646 }
02647 
02663 uint_t
02664 edt_reg_or(EdtDev * edt_p, uint_t desc, uint_t mask)
02665 {
02666     int     ret;
02667     uint_t  val;
02668     edt_buf buf;
02669 
02670     buf.desc = desc;
02671     buf.value = mask;
02672     ret = edt_ioctl(edt_p, EDTS_REG_OR, &buf);
02673     if (ret < 0)
02674         edt_msg_perror(EDTFATAL, "edt_ioctl(EDT_REG_OR)");
02675 
02676     if (dump_reg_access && 
02677         desc != 0x04000084 &&
02678         desc != 0x01010040 &&
02679         desc != 0x01010042)
02680         printf("reg or %08x %02x\n", desc, mask);
02681     val = (u_int) buf.value;
02682     return val;
02683 
02684 }
02685 
02701 uint_t
02702 edt_reg_and(EdtDev * edt_p, uint_t desc, uint_t mask)
02703 {
02704     int     ret;
02705     uint_t  val;
02706     edt_buf buf;
02707 
02708     buf.desc = desc;
02709     buf.value = mask;
02710     ret = edt_ioctl(edt_p, EDTS_REG_AND, &buf);
02711     if (ret < 0)
02712         edt_msg_perror(EDTFATAL, "edt_ioctl(EDT_REG_AND)");
02713 
02714     if (dump_reg_access && 
02715         desc != 0x04000084 &&
02716         desc != 0x01010040 &&
02717         desc != 0x01010042)
02718         printf("reg and %08x %02x\n", desc, mask);
02719     val = (u_int) buf.value;
02720     return val;
02721 }
02722 
02735 void
02736 edt_reg_clearset(EdtDev * edt_p, uint_t desc, uint_t mask)
02737 {
02738     int     ret;
02739     edt_buf buf;
02740 
02741     buf.desc = desc;
02742     buf.value = mask;
02743     ret = edt_ioctl(edt_p, EDTS_REG_BIT_CLEARSET, &buf);
02744     if (ret < 0)
02745         edt_msg_perror(EDTFATAL, "edt_ioctl(EDT_REG_BIT_CLEARSET)");
02746 
02747     return;
02748 }
02749 
02761 void
02762 edt_reg_setclear(EdtDev * edt_p, uint_t desc, uint_t mask)
02763 {
02764     int     ret;
02765     edt_buf buf;
02766 
02767     buf.desc = desc;
02768     buf.value = mask;
02769     ret = edt_ioctl(edt_p, EDTS_REG_BIT_SETCLEAR, &buf);
02770     if (ret < 0)
02771         edt_msg_perror(EDTFATAL, "edt_ioctl(EDT_REG_BIT_SETCLEAR)");
02772 
02773     return;
02774 }
02775 
02792 void
02793 edt_reg_write(EdtDev * edt_p, uint_t desc, uint_t value)
02794 {
02795     int     ret;
02796     edt_buf buf;
02797 
02798 #ifdef USB
02799     if (edt_p->devtype == USB_ID)
02800     {
02801         usb_reg_write(edt_p, desc, value) ;
02802     }
02803     else
02804 #endif /* USB */
02805     {
02806         buf.desc = desc;
02807         buf.value = value;
02808 
02809         ret = edt_ioctl(edt_p, EDTS_REG, &buf);
02810         if (ret < 0)
02811             edt_msg_perror(EDTFATAL, "write");
02812 
02813         if (dump_reg_access && 
02814             desc != 0x04000084 &&
02815             desc != 0x01010040 &&
02816             desc != 0x01010042)
02817             printf("reg write %08x %02x\n", desc, value);
02818     }
02819 }
02820 
02843 void
02844 edt_startdma_action(EdtDev * edt_p, uint_t val)
02845 {
02846     (void) edt_ioctl(edt_p, EDTS_STARTACT, &val);
02847 }
02848 
02879 void
02880 edt_enddma_action(EdtDev * edt_p, uint_t val)
02881 {
02882     (void) edt_ioctl(edt_p, EDTS_ENDACT, &val);
02883 }
02884 
02904 void
02905 edt_startdma_reg(EdtDev * edt_p, uint_t desc, uint_t val)
02906 {
02907     int     ret;
02908     edt_buf buf;
02909 
02910     buf.desc = desc;
02911     buf.value = val;
02912     ret = edt_ioctl(edt_p, EDTS_STARTDMA, &buf);
02913     if (ret < 0)
02914         edt_msg_perror(EDTFATAL, "write");
02915 }
02916 
02929 void
02930 edt_enddma_reg(EdtDev * edt_p, uint_t desc, uint_t val)
02931 {
02932     int     ret;
02933     edt_buf buf;
02934 
02935     buf.desc = desc;
02936     buf.value = val;
02937     ret = edt_ioctl(edt_p, EDTS_ENDDMA, &buf);
02938     if (ret < 0)
02939         edt_msg_perror(EDTFATAL, "write");
02940 }
02941 
02942 
02943 
02975 void
02976 edt_read_start_action(EdtDev * edt_p, u_int enable, u_int reg_desc,
02977         u_char set, u_char clear, u_char setclear, u_char clearset,
02978         int delay1, int delay2)
02979 {
02980     edt_buf buf;
02981     u_int delays;
02982 
02983     delays = ((delay1 << 16) & 0xffff0000) | (delay2 & 0xffff);
02984     (void) edt_ioctl(edt_p, EDTS_READ_START_DELAYS, &delays);
02985 
02986     buf.flags = enable;
02987     buf.desc  = reg_desc;
02988     buf.value = set | (clear << 8) | (setclear << 16) | (clearset << 24);
02989 
02990     (void) edt_ioctl(edt_p, EDTS_READ_STARTACT, &buf);
02991 }
02992 
02993 
02994 
03026 void
03027 edt_read_end_action(EdtDev * edt_p, u_int enable, u_int reg_desc,
03028         u_char set, u_char clear, u_char setclear, u_char clearset,
03029         int delay1, int delay2)
03030 {
03031     edt_buf buf;
03032     u_int delays;
03033 
03034     delays = ((delay1 << 16) & 0xffff0000) | (delay2 & 0xffff);
03035     (void) edt_ioctl(edt_p, EDTS_READ_END_DELAYS, &delays);
03036 
03037     buf.flags = enable;
03038     buf.desc  = reg_desc;
03039     buf.value = set | (clear << 8) | (setclear << 16) | (clearset << 24);
03040 
03041     (void) edt_ioctl(edt_p, EDTS_READ_ENDACT, &buf);
03042 }
03043 
03044 
03045 
03077 void
03078 edt_write_start_action(EdtDev * edt_p, u_int enable, u_int reg_desc,
03079         u_char set, u_char clear, u_char setclear, u_char clearset,
03080         int delay1, int delay2)
03081 {
03082     edt_buf buf;
03083     u_int delays;
03084 
03085     delays = ((delay1 << 16) & 0xffff0000) | (delay2 & 0xffff);
03086     (void) edt_ioctl(edt_p, EDTS_WRITE_START_DELAYS, &delays);
03087 
03088     buf.flags = enable;
03089     buf.desc  = reg_desc;
03090     buf.value = set | (clear << 8) | (setclear << 16) | (clearset << 24);
03091 
03092     (void) edt_ioctl(edt_p, EDTS_WRITE_STARTACT, &buf);
03093 }
03094 
03095 
03096 
03128 void
03129 edt_write_end_action(EdtDev * edt_p, u_int enable, u_int reg_desc,
03130         u_char set, u_char clear, u_char setclear, u_char clearset,
03131         int delay1, int delay2)
03132 {
03133     edt_buf buf;
03134     u_int delays;
03135 
03136     delays = ((delay1 << 16) & 0xffff0000) | (delay2 & 0xffff);
03137     (void) edt_ioctl(edt_p, EDTS_WRITE_END_DELAYS, &delays);
03138 
03139     buf.flags = enable;
03140     buf.desc  = reg_desc;
03141     buf.value = set | (clear << 8) | (setclear << 16) | (clearset << 24);
03142 
03143     (void) edt_ioctl(edt_p, EDTS_WRITE_ENDACT, &buf);
03144 }
03145 
03146 
03147 
03168 u_char
03169 edt_intfc_read(EdtDev * edt_p, uint_t offset)
03170 {
03171     u_int   read;
03172 
03173     read = edt_reg_read(edt_p, INTFC_BYTE | (offset & 0xffff));
03174     return ((u_char) read & 0xff);
03175 }
03176 
03198 void
03199 edt_intfc_write(EdtDev * edt_p, uint_t offset, u_char data)
03200 {
03201     edt_reg_write(edt_p, INTFC_BYTE | (offset & 0xffff), data);
03202 }
03203 
03238 u_short
03239 edt_intfc_read_short(EdtDev * edt_p, uint_t offset)
03240 {
03241     u_int   read;
03242 
03243     read = edt_reg_read(edt_p, INTFC_WORD | (offset & 0xffff));
03244     return (read & 0xffff);
03245 }
03246 
03269 void
03270 edt_intfc_write_short(EdtDev * edt_p, uint_t offset, u_short data)
03271 {
03272     edt_reg_write(edt_p, INTFC_WORD | (offset & 0xffff), data);
03273 }
03274 
03289 uint_t
03290 edt_intfc_read_32(EdtDev * edt_p, uint_t offset)
03291 {
03292     uint_t  read;
03293 
03294     read = edt_reg_read(edt_p, INTFC_32 | (offset & 0xffff));
03295     return (read);
03296 }
03297 
03313 void
03314 edt_intfc_write_32(EdtDev * edt_p, uint_t offset, uint_t data)
03315 {
03316     edt_reg_write(edt_p, INTFC_32 | (offset & 0xffff), data);
03317 }
03318 
03319 
03320 int 
03321 edt_set_rci_chan(EdtDev *edt_p, int unit, int channel)
03322 {
03323     int ret ;
03324     edt_buf buf;
03325     buf.desc = unit;
03326     buf.value = channel;
03327     edt_msg(EDTDEBUG, "set rci unit %d chan %d\n",unit,channel) ;
03328     ret = edt_ioctl(edt_p, EDTS_RCI_CHAN, &buf);
03329     return (ret) ;
03330 }
03331 
03332 int 
03333 edt_get_rci_chan(EdtDev *edt_p, int unit)
03334 {
03335     int channel ;
03336     edt_buf buf;
03337     buf.desc = unit;
03338     edt_ioctl(edt_p, EDTG_RCI_CHAN, &buf);
03339     channel = (u_int) buf.value ;
03340     edt_msg(EDTDEBUG, "get rci unit %d chan %d\n",unit,channel) ;
03341     return (channel) ;
03342 }
03343 
03344 int
03345 edt_set_rci_dma(EdtDev * edt_p, int unit, int channel)
03346 
03347 {
03348     char msg[5];
03349     sprintf(msg,"D %d",channel);
03350 
03351     edt_send_msg(edt_p,unit,msg,3);
03352     edt_set_rci_chan(edt_p, unit, channel) ;
03353 
03354     return 0;
03355 }
03356 
03357 int
03358 edt_get_rci_dma(EdtDev * edt_p, int unit)
03359 
03360 {
03361     char msgbuf[5];
03362     int channel;
03363     msgbuf[1] = 0;
03364 
03365     edt_send_msg(edt_p, unit, "D", 1);
03366     edt_serial_wait(edt_p, 100, 0) ;
03367     edt_get_msg(edt_p, msgbuf, sizeof(msgbuf));
03368 
03369     channel = atoi(&msgbuf[2]);
03370 
03371     return channel;
03372 
03373 }
03374 
03375 int
03376 edt_set_foiunit(EdtDev * edt_p, int val)
03377 {
03378     edt_p->foi_unit = val;
03379     return (edt_ioctl(edt_p, EDTS_FOIUNIT, &val));
03380 }
03381 
03382 /*
03383 * OBSOLETE (FOI no longer supported).
03384 *
03385 * Returns the number of RCI modules connected to the EDT FOI (fiber
03386 * optic interface) board.
03387 */
03388 int
03389 edt_get_foiunit(EdtDev * edt_p)
03390 {
03391     int     unit;
03392 
03393     edt_ioctl(edt_p, EDTG_FOIUNIT, &unit);
03394     return (unit);
03395 }
03396 
03397 /*
03398 * OBSOLETE (FOI no longer supported).
03399 *
03400 * sets which RCI unit to address with subsequent serial and register 
03401 * read/write functions
03402 *
03403 * @param edt_p:    device struct returned from edt_open
03404 *        unit:     unit number of RCI unit
03405 *
03406 * @return 0 on success; -1 on failure
03407 */
03408 
03409 int
03410 edt_set_foicount(EdtDev * edt_p, int val)
03411 {
03412     return (edt_ioctl(edt_p, EDTS_FOICOUNT, &val));
03413 }
03414 
03425 int
03426 edt_get_foicount(EdtDev * edt_p)
03427 {
03428     int     val;
03429 
03430     edt_ioctl(edt_p, EDTG_FOICOUNT, &val);
03431     return (val);
03432 }
03433 
03448 int
03449 edt_set_burst_enable(EdtDev * edt_p, int onoff)
03450 {
03451     return (edt_ioctl(edt_p, EDTS_BURST_EN, &onoff));
03452 }
03453 
03454 
03468 int
03469 edt_get_burst_enable(EdtDev * edt_p)
03470 {
03471     int     val;
03472 
03473     edt_ioctl(edt_p, EDTG_BURST_EN, &val);
03474     return (val);
03475 }
03476 
03477 int
03478 edt_set_continuous(EdtDev * edt_p, int val)
03479 {
03480 #ifdef PDV
03481     u_int tmp ;
03482     tmp = edt_p->dd_p->datapath_reg ;
03483     /* tmp = edt_reg_read(edt_p, PDV_DATA_PATH) & ~PDV_CONTINUOUS ;*/
03484     edt_ioctl(edt_p, EDTS_PDVDPATH, &tmp);
03485     return (edt_ioctl(edt_p, EDTS_PDVCONT, &val));
03486 #else
03487     return 0;
03488 #endif
03489 }
03490 
03491 void
03492 edt_foi_autoconfig(EdtDev * edt_p)
03493 {
03494     edt_reset_serial(edt_p);
03495     edt_set_foicount(edt_p, 0);
03496     edt_check_foi(edt_p);
03497 }
03498 
03499 void
03500 edt_reset_counts(EdtDev * edt_p)
03501 {
03502     int     dmy;
03503 
03504     edt_ioctl(edt_p, EDTS_RESETCOUNT, &dmy);
03505 }
03506 
03507 void
03508 edt_reset_serial(EdtDev * edt_p)
03509 {
03510     int     dmy;
03511 
03512     dmy = edt_p->channel_no ;
03513     edt_ioctl(edt_p, EDTS_RESETSERIAL, &dmy);
03514 }
03515 
03516 #if defined( PCD ) || defined(UCD) || defined(PDV)
03517 
03518 u_char
03519 pcd_get_option(EdtDev * edt_p)
03520 {
03521     return (edt_intfc_read(edt_p, PCD_OPTION));
03522 }
03523 
03524 u_char
03525 pcd_get_cmd(EdtDev * edt_p)
03526 {
03527     return (edt_intfc_read(edt_p, PCD_CMD));
03528 }
03529 
03530 void
03531 pcd_set_cmd(EdtDev * edt_p, u_char val)
03532 {
03533     edt_intfc_write(edt_p, PCD_CMD, val);
03534 }
03535 
03536 u_char
03537 pcd_get_funct(EdtDev * edt_p)
03538 {
03539     return (edt_intfc_read(edt_p, PCD_FUNCT));
03540 }
03541 
03542 void
03543 pcd_set_funct(EdtDev * edt_p, u_char val)
03544 {
03545     edt_intfc_write(edt_p, PCD_FUNCT, val);
03546 }
03547 
03548 u_char
03549 pcd_get_stat(EdtDev * edt_p)
03550 {
03551     return ((u_char) edt_intfc_read(edt_p, PCD_STAT));
03552 }
03553 
03554 u_char
03555 pcd_get_stat_polarity(EdtDev * edt_p)
03556 {
03557     return (edt_intfc_read(edt_p, PCD_STAT_POLARITY));
03558 }
03559 
03560 void
03561 pcd_set_stat_polarity(EdtDev * edt_p, u_char val)
03562 {
03563     edt_intfc_write(edt_p, PCD_STAT_POLARITY, val);
03564 }
03565 
03566 void
03567 pcd_set_byteswap(EdtDev * edt_p, int val)
03568 {
03569     u_char  tmp;
03570 
03571     tmp = edt_intfc_read(edt_p, PCD_CONFIG);
03572     if (val)
03573         tmp |= PCD_BYTESWAP;
03574     else
03575         tmp &= ~PCD_BYTESWAP;
03576     edt_intfc_write(edt_p, PCD_CONFIG, tmp);
03577 }
03578 
03579 
03580 void
03581 edt_flush_channel(EdtDev *edt_p, int channel)
03582 
03583 {
03584     u_int dma_cfg = edt_reg_read(edt_p, EDT_DMA_CFG) ;
03585 
03586     dma_cfg &= ~(EDT_EMPTY_CHAN | EDT_EMPTY_CHAN_FIFO) ;
03587 
03588     /*
03589     * Set the channel number and enable the rfifo and related logic.
03590     */
03591     dma_cfg |= ((channel << EDT_EMPTY_CHAN_SHIFT) | EDT_RFIFO_ENB) ;
03592     edt_reg_write(edt_p, EDT_DMA_CFG, dma_cfg) ;
03593 
03594     /*
03595     * Set then reset the channel fifo flush bit.
03596     */
03597     dma_cfg |= EDT_EMPTY_CHAN_FIFO ;
03598     edt_reg_write(edt_p, EDT_DMA_CFG, dma_cfg) ;
03599 
03600     dma_cfg &= ~EDT_EMPTY_CHAN_FIFO ;
03601     edt_reg_write(edt_p, EDT_DMA_CFG, dma_cfg) ;
03602 
03603 
03604 }
03605 
03606 
03607 
03608 void
03609 pcd_flush_channel(EdtDev * edt_p, int channel)
03610 {
03611     u_short ssd16_chen = edt_reg_read(edt_p, SSD16_CHEN) ;
03612 
03613     ssd16_chen &= ~(1 << channel);
03614     edt_reg_write(edt_p, SSD16_CHEN, ssd16_chen) ;
03615 
03616     edt_flush_channel(edt_p,channel);
03617 
03618 
03619     ssd16_chen |= (1 << channel);
03620     edt_reg_write(edt_p, SSD16_CHEN, ssd16_chen) ;
03621 
03622 }
03623 
03624 /*****************************************************************************
03625 *
03626 * pio routines:  programmed I/O for PCD DMA boards.
03627 *
03628 *****************************************************************************/
03629 
03630 static volatile u_int  *reg_fifo_io  = NULL ;
03631 static volatile u_char *reg_fifo_cnt = NULL ;
03632 static volatile u_char *reg_fifo_ctl = NULL ;
03633 static volatile u_char *reg_intfc_off ;         /* mmap to intfc regs      */
03634 static volatile u_char *reg_intfc_dat ;         /* mmap to intfc regs      */
03635 static volatile int io_direction = -1 ;
03636 
03637 void
03638 pcd_pio_intfc_write(EdtDev *edt_p, u_int desc, u_char val) 
03639 {
03640     int dmy ;
03641 
03642     *reg_intfc_off = desc & 0xff ;
03643     dmy = *reg_intfc_off ;
03644 
03645     *reg_intfc_dat = val ;
03646     dmy = *reg_intfc_dat ;
03647 }
03648 
03649 u_char
03650 pcd_pio_intfc_read(EdtDev *edt_p, u_int desc) 
03651 {
03652     int dmy ;
03653 
03654     *reg_intfc_off = desc & 0xff ;
03655     dmy = *reg_intfc_off ;
03656 
03657     return(*reg_intfc_dat) ;
03658 }
03659 
03660 
03661 
03662 void
03663 pcd_pio_set_direction(EdtDev *edt_p, int direction)
03664 {
03665     u_char  cmd = pcd_pio_intfc_read(edt_p, PCD_CMD) ;
03666 
03667     if (direction)
03668     {
03669         pcd_pio_intfc_write(edt_p, PCD_DIRA, 0x0f);
03670 
03671         cmd &= ~PCD_DIR;
03672         cmd |= PCD_ENABLE;
03673 
03674     }
03675     else
03676     {
03677         pcd_pio_intfc_write(edt_p, PCD_DIRA, 0xf0);
03678 
03679         cmd |= PCD_DIR | PCD_ENABLE ;
03680     }
03681 
03682     pcd_pio_intfc_write(edt_p, PCD_CMD, cmd);
03683 }
03684 
03685 static void
03686 pcd_pio_quick_flush(EdtDev *edt_p)
03687 {
03688     u_char tmpc ;
03689 
03690     tmpc = *reg_fifo_ctl ;
03691     tmpc &= ~1 ;
03692     *reg_fifo_ctl = tmpc ;
03693     tmpc |= 1 ;
03694     *reg_fifo_ctl = tmpc ;
03695 }
03696 
03697 
03698 void
03699 pcd_pio_flush_fifo(EdtDev * edt_p)
03700 {
03701     unsigned char cmd;
03702     unsigned int dmy;
03703 
03704     /* reset the interface fifos */
03705     *reg_intfc_off = PCD_CMD & 0xff ;
03706     dmy = *reg_intfc_off ;
03707     cmd = *reg_intfc_dat ;
03708     cmd &= ~PCD_ENABLE;
03709     *reg_intfc_dat = cmd ;
03710     dmy = *reg_intfc_dat ;
03711     cmd |= PCD_ENABLE;
03712     *reg_intfc_dat = cmd ;
03713     dmy = *reg_intfc_dat ;
03714 
03715     pcd_pio_quick_flush(edt_p) ;
03716 
03717 }
03718 
03719 void
03720 pcd_pio_init(EdtDev *edt_p)
03721 {
03722     static u_char * mapaddr = 0 ;
03723 
03724     if (mapaddr == 0)
03725     {
03726         mapaddr = (u_char *) edt_mapmem(edt_p, 0, 256) ;
03727         reg_fifo_io  = (u_int *)(mapaddr + (EDT_GP_OUTPUT & 0xff)) ;
03728         reg_fifo_cnt  = (u_char *)(mapaddr + (EDT_DMA_CFG & 0xff) + 3) ;
03729         reg_fifo_ctl = (u_char *)(mapaddr + (EDT_DMA_CFG & 0xff) + 1) ;
03730         reg_intfc_off  = (volatile u_char *) mapaddr + (EDT_REMOTE_OFFSET & 0xff) ;
03731         reg_intfc_dat = (volatile u_char *) mapaddr + (EDT_REMOTE_DATA & 0xff) ;
03732     }
03733     pcd_pio_intfc_write(edt_p, PCD_DIRB, 0xcc);
03734     pcd_pio_flush_fifo(edt_p) ;
03735 }
03736 
03737 int
03738 pcd_pio_write(EdtDev *edt_p, u_char *buf, int size)
03739 {
03740     int i;
03741     u_int *tmpl = (u_int *) buf ;
03742 
03743     pcd_pio_set_direction(edt_p, EDT_WRITE) ;
03744 
03745     for (i = 0 ; i < size / 4 ; i++) 
03746         *reg_fifo_io = *tmpl++ ;
03747 
03748     return(size);
03749 }
03750 
03751 int
03752 pcd_pio_read(EdtDev *edt_p, u_char *buf, int size)
03753 {
03754     u_int *tmpl = (u_int *) buf ;
03755     int wordcnt = 0 ;
03756     int words_avail ;
03757     int words_requested = size / 4 ;
03758 
03759     pcd_pio_set_direction(edt_p, EDT_READ) ;
03760 
03761     while (wordcnt < words_requested)
03762     {
03763         words_avail = *reg_fifo_cnt & 0xf ;
03764 
03765         while (words_avail && wordcnt < words_requested)
03766         {
03767             -- words_avail ;
03768             *tmpl = *reg_fifo_io ;
03769             wordcnt++ ;
03770             tmpl++ ;
03771         }
03772 
03773         if ((wordcnt == words_requested - 1) && (*reg_fifo_cnt & 0x1f) == 0x10)
03774         {
03775             *tmpl = *reg_fifo_io ;
03776             wordcnt++ ;
03777         }
03778     }
03779 
03780     pcd_pio_quick_flush(edt_p);
03781 
03782     return(size) ;
03783 }
03784 
03785 void
03786 pcd_set_abortdma_onintr(EdtDev *edt_p, int flag)
03787 {
03788     if (flag == 0)
03789     {
03790         edt_reg_and(edt_p, PCD_CMD, ~PCD_STAT_INT_1) ;
03791     }
03792 
03793     edt_ioctl(edt_p, EDTS_ABORTDMA_ONINTR, &flag) ;
03794 
03795     if (flag)
03796     {
03797         edt_reg_or(edt_p, PCD_CMD, PCD_STAT_INT_1 | PCD_ENABLE) ;
03798         edt_reg_or(edt_p, PCD_STAT_POLARITY, PCD_STAT_INT_ENA) ;
03799         edt_set_remote_intr(edt_p, TRUE);
03800     }
03801 }
03802 
03803 #endif                          /* PCD */
03804 
03805 
03806 
03815 void
03816 edt_flush_fifo(EdtDev * edt_p)
03817 {
03818     uint_t  tmp;
03819     unsigned char cmd;
03820     unsigned char cfg;
03821     unsigned int dmy;
03822 
03823     edt_msg(EDTDEBUG, "edt_flush_fifo\n") ;
03824     /* Turn off the PCI fifo */
03825     tmp = edt_reg_read(edt_p, EDT_DMA_INTCFG);
03826     tmp &= (~EDT_RFIFO_ENB);
03827     edt_reg_write(edt_p, EDT_DMA_INTCFG, tmp);
03828     dmy = edt_reg_read(edt_p, EDT_DMA_INTCFG);
03829 
03830     if (edt_is_pcd(edt_p) || edt_p->devid == PDVAERO_ID)
03831     {
03832         /* reset the interface fifos */
03833         cmd = edt_intfc_read(edt_p, PCD_CMD);
03834         cmd &= ~PCD_ENABLE;
03835         edt_intfc_write(edt_p, PCD_CMD, cmd);
03836         dmy = edt_intfc_read(edt_p, PCD_CMD);
03837         cmd |= PCD_ENABLE;
03838         edt_intfc_write(edt_p, PCD_CMD, cmd);
03839         dmy = edt_intfc_read(edt_p, PCD_CMD);
03840     }
03841     else if (edt_is_pdv(edt_p))
03842     {
03843         if (edt_p->devid == PDVFOI_ID)
03844         {
03845             edt_p->foi_unit = edt_get_foiunit(edt_p);
03846             edt_init_mac8100(edt_p) ;
03847             edt_send_msg(edt_p, edt_p->foi_unit, "z", 1);
03848             edt_intfc_write(edt_p, PDV_CMD, PDV_RESET_INTFC);
03849         }
03850         else
03851         {
03852             int cont = edt_reg_read(edt_p, PDV_DATA_PATH) & PDV_CONTINUOUS;
03853 
03854             cfg = edt_intfc_read(edt_p, PDV_CFG);
03855             cfg &= ~PDV_FIFO_RESET;
03856             edt_intfc_write(edt_p, PDV_CFG, (u_char) (cfg | PDV_FIFO_RESET));
03857             edt_intfc_write(edt_p, PDV_CMD, PDV_RESET_INTFC);
03858             edt_intfc_write(edt_p, PDV_CFG, cfg);
03859 
03860             if (cont)
03861                 edt_reg_or(edt_p,PDV_DATA_PATH, PDV_CONTINUOUS);
03862         }
03863     }
03864 
03865 
03866     /* Turn     on the PCI fifos, which flushes them */
03867     tmp |= (EDT_RFIFO_ENB);
03868     edt_reg_write(edt_p, EDT_DMA_INTCFG, tmp);
03869     dmy = edt_reg_read(edt_p, EDT_DMA_INTCFG);
03870 
03871 }
03872 
03885 uint_t
03886 edt_get_bytecount(EdtDev * edt_p)
03887 {
03888     uint_t  tmp;
03889 
03890     if (edt_ioctl(edt_p, EDTG_BYTECOUNT, &tmp) < 0)
03891         edt_msg_perror(EDTFATAL, "edt_ioctl(EDTG_BYTECOUNT)");
03892 
03893     return (tmp);
03894 }
03895 
03905 uint_t
03906 edt_get_timeout_count(EdtDev * edt_p)
03907 {
03908     uint_t  tmp;
03909 
03910     if (edt_ioctl(edt_p, EDTG_TIMECOUNT, &tmp) < 0)
03911         edt_msg_perror(EDTFATAL, "edt_ioctl(EDTG_TIMECOUNT)");
03912 
03913     return (tmp);
03914 }
03919 unsigned short
03920 edt_get_direction(EdtDev * edt_p)
03921 {
03922     unsigned short dirreg;
03923 
03924     /* Set the direction register for DMA output */
03925     dirreg = edt_intfc_read(edt_p, PCD_DIRA);
03926     dirreg |= edt_intfc_read(edt_p, PCD_DIRB) << 8;
03927     return (dirreg);
03928 }
03929 
03940 int
03941 edt_cancel_current_dma(EdtDev * edt_p)
03942 {
03943     unsigned int finish_current = 0;
03944 
03945     return edt_ioctl(edt_p, EDTS_STOPBUF, &finish_current);
03946 }
03947 
03948 
03960 void
03961 edt_set_direction(EdtDev * edt_p, int direction)
03962 {
03963 
03964 
03965     if (edt_is_pcd(edt_p) || edt_p->devid == PDVAERO_ID)
03966     {
03967         edt_ioctl(edt_p, EDTS_DIRECTION, &direction);
03968     }
03969 
03970     edt_p->last_direction = (direction) ? 2: 1;
03971 
03972 }
03973 
03974 /*
03975 * EDT IOCTL Interface Routines
03976 * 
03977 * DESCRIPTION General   Purpose device control layer for EDT PCI and SBus
03978 * interface products
03979 * 
03980 * All routines access a specific device, whose handle is created and returned
03981 * by    the <device>_open() routine.
03982 */
03983 
03984 
03985 #ifndef TRUE
03986 #define TRUE 1
03987 #endif
03988 #ifndef FALSE
03989 #define FALSE 0
03990 #endif
03991 
03992 
04002 int
04003 edt_ioctl(EdtDev * edt_p, int code, void *arg)
04004 {
04005     int     get, set;
04006     int     size;
04007     edt_ioctl_struct eis;
04008 #ifdef __APPLE__
04009     int     ret ;
04010 #endif
04011 
04012 #if 0 /* produces too much output for the normal case, but may still be useful...*/
04013     edt_msg(EDTDEBUG, "edt_ioctl(%04x, %04x)\n", code, arg);
04014 #endif
04015 
04016     if (edt_p->devid == DMY_ID)
04017         return (0);
04018     eis.device = edt_p->fd;
04019     eis.controlCode = EIO_DECODE_ACTION(code);
04020     size = EIO_DECODE_SIZE(code);
04021     set = EIO_DECODE_SET(code);
04022     get = EIO_DECODE_GET(code);
04023     eis.inSize = 0;
04024     eis.inBuffer = NULL;
04025     eis.outSize = 0;
04026     eis.outBuffer = NULL;
04027     eis.bytesReturned = 0 ;
04028 #ifdef __APPLE__
04029     eis.channel = edt_p->channel_no ;
04030     eis.unit = edt_p->unit_no ;
04031 #endif
04032 
04033 
04034     if (set)
04035     {
04036         eis.inSize = size;
04037         eis.inBuffer = arg;
04038     }
04039 
04040     if (get)
04041     {
04042         eis.outSize = size;
04043         eis.outBuffer = arg;
04044     }
04045 
04046 
04047 #ifdef _NT_
04048 
04049     if (!DeviceIoControl(
04050         (HANDLE) edt_p->fd,
04051         EDT_MAKE_IOCTL(EDT_DEVICE_TYPE, eis.controlCode),
04052         eis.inBuffer,
04053         eis.inSize,
04054         eis.outBuffer,
04055         eis.outSize,
04056         &eis.bytesReturned,
04057         NULL))
04058     {
04059         return -1;
04060     }
04061     return 0;
04062 
04063 #else
04064 #ifdef VXWORKS
04065     return ioctl(edt_p->fd, EDT_NT_IOCTL, (int)&eis);
04066 #else
04067 #if defined(__APPLE__)
04068 
04069     eis.device = edt_p->channel_no ;
04070     ret = edt_mac_ioctl((u_int)edt_p->fd, EDT_NT_IOCTL, &eis) ;
04071     return(ret);
04072 #else
04073     return ioctl(edt_p->fd, EDT_NT_IOCTL, &eis);
04074 #endif /* apple */
04075 #endif
04076 #endif
04077 
04078 }
04079 
04080 int
04081 edt_ioctl_nt(EdtDev * edt_p, int controlCode, void *inBuffer, int inSize,
04082              void *outBuffer, int outSize, int *bytesReturned)
04083 {
04084     int     ret = 0;
04085 
04086     edt_ioctl_struct eis;
04087 
04088     eis.device = edt_p->fd;
04089     eis.controlCode = controlCode;
04090     eis.inBuffer = inBuffer;
04091     eis.inSize = inSize;
04092     eis.outBuffer = outBuffer;
04093     eis.outSize = outSize;
04094     eis.bytesReturned = 0;
04095 #ifdef __APPLE__
04096     eis.channel = edt_p->channel_no ;
04097     eis.unit = edt_p->unit_no ;
04098 #endif
04099 
04100 #ifdef _NT_
04101 
04102     if (inSize == 0 && outSize == 0)
04103         return ret ;
04104 
04105     if (!DeviceIoControl(
04106         eis.device,
04107         eis.controlCode,
04108         eis.inBuffer,
04109         eis.inSize,
04110         eis.outBuffer,
04111         eis.outSize,
04112         &eis.bytesReturned,
04113         NULL))
04114     {
04115 
04116     }
04117 
04118 #else
04119 #ifdef VXWORKS
04120     if ((ret = ioctl(eis.device, EDT_NT_IOCTL, (int)&eis)) == 0)
04121 #else /* vxworks */
04122 #if defined(__APPLE__)
04123     if ((ret = edt_mac_ioctl((u_int)edt_p->fd, EDT_NT_IOCTL, &eis)) == 0)
04124 #else
04125     if ((ret = ioctl(eis.device, EDT_NT_IOCTL, &eis)) == 0)
04126 #endif /* apple */
04127 #endif /* vxworks */
04128 #endif /* nt */
04129     {
04130         *bytesReturned = eis.bytesReturned;
04131     }
04132     return ret;
04133 }
04134 
04135 
04136 uint_t
04137 edt_debugval(EdtDev * edt_p)
04138 {
04139     uint_t  debugval = 0;
04140 
04141     return (debugval);
04142 }
04143 
04155 int
04156 edt_timeouts(EdtDev * edt_p)
04157 {
04158     int     timeouts;
04159 
04160     if (edt_p->devid == DMY_ID)
04161         return (0);
04162     edt_ioctl(edt_p, EDTG_TIMEOUTS, &timeouts);
04163     return (timeouts);
04164 }
04165 
04166 int
04167 edt_set_dependent(EdtDev * edt_p, void *addr)
04168 {
04169     if (addr == NULL)
04170         return (-1);
04171     if (edt_p->devid == DMY_ID)
04172     {
04173 #ifdef _NT_
04174         edt_p->fd = CreateFile(
04175             edt_p->edt_devname,
04176             GENERIC_READ | GENERIC_WRITE,
04177             FILE_SHARE_READ | FILE_SHARE_WRITE,
04178             NULL,
04179             OPEN_ALWAYS,
04180             FILE_ATTRIBUTE_NORMAL,
04181             NULL);
04182 #else
04183         if (edt_p->fd)
04184         {
04185             /* printf("fd already open\n") ;*/
04186         }
04187         else
04188         {
04189             edt_p->fd = open(edt_p->edt_devname, O_RDWR, 0666);
04190         }
04191 #endif
04192         edt_write(edt_p, addr, sizeof(Dependent));
04193 #ifdef _NT_
04194         CloseHandle(edt_p->fd);
04195         edt_p->fd = NULL;
04196 #else
04197         close(edt_p->fd);
04198         edt_p->fd = 0;
04199 #endif
04200         return (0);
04201     }
04202     return (edt_ioctl(edt_p, EDTS_DEPENDENT, addr));
04203 }
04204 
04205 int
04206 edt_get_dependent(EdtDev * edt_p, void *addr)
04207 {
04208     if (addr == NULL)
04209         return (-1);
04210     if (edt_p->devid == DMY_ID)
04211     {
04212         int ret ;
04213 #ifdef _NT_
04214         edt_p->fd = CreateFile(
04215             edt_p->edt_devname,
04216             GENERIC_READ | GENERIC_WRITE,
04217             FILE_SHARE_READ | FILE_SHARE_WRITE,
04218             NULL,
04219             OPEN_ALWAYS,
04220             FILE_ATTRIBUTE_NORMAL,
04221             NULL);
04222 #else
04223         edt_p->fd = open(edt_p->edt_devname, O_RDWR, 0666);
04224 #endif
04225         ret = edt_read(edt_p, addr, sizeof(Dependent));
04226 #ifdef _NT_
04227         CloseHandle(edt_p->fd);
04228         edt_p->fd = NULL;
04229 #else
04230         close(edt_p->fd);
04231         edt_p->fd = 0;
04232 #endif
04233         if (ret != sizeof(Dependent))
04234             return (-1) ;
04235         return (0);
04236     }
04237     return (edt_ioctl(edt_p, EDTG_DEPENDENT, addr));
04238 }
04239 
04240 int
04241 edt_dump_sglist( EdtDev * edt_p, int val)
04242 {
04243     return (edt_ioctl(edt_p, EDTS_DUMP_SGLIST, &val));
04244 }
04245 
04246 int
04247 edt_set_debug(EdtDev * edt_p, int val)
04248 {
04249     return (edt_ioctl(edt_p, EDTS_DEBUG, &val));
04250 }
04251 
04252 int
04253 edt_get_debug(EdtDev * edt_p)
04254 {
04255     int     val;
04256 
04257     edt_ioctl(edt_p, EDTG_DEBUG, &val);
04258     return (val);
04259 }
04260 
04274 int
04275 edt_set_rtimeout(EdtDev * edt_p, int value)
04276 {
04277     edt_msg(EDTDEBUG, "edt_set_rtimeout(%d)\n", value);
04278     return edt_ioctl(edt_p, EDTS_RTIMEOUT, &value);
04279 }
04280 
04296 int
04297 edt_set_wtimeout(EdtDev * edt_p, int value)
04298 {
04299     edt_msg(EDTDEBUG, "edt_set_wtimeout(%d)\n", value);
04300     return edt_ioctl(edt_p, EDTS_WTIMEOUT, &value);
04301 }
04302 
04314 int
04315 edt_get_rtimeout(EdtDev * edt_p)
04316 {
04317     int     value;
04318 
04319     edt_ioctl(edt_p, EDTG_RTIMEOUT, &value);
04320     return (value);
04321 }
04322 
04334 int
04335 edt_get_wtimeout(EdtDev * edt_p)
04336 {
04337     int     value;
04338 
04339     edt_ioctl(edt_p, EDTG_WTIMEOUT, &value);
04340     return (value);
04341 }
04342 
04343 int
04344 edt_get_tracebuf(EdtDev * edt_p, u_int * addr)
04345 {
04346     if (addr == NULL)
04347         return (-1);
04348     return (edt_ioctl(edt_p, EDTG_TRACEBUF, addr));
04349 }
04350 
04351 u_short
04352 edt_read_mac8100(EdtDev * edt_p, u_int add)
04353 {
04354     u_int   read;
04355 
04356     read = edt_reg_read(edt_p, MAC8100_WORD | (add & 0xff));
04357     return (read & 0xffff);
04358 }
04359 
04360 void
04361 edt_write_mac8100(EdtDev * edt_p, u_int add, u_short data)
04362 {
04363     edt_reg_write(edt_p, MAC8100_WORD | (add & 0xff), data);
04364 }
04365 
04366 void
04367 edt_send_dma(EdtDev * edt_p, int unit, u_int start_val)
04368 {
04369     u_int   stat;
04370     int     loop = 0;
04371 
04372     stat = edt_reg_read(edt_p, FOI_WR_MSG_STAT);
04373     while ((stat & FOI_MSG_BSY) != 0)
04374     {
04375         if (loop++ > 1000000)
04376         {
04377             edt_msg(EDTDEBUG, "failed send dma stat %x\n", stat);
04378             return;
04379         }
04380         stat = edt_reg_read(edt_p, FOI_WR_MSG_STAT);
04381     }
04382     /* routing byte */
04383     edt_reg_write(edt_p, FOI_WR_MSG_DATA, 0x00 | (unit & 0x1f));
04384     while ((stat & FOI_TX_FIFO_FULL) == 0)
04385     {
04386         edt_reg_write(edt_p, FOI_WR_MSG_DATA, start_val++);
04387 
04388         stat = edt_reg_read(edt_p, FOI_WR_MSG_STAT);
04389     }
04390     edt_reg_write(edt_p, FOI_WR_MSG_STAT, FOI_MSG_SEND);
04391 }
04392 
04393 #define END_MARKER      0xffff
04394 static u_short init_mac8100_data[] = {
04395     0, 0x0,
04396     1, 0x0,
04397     2, 0x0,
04398     3, 0x0,
04399     4, 0x0,
04400     5, 0x0,
04401     6, 0x0,
04402     7, 0x07c2,
04403     /* 7, 0x7d8 */ /* this inserts status and crc */
04404     /* 7, 0x07ca,*/
04405     8, 0x0ec0,
04406     /* 8, 0x800,*/ /* 800 to accept all packets */
04407     9, 0x2400, /* autoclear RXDC, counters roll */
04408     11, 0x0000,
04409     14, 0x8800,
04410     17, 0x843f,
04411     18, 0x0000,
04412     /* 18, 0x4000 */ /* sets receive fifo watermark 1,2 */
04413     19, 0x4000,
04414     20, 0x001f,
04415     21, 0x0000,
04416     END_MARKER, 0x0000
04417 };
04418 
04419 static u_short init_mac8101_data[] = {
04420     7,  0x03e1,
04421     8,  0x0ec0,
04422     9,  0x2400, /* autoclear RXDC, counters roll */
04423     10, 0x0000,
04424     17, 0xf43e,
04425     18, 0xf080,
04426     19, 0x4000,
04427     END_MARKER, 0x0000
04428 };
04429 
04430 void
04431 edt_init_mac8100(EdtDev * edt_p)
04432 {
04433 
04434     int is_mac8101;
04435 
04436     u_short *init_tab = init_mac8100_data;
04437     u_int   tmpcfg;
04438 
04439     /* enable mac8100 */
04440     tmpcfg = edt_reg_read(edt_p, EDT_DMA_CFG);
04441     edt_reg_write(edt_p, EDT_DMA_CFG, tmpcfg | 0x200);
04442     edt_msleep(2) ;
04443 
04444     /* do reset */
04445     edt_write_mac8100(edt_p, 7, 0x8000) ;
04446     /* self clears in 1 usec */
04447     edt_msleep(2) ;
04448 
04449 
04450     /* read a xilinx register? */
04451     (void) edt_reg_read(edt_p, FOI_MSG);
04452 
04453     /* read part ID */
04454     is_mac8101 = edt_read_mac8100(edt_p, 32) & 0x1000;
04455 
04456     if (! is_mac8101)  {
04457         init_tab = init_mac8100_data;                   /* for old 5v PCIFOI */
04458     }
04459     else
04460     {
04461         init_tab = init_mac8101_data;                   /* for new 3v PCIFOI */
04462         edt_reg_write(edt_p, 0x010000c5, 0x02);         /* clr fifo's, inrpts */
04463         edt_reg_write(edt_p, 0x040000d4, 0x80000000);   /* reset Xilinx */
04464         edt_reg_write(edt_p, 0x040000d4, 0x36000000);   /* RXRBDIR + RXBUIG */
04465     }
04466 
04467 
04468     while (*init_tab != END_MARKER)
04469     {
04470         edt_write_mac8100(edt_p, (u_int) * init_tab, *(init_tab + 1));
04471         init_tab += 2;
04472     }
04473     /* reset message fifos */
04474     edt_reg_write(edt_p, FOI_WR_MSG_STAT, FOI_FIFO_FLUSH);
04475 
04476 }
04477 
04478 
04479 
04483 int
04484 edt_send_msg(EdtDev * edt_p, int unit, const char *msg, int size)
04485 {
04486     int dummy ;
04487     ser_buf ser ;
04488     ser.unit = unit ;
04489     ser.size = size ;
04490     ser.flags = EDT_SERIAL_SAVERESP ;
04491     memcpy(ser.buf,msg,size) ;
04492 
04493     edt_ioctl_nt(edt_p, ES_SERIAL, &ser, size + EDT_SERBUF_OVRHD,
04494         NULL, 0, &dummy);
04495     return (0);
04496 }
04497 
04498 int
04499 edt_get_msg_unit(EdtDev * edt_p, char *msgbuf, int maxsize, int unit)
04500 {
04501     ser_buf ser ;
04502     int     bytes = 0;
04503     ser.unit = unit ;
04504     ser.size = maxsize ;
04505 
04506     edt_ioctl_nt(edt_p, EG_SERIAL, &ser, EDT_SERBUF_OVRHD,
04507         msgbuf, maxsize, &bytes);
04508     if (bytes < maxsize)
04509         msgbuf[bytes] = '\0';
04510     return (bytes);
04511 }
04512 
04526 int
04527 edt_get_msg(EdtDev * edt_p, char *msgbuf, int maxsize)
04528 {
04529     if (edt_p->devid == PDVFOI_ID)
04530         return(edt_get_msg_unit(edt_p, msgbuf, maxsize, edt_p->foi_unit)) ;
04531     else if (edt_is_dvcl(edt_p) || edt_is_dvfox(edt_p) || edt_p->devid == PDVAERO_ID)
04532         return(edt_get_msg_unit(edt_p, msgbuf, maxsize, edt_p->channel_no)) ;
04533     else return(edt_get_msg_unit(edt_p, msgbuf, maxsize, 0)) ;
04534 }
04535 
04536 
04537 void
04538 edt_check_foi(EdtDev * edt_p)
04539 {
04540     int     retval = 0;
04541     char    msgbuf[256];
04542     int     foicount;
04543     int     loop = 0;
04544 
04545     if (edt_p->devid == PDVFOI_ID)
04546     {
04547         int     count = edt_get_foicount(edt_p);
04548 
04549         if (count)
04550         {
04551             edt_msg(EDTDEBUG, "foi_count %d cur unit %d\n", count, edt_p->foi_unit);
04552         }
04553         else while (retval == 0)
04554         {
04555             char   *tmpp = msgbuf;
04556 
04557             if (loop)
04558                 edt_msleep(1000);
04559 
04560             edt_msg(EDTDEBUG, "foi count 0 - doing autoconfig\n");
04561             edt_reset_serial(edt_p);
04562             edt_init_mac8100(edt_p);
04563             edt_msleep(100);
04564 #if 1
04565             /* for now -  to flush full mac8101 receive fifo on pcifoi mac8100 hw reset */
04566             /*  - send to unit 14 so no response */
04567             edt_send_msg(edt_p, 0x2e, "b", 1);
04568             edt_serial_wait(edt_p, 100, 0) ;
04569             edt_msleep(100);
04570 #endif
04571             edt_send_msg(edt_p, 0x3f, "A", 1);
04572             edt_serial_wait(edt_p, 100, 0) ;
04573             /*
04574             * give rci time to turn off passthru (~1ms)
04575             */
04576             edt_msleep(100);
04577             /* assign first rci in path as unit 0 */
04578             edt_send_msg(edt_p, 0x3f, "U 0", 3);
04579             edt_serial_wait(edt_p, 100, 0) ;
04580             retval = 0;
04581             foicount = 0;
04582             edt_msleep(1000);
04583             /* default to 0 */
04584             edt_set_foiunit(edt_p, 0);
04585 
04586             edt_msleep(100);
04587             retval = edt_get_msg(edt_p, msgbuf, sizeof(msgbuf));
04588             if (retval != 0)
04589             {
04590                 while (tmpp < &tmpp[retval - 4])
04591                 {
04592                     edt_msg(EDTDEBUG, "string <%s>\n", tmpp);
04593                     if (tmpp[0] == 0x3f && tmpp[1] == 'U' && tmpp[2] == ' ')
04594                     {
04595                         foicount = atoi(&tmpp[3]);
04596                         edt_msg(EDTDEBUG, "setting foi count to %d\n", foicount);
04597                         edt_set_foicount(edt_p, foicount);
04598                         break;
04599                     }
04600                     tmpp++;
04601                 }
04602             }
04603             if (loop++ > 3)
04604             {
04605                 edt_msg(EDTDEBUG, "leaving checkfoi without response\n");
04606                 return;
04607             }
04608             edt_msleep(1000);
04609 
04610             edt_msg(EDTDEBUG, "done with auto config\n");
04611             edt_send_msg(edt_p, 0, "i", 1);
04612             edt_msleep(100);
04613             edt_get_msg(edt_p, msgbuf, sizeof(msgbuf));
04614             edt_send_msg(edt_p, 0, "z", 1);
04615             edt_msleep(100);
04616             edt_get_msg(edt_p, msgbuf, sizeof(msgbuf));
04617             edt_msg(EDTDEBUG, "done with init and flush\n");
04618         }
04619     }
04620 }
04621 
04622 int
04623 edt_set_statsig(EdtDev * edt_p, int event, int sig)
04624 {
04625     edt_buf buf;
04626 
04627     buf.desc = event;
04628     buf.value = sig;
04629     return (edt_ioctl(edt_p, EDTS_EVENT_SIG, &buf));
04630 }
04631 
04632 int
04633 edt_set_eodma_int(EdtDev * edt_p, int sig)
04634 {
04635     return (edt_ioctl(edt_p, EDTS_EODMA_SIG, &sig));
04636 }
04637 
04638 int
04639 edt_set_autodir(EdtDev * edt_p, int val)
04640 {
04641     return (edt_ioctl(edt_p, EDTS_AUTODIR, &val));
04642 }
04643 
04663 int
04664 edt_set_firstflush(EdtDev * edt_p, int flag)
04665 {
04666     return (edt_ioctl(edt_p, EDTS_FIRSTFLUSH, &flag));
04667 }
04668 
04669 
04693 int
04694 edt_get_firstflush(EdtDev * edt_p)
04695 {
04696 
04697     int val;
04698 
04699     edt_ioctl(edt_p, EDTG_FIRSTFLUSH, &val);
04700 
04701     return val;
04702 }
04703 
04704 
04705 u_char
04706 edt_set_funct_bit(EdtDev * edt_p, u_char mask)
04707 {
04708     unsigned char funct;
04709 
04710     funct = edt_reg_read(edt_p, PCD_FUNCT);
04711     funct |= mask;
04712     edt_reg_write(edt_p, PCD_FUNCT, funct);
04713     return (funct);
04714 }
04715 
04716 u_char
04717 edt_clr_funct_bit(EdtDev * edt_p, u_char mask)
04718 {
04719     u_char  funct;
04720 
04721     funct = edt_reg_read(edt_p, PCD_FUNCT);
04722     funct &= ~mask;
04723     edt_reg_write(edt_p, PCD_FUNCT, funct);
04724     return (funct);
04725 }
04726 
04727 
04732 static void
04733 shft_av9110(EdtDev * edt_p, u_int data, u_int numbits)
04734 {
04735     int use_pcd_method;
04736 
04737     if (ID_IS_PCD(edt_p->devid) || edt_p->devid == PDVAERO_ID)
04738         use_pcd_method = 1;
04739     else
04740         use_pcd_method = 0;
04741 
04742     while (numbits)
04743     {
04744         if (use_pcd_method)
04745         {
04746             if (data & 0x1)
04747                 edt_set_funct_bit(edt_p, EDT_FUNCT_DATA);
04748             else
04749                 edt_clr_funct_bit(edt_p, EDT_FUNCT_DATA);
04750             /* clock it in */
04751             edt_set_funct_bit(edt_p, EDT_FUNCT_CLK);
04752             edt_clr_funct_bit(edt_p, EDT_FUNCT_CLK);
04753         }
04754         else
04755         {
04756             if (data & 0x1)
04757                 edt_set_pllct_bit(edt_p, EDT_FUNCT_DATA);
04758             else
04759                 edt_clr_pllct_bit(edt_p, EDT_FUNCT_DATA);
04760             /* clock it in */
04761             edt_set_pllct_bit(edt_p, EDT_FUNCT_CLK);
04762             edt_clr_pllct_bit(edt_p, EDT_FUNCT_CLK);
04763 
04764         }
04765         data = data >> 1;
04766         numbits--;
04767     }
04768 }
04769 
04770 u_char
04771 edt_set_pllct_bit(EdtDev * edt_p, u_char mask)
04772 {
04773     unsigned char pll_ct;
04774 
04775     pll_ct = edt_reg_read(edt_p, PDV_PLL_CTL);
04776     pll_ct |= mask;
04777     edt_reg_write(edt_p, PDV_PLL_CTL, pll_ct);
04778     return (pll_ct);
04779 }
04780 
04781 u_char
04782 edt_clr_pllct_bit(EdtDev * edt_p, u_char mask)
04783 {
04784     u_char  pll_ct;
04785 
04786     pll_ct = edt_reg_read(edt_p, PDV_PLL_CTL);
04787     pll_ct &= ~mask;
04788     edt_reg_write(edt_p, PDV_PLL_CTL, pll_ct);
04789     return (pll_ct);
04790 }
04791 
04792 void
04793 edt_set_out_clk(EdtDev * edt_p, edt_pll * clk_data)
04794 {
04795     int use_pcd_method;
04796 
04797     unsigned char opt_e = 0;
04798     u_int   svfnct;
04799 
04800     if (ID_IS_PCD(edt_p->devid) || edt_p->devid == PDVAERO_ID)
04801         use_pcd_method = 1;
04802     else
04803         use_pcd_method = 0;
04804 
04805     switch (clk_data->h)
04806     {
04807     case 1:
04808         opt_e = EDT_FAST_DIV1;
04809         break;
04810 
04811     case 3:
04812         opt_e = EDT_FAST_DIV3;
04813         break;
04814 
04815     case 5:
04816         opt_e = EDT_FAST_DIV5;
04817         break;
04818 
04819     case 7:
04820         opt_e = EDT_FAST_DIV7;
04821         break;
04822 
04823     default:
04824         edt_msg(EDTDEBUG, "Illegal value %d for xilinx fast clk divide\n",
04825             clk_data->h);
04826         opt_e = EDT_FAST_DIV1;
04827         clk_data->h = 1;
04828         break;
04829     }
04830     opt_e |= ((clk_data->l - 1) << EDT_X_DIVN_SHFT);
04831 
04832 
04833     if (use_pcd_method)
04834     {
04835         edt_reg_write(edt_p, EDT_OUT_SCALE, opt_e);
04836         edt_reg_write(edt_p, EDT_REF_SCALE, clk_data->x - 1);
04837         svfnct = edt_reg_read(edt_p, PCD_FUNCT);
04838         edt_set_funct_bit(edt_p, EDT_FUNCT_SELAV);
04839         edt_clr_funct_bit(edt_p, EDT_FUNCT_CLK);
04840 
04841 
04842     }
04843     else
04844     {
04845         edt_reg_write(edt_p, PDV_OUT_SCALE, opt_e);
04846         edt_reg_write(edt_p, PDV_REF_SCALE, clk_data->x - 1);
04847         svfnct = edt_reg_read(edt_p, PDV_PLL_CTL);
04848         edt_set_pllct_bit(edt_p, EDT_FUNCT_SELAV);
04849         edt_clr_pllct_bit(edt_p, EDT_FUNCT_CLK);
04850 
04851     }
04852 
04853 
04854     svfnct &= ~EDT_FUNCT_SELAV;  /* Must turn this off when done - jerry */
04855 
04856     /* shift out data */
04857     shft_av9110(edt_p, clk_data->n, 7);
04858     shft_av9110(edt_p, clk_data->m, 7);
04859     /* set vco preescale */
04860     if (clk_data->v == 1)
04861         shft_av9110(edt_p, 0, 1);
04862     else
04863         shft_av9110(edt_p, 1, 1);
04864     /* clkx divide is not used (right now) so set to div 1 */
04865     switch (clk_data->r)
04866     {
04867     case 1:
04868         shft_av9110(edt_p, 0x170, 9);
04869         break;
04870 
04871     case 2:
04872         shft_av9110(edt_p, 0x174, 9);
04873         break;
04874 
04875     case 4:
04876         shft_av9110(edt_p, 0x178, 9);
04877         break;
04878 
04879     case 8:
04880         shft_av9110(edt_p, 0x17c, 9);
04881         break;
04882 
04883     default:
04884         edt_msg(EDTDEBUG, "illegal value %d for AV9110 aoutput divide\n",
04885             clk_data->r);
04886         shft_av9110(edt_p, 0x5c, 7);
04887         break;
04888     }
04889     /* restore fnct bits */
04890 
04891     if (use_pcd_method)
04892         edt_reg_write(edt_p, PCD_FUNCT, svfnct);
04893     else
04894         edt_reg_write(edt_p, PDV_PLL_CTL, svfnct);
04895 
04896 }
04897 
04898 u_int
04899 edt_set_sglist(EdtDev *edt_p, 
04900                uint_t bufnum, 
04901                uint_t *log_list,
04902                uint_t log_entrys)
04903 {
04904     int ret ;
04905     buf_args sg_args ;
04906     sg_args.index = bufnum ;
04907     sg_args.size = log_entrys ;
04908 #ifdef WIN32
04909     sg_args.addr = (uint64_t) (log_list);
04910 #else
04911     sg_args.addr = (uint64_t) ((unsigned long) log_list);
04912 #endif
04913     ret = edt_ioctl(edt_p, EDTS_SGLIST, &sg_args);
04914 
04915     return ret;
04916 }
04917 
04918 u_int
04919 edt_set_sgbuf(EdtDev * edt_p, u_int sgbuf, u_int bufsize, u_int bufdir, u_int verbose)
04920 {
04921     edt_set_buffer_size(edt_p, sgbuf, bufsize, bufdir) ;
04922     return 0;
04923 }
04924 
04941 int
04942 edt_set_timeout_action(EdtDev * edt_p, u_int action)
04943 
04944 {
04945 
04946     if (!edt_p)
04947     {
04948         return -1;
04949 
04950     }
04951 
04952     edt_ioctl(edt_p, EDTS_TIMEOUT_ACTION, &action);
04953 
04954     return 0;
04955 }
04956 
04970 int
04971 edt_get_timeout_goodbits(EdtDev * edt_p)
04972 
04973 {
04974 
04975     u_int   nGoodBits;
04976 
04977     if (!edt_p)
04978     {
04979         return 0;
04980     }
04981 
04982     edt_ioctl(edt_p, EDTG_TIMEOUT_GOODBITS, &nGoodBits);
04983 
04984     return nGoodBits;
04985 }
04986 
05000 int
05001 edt_get_goodbits(EdtDev * edt_p)
05002 
05003 {
05004 
05005     u_int   nGoodBits;
05006 
05007     if (!edt_p)
05008     {
05009         return 0;
05010     }
05011 
05012     edt_ioctl(edt_p, EDTG_GOODBITS, &nGoodBits);
05013 
05014     return nGoodBits;
05015 }
05016 
05121 #ifdef _NT_
05122 
05123 int
05124 edt_get_kernel_event(EdtDev *edt_p, int event_type)
05125 
05126 {
05127     EdtEventHandler *p;
05128     char    fullname[128];
05129     char   *Name;
05130     char *edt_devname;
05131 
05132     if (edt_p == NULL 
05133         || (event_type < 0)
05134         || (event_type >= EDT_MAX_KERNEL_EVENTS)
05135         || ((Name = BaseEventNames[event_type]) == NULL)
05136         || ((p = &edt_p->event_funcs[event_type]) == NULL))
05137     {
05138         /* out of range */
05139         edt_msg(EDTDEBUG, "Invalid argument to edt_get_kernel_event\n");
05140         return -1;
05141     }
05142 
05143     switch(edt_p->devid)
05144     {
05145     case P11W_ID:
05146         edt_devname = "P11w";
05147         break;
05148 
05149     case P16D_ID:
05150         edt_devname = "P16d";
05151         break;
05152 
05153     case PCD20_ID:
05154     case PCD40_ID:
05155     case PCD60_ID:
05156     case PCD_16_ID:
05157     case PGP20_ID:
05158     case PGP40_ID:
05159     case PGP60_ID:
05160     case PGP_ECL_ID:
05161     case PSS4_ID:
05162     case PSS16_ID:
05163     case PGS4_ID:
05164     case PGS16_ID:
05165     case PCDA_ID:
05166     case PCDCL_ID:
05167     case PCDA16_ID:
05168     case PCDFCI_SIM_ID:
05169     case PCDFCI_PCD_ID:
05170     case PCDFOX_ID:
05171     case PE8LX1_ID:
05172     case PE8LX16_LS_ID:
05173     case PE8LX16_ID:
05174     case PE8LX64_ID:
05175     case PE4AMC16_ID:
05176          
05177         edt_devname = "Pcd";
05178         break;
05179 
05180     case PDV_ID:
05181     case PDVA_ID:
05182     case PDVA16_ID:
05183     case PGP_RGB_ID:
05184     case PDVK_ID:
05185     case PDVCL_ID:
05186     case PDVCL2_ID:
05187     case PE4DVCL_ID:
05188     case PE4DVFOX_ID:
05189     case PE8DVCL_ID:
05190     case PE8DVCLS_ID:
05191     case PE8DVFOX_ID:
05192     case PDV44_ID:
05193     case PDVFOI_ID:
05194     case PDVFCI_AIAG_ID:
05195     case PDVFCI_USPS_ID:
05196     case PDVFOX_ID:
05197     case PDVAERO_ID:
05198         edt_devname = "Pdv";
05199         break;
05200 
05201     case P53B_ID:
05202         edt_devname = "P53b";
05203         break;
05204 
05205     default:
05206         edt_devname = NULL;
05207         edt_msg(EDTDEBUG, "Unknown device type %d\n", edt_p->devid);
05208         return -1;
05209 
05210     }
05211 
05212     sprintf(fullname, "%s%s%d%d", edt_devname, Name, edt_p->unit_no, edt_p->channel_no);
05213 
05214     if ((p->wait_event =
05215         CreateEvent(NULL, FALSE, FALSE,fullname)) == NULL)
05216     {
05217         if ((p->wait_event =
05218             OpenEvent(SYNCHRONIZE, FALSE, fullname)) == NULL)
05219         {
05220 
05221             edt_msg(EDTDEBUG, "Unable to open event %s\n", fullname);
05222             edt_msg_perror(EDTFATAL, "event") ;
05223 
05224             return -1;
05225 
05226         }
05227         else
05228         {
05229             ResetEvent(p->wait_event) ;
05230             return(0) ;
05231         }
05232 
05233     }
05234     else
05235     {
05236         edt_buf argbuf ;
05237         argbuf.desc = event_type ;
05238         argbuf.value = (uint64_t)p->wait_event ;
05239         edt_ioctl(edt_p, EDTS_EVENT_HNDL, &argbuf);
05240         ResetEvent(p->wait_event) ;
05241     }
05242 
05243     return 0;
05244 
05245 }
05246 
05247 /********************************************************
05248 * Close everything and zero memory
05249 ********************************************************/
05250 
05251 static
05252 void
05253 edt_clear_event_func(EdtEventHandler * p)
05254 
05255 {
05256     if (p->wait_thread)
05257         CloseHandle(p->wait_thread);
05258     if (p->wait_event)
05259         CloseHandle(p->wait_event);
05260     if (p->closing_event)
05261         CloseHandle(p->closing_event);
05262 
05263     memset(p, 0, sizeof(*p));
05264 
05265 }
05266 
05267 /********************************************************/
05268 /* Thread function to wait on a particular driver event */
05269 /********************************************************/
05270 
05271 static u_int WINAPI
05272 edt_wait_event_thread(void *pObj)
05273 {
05274     EdtEventHandler *p = (EdtEventHandler *) pObj;
05275     int     rc = WAIT_OBJECT_0;
05276     HANDLE  events[2];
05277     u_int   tmp;
05278 
05279 
05280     if (p)
05281     {
05282         events[0] = p->wait_event;
05283         events[1] = p->closing_event;
05284 
05285         while (p->active)
05286         {
05287 
05288 #ifndef NEW_WAY
05289             rc = WaitForMultipleObjects(2, events, FALSE, INFINITE);
05290 #else
05291 
05292             edt_ioctl(p->owner, EDTS_WAIT_EVENT, &p->event_type);
05293 #endif
05294 
05295             if (p->active && rc == WAIT_OBJECT_0)
05296             {
05297                 edt_ioctl(p->owner, EDTS_CLR_EVENT, &p->event_type);
05298 
05299                 if (p->callback)
05300                     p->callback(p->data);
05301 
05302             }
05303 
05304             if (p->continuous == 0)
05305             {
05306                 edt_ioctl(p->owner, EDTS_DEL_EVENT_FUNC, &p->event_type);
05307 
05308                 /* May need this later -- Mark 01/99 */
05309                 tmp = p->thrdid;
05310                 /*p->active = 0 ;*/
05311                 edt_clear_event_func(p);
05312                 p->thrdid = tmp;
05313 
05314                 break;
05315             }
05316         }
05317     }
05318     return 0;
05319 }
05320 
05321 /* ****************************************************** */
05322 /* Add an event function for an event_type               */
05323 /* Name is derived from event type -                     */
05324 /* only works for "base events" defined for all boards   */
05325 /* ****************************************************** */
05326 
05327 int
05328 edt_set_event_func(EdtDev * edt_p, int event_type, EdtEventFunc func, void *data,
05329                    int continuous)
05330 {
05331     EdtEventHandler *p;
05332     char   *Name;
05333     HANDLE event;
05334 
05335     edt_msg(EDTDEBUG, "edt_set_event_func(type %d cont %d)\n", event_type, continuous);
05336 
05337     if (edt_p == NULL || (func == NULL)
05338         || (event_type < 0)
05339         || (event_type >= EDT_MAX_KERNEL_EVENTS)
05340         || ((Name = BaseEventNames[event_type]) == NULL)
05341         || ((p = &edt_p->event_funcs[event_type]) == NULL))
05342     {
05343         /* out of range */
05344         return -1;
05345     }
05346 
05347 
05348     if (p->callback)
05349     {
05350         /* whoops - we're already going */
05351 
05352         /* if it's the same callback, no problem */
05353 
05354         if (p->callback == func && p->data == data)
05355             return 0;
05356         else
05357             return -1;
05358     }
05359 
05360     /* Set the function */
05361     p->callback = func;
05362     /* Set the data */
05363     p->data = data;
05364 
05365     p->owner = edt_p;
05366     p->active = TRUE;
05367     p->event_type = event_type;
05368     p->continuous = continuous;
05369 
05370 
05371     /* Unlock */
05372 
05373     /* Launch the thread */
05374 
05375 
05376     edt_get_kernel_event(edt_p, event_type) ;
05377     event = edt_p->event_funcs[event_type].wait_event;
05378 
05379     if (event == NULL)
05380     {
05381         edt_clear_event_func(p);
05382         return -1;
05383 
05384     }
05385 
05386     if ((p->closing_event = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)
05387     {
05388         edt_clear_event_func(p);
05389         return -1;
05390     }
05391 
05392     if ((p->wait_thread = (thread_t)
05393         _beginthreadex(NULL, 0, edt_wait_event_thread, p, CREATE_SUSPENDED,
05394         &p->thrdid)) == NULL)
05395     {
05396         edt_clear_event_func(p);
05397         return -1;
05398     }
05399 
05400     /*
05401     * The continuous parameter now supports one of three modes:
05402     *
05403     *           EDT_EVENT_MODE_ONCE             (0)
05404     *           EDT_EVENT_MODE_CONTINUOUS       (1)
05405     *           EDT_EVENT_MODE_SERIALIZE        (2)
05406     *
05407     * The mode is passed to the driver in the high byte of event_type.
05408     */
05409     event_type |= ((continuous << EDT_EVENT_MODE_SHFT) & EDT_EVENT_MODE_MASK) ;
05410     edt_ioctl(edt_p, EDTS_ADD_EVENT_FUNC, &event_type);
05411     event_type &= ~EDT_EVENT_MODE_MASK ;
05412 
05413     ResumeThread(p->wait_thread);
05414 
05415     /*SetThreadPriority(p->wait_thread, THREAD_PRIORITY_HIGHEST);*/
05416 
05417     return 0;
05418 }
05419 
05420 int
05421 edt_remove_event_func(EdtDev * edt_p, int event_type)
05422 
05423 {
05424     EdtEventHandler *p;
05425 
05426     if (edt_p == NULL || event_type < 0 || event_type >= EDT_MAX_KERNEL_EVENTS)
05427     {
05428         /* out of range */
05429         return -1;
05430     }
05431 
05432     p = &edt_p->event_funcs[event_type];
05433 
05434     /*
05435     * Try and close the thread gracefully
05436     */
05437 
05438     if (p->wait_thread && p->wait_event)
05439     {
05440         p->active = FALSE;
05441 
05442         SetEvent(p->closing_event);
05443 
05444         edt_ioctl(edt_p, EDTS_DEL_EVENT_FUNC, &event_type);
05445 
05446         WaitForSingleObject(p->wait_thread, INFINITE);
05447 
05448         edt_clear_event_func(p);
05449 
05450     }else
05451         edt_clear_event_func(p);
05452 
05453     return 0;
05454 }
05455 
05456 #elif defined(__sun)            /* _NT_ */
05457 
05458 /* *******************************************************/
05459 /* Add an event function for an event_type               */
05460 /* Name is derived from event type                       */
05461 /* - only works for "base events" defined for all boards */
05462 /* *******************************************************/
05463 
05464 int
05465 edt_set_event_func(EdtDev * edt_p, int event_type, EdtEventFunc f, void *data,
05466                    int continuous)
05467 {
05468     EdtEventHandler *p;
05469     char    fullname[128];
05470     char   *Name;
05471 
05472 
05473     if (edt_p == NULL || (f == NULL)
05474         || (event_type < 0)
05475         || (event_type >= EDT_MAX_KERNEL_EVENTS)
05476         || ((Name = BaseEventNames[event_type]) == NULL)
05477         || ((p = &edt_p->event_funcs[event_type]) == NULL))
05478     {
05479         /* out of range */
05480         return -1;
05481     }
05482 
05483     if (p->active && p->callback)
05484     {
05485         /* whoops - we're already going */
05486         edt_remove_event_func(edt_p, event_type);
05487     }
05488     /*
05489     * Solaris:  if another thread has run for this event, wait for it.
05490     * Otherwise it stays alive and uses mmap() resources.  Mark  01/99
05491     */
05492     else if (p->thrdid)
05493         thr_join(p->thrdid, NULL, NULL);
05494 
05495     /* Set the function */
05496     p->callback = f;
05497     /* Set the data */
05498     p->data = data;
05499 
05500     p->owner = edt_p;
05501     p->active = TRUE;
05502     p->event_type = event_type;
05503     p->continuous = continuous;
05504 
05505     sema_init(&p->sema_thread, 0, USYNC_PROCESS, NULL);
05506 
05507     /*
05508     * The continuous parameter now supports one of three modes:
05509     *
05510     *           EDT_EVENT_MODE_ONCE             (0)
05511     *           EDT_EVENT_MODE_CONTINUOUS       (1)
05512     *           EDT_EVENT_MODE_SERIALIZE        (2)
05513     *
05514     * The mode is passed to the driver in the high byte of event_type.
05515     */
05516     event_type |= ((continuous << EDT_EVENT_MODE_SHFT) & EDT_EVENT_MODE_MASK) ;
05517     edt_ioctl(edt_p, EDTS_ADD_EVENT_FUNC, &event_type);
05518     event_type &= ~EDT_EVENT_MODE_MASK ;
05519 
05520     /* Launch the thread */
05521 
05522     sprintf(fullname, "%s%d%d", Name, edt_p->unit_no, edt_p->channel_no);
05523     if (thr_create(NULL, 0, edt_wait_event_thread, (void *) p,
05524         THR_NEW_LWP | THR_BOUND, &p->thrdid))
05525     {
05526         edt_msg_perror(EDTFATAL, "edt_set_event_func: thr_create");
05527         edt_msg(EDTWARN, "Unable to create eventthread %s\n", fullname);
05528         edt_msg(EDTWARN, "thr_create:  use \"-lthread\" compile option\n", stderr);
05529         return -1;
05530     }
05531 
05532     sema_wait(&p->sema_thread);
05533     thr_yield();
05534 
05535     return 0;
05536 }
05537 
05538 /********************************************************/
05539 /* Close everything and zero memory                      */
05540 /********************************************************/
05541 
05542 static
05543 void
05544 edt_clear_event_func(EdtEventHandler * p)
05545 
05546 {
05547     /* TODO - anything else need to be done here for solaris?  -- Mark 01/99 */
05548     memset(p, 0, sizeof(*p));
05549 }
05550 
05551 
05552 /********************************************************/
05553 /* Thread function to wait on a particular driver event */
05554 /********************************************************/
05555 
05556 static void *
05557 edt_wait_event_thread(void *pObj)
05558 
05559 {
05560     EdtEventHandler *p = (EdtEventHandler *) pObj;
05561     thread_t tmp;
05562     int     ret;
05563 
05564 #ifdef __sun
05565     if (p->owner->use_RT_for_event_func)
05566         edt_set_RT(1) ;         /* This isn't a good idea unless
05567                                 * you really can't live without it.  - Mark
05568                                 */
05569 #endif
05570 
05571     if (p)
05572     {
05573         while (p->active)
05574         {
05575             sema_post(&p->sema_thread);
05576             if (p->continuous == 0)
05577                 edt_ioctl(p->owner, EDTS_WAIT_EVENT_ONCE, &p->event_type);
05578             else
05579                 edt_ioctl(p->owner, EDTS_WAIT_EVENT, &p->event_type);
05580 
05581             if (p->active && p->callback)
05582                 p->callback(p->data);
05583 
05584             if (p->continuous == 0)
05585             {
05586                 edt_ioctl(p->owner, EDTS_DEL_EVENT_FUNC, &p->event_type);
05587 
05588                 /* Need this later for thr_join() in set_event_func() */
05589                 tmp = p->thrdid;
05590                 edt_clear_event_func(p);
05591                 p->thrdid = tmp;
05592 
05593                 break;
05594             }
05595         }
05596     }
05597 
05598     thr_exit(NULL);
05599 
05600     return pObj;
05601 }
05602 
05603 /* *******************************************************/
05604 /* Delete an event handler                               */
05605 /* *******************************************************/
05606 
05607 int
05608 edt_remove_event_func(EdtDev * edt_p, int event_type)
05609 {
05610     EdtEventHandler *p;
05611 
05612     if (edt_p == NULL || event_type < 0 || event_type >= EDT_MAX_KERNEL_EVENTS)
05613     {
05614         /* out of range */
05615         return -1;
05616     }
05617 
05618     p = &edt_p->event_funcs[event_type];
05619 
05620     /*
05621     * Try and close the thread gracefully
05622     */
05623 
05624     if (p->active)
05625     {
05626         p->active = FALSE;
05627 
05628         edt_ioctl(edt_p, EDTS_DEL_EVENT_FUNC, &event_type);
05629 
05630         thr_join(p->thrdid, NULL, NULL);
05631 
05632         edt_clear_event_func(p);
05633     }
05634 
05635     return 0;
05636 }
05637 #elif defined(sgi) || defined(__linux__) || defined(__APPLE__)
05638 
05639 #ifndef NO_PTHREAD
05640 
05641 #include <pthread.h>
05642 
05643 /* *******************************************************/
05644 /* Add an event function for an event_type               */
05645 /* Name is derived from event type                       */
05646 /* - only works for "base events" defined for all boards */
05647 /* *******************************************************/
05648 
05649 int
05650 edt_set_event_func(EdtDev * edt_p, int event_type, EdtEventFunc f, void *data,
05651                    int continuous)
05652 {
05653     EdtEventHandler *p;
05654     char    fullname[128];
05655     char   *Name;
05656 
05657 
05658     if (edt_p == NULL || (f == NULL)
05659         || (event_type < 0)
05660         || (event_type >= EDT_MAX_KERNEL_EVENTS)
05661         || ((Name = BaseEventNames[event_type]) == NULL)
05662         || ((p = &edt_p->event_funcs[event_type]) == NULL))
05663     {
05664         /* out of range */
05665         return -1;
05666     }
05667 
05668     if (p->active && p->callback)
05669     {
05670         /* whoops - we're already going */
05671         edt_remove_event_func(edt_p, event_type);
05672     }
05673     /*
05674     * pthreads:  if another thread has run for this event, wait for it.
05675     * Otherwise it stays alive and uses mmap() resources.  Mark  01/99
05676     */
05677     else if (p->thrdid)
05678         pthread_join(p->thrdid, NULL);
05679 
05680     /* Set the function */
05681     p->callback = f;
05682     /* Set the data */
05683     p->data = data;
05684 
05685     p->owner = edt_p;
05686     p->active = TRUE;
05687     p->event_type = event_type;
05688     p->continuous = continuous;
05689 
05690 
05691     /* sema_init(&p->sema_thread, 0, USYNC_PROCESS, NULL); */
05692 
05693     /*
05694     * The continuous parameter now supports one of three modes:
05695     *
05696     *           EDT_EVENT_MODE_ONCE             (0)
05697     *           EDT_EVENT_MODE_CONTINUOUS       (1)
05698     *           EDT_EVENT_MODE_SERIALIZE        (2)
05699     *
05700     * The mode is passed to the driver in the high byte of event_type.
05701     */
05702     event_type |= ((continuous << EDT_EVENT_MODE_SHFT) & EDT_EVENT_MODE_MASK) ;
05703     edt_ioctl(edt_p, EDTS_ADD_EVENT_FUNC, &event_type);
05704     event_type &= ~EDT_EVENT_MODE_MASK ;
05705 
05706     /* Launch the thread */
05707 
05708     sprintf(fullname, "%s%d%d", Name, edt_p->unit_no, edt_p->channel_no);
05709     if (pthread_create(&p->thrdid, 0, edt_wait_event_thread, (void *) p)
05710         != 0)
05711     {
05712         edt_msg_perror(EDTFATAL, "edt_set_event_func: thr_create");
05713         edt_msg(EDTWARN, "Unable to create eventthread %s\n", fullname);
05714         edt_msg(EDTWARN, "thr_create:  use \"-lthread\" compile option\n", stderr);
05715         return -1;
05716     }
05717 
05718     /* sema_wait(&p->sema_thread); */
05719     /* thr_yield(); */
05720 
05721     return 0;
05722 }
05723 
05724 /********************************************************/
05725 /* Close everything and zero memory                      */
05726 /********************************************************/
05727 
05728 static
05729 void
05730 edt_clear_event_func(EdtEventHandler * p)
05731 
05732 {
05733     /* TODO - anything else need to be done here for solaris?  -- Mark 01/99 */
05734     memset(p, 0, sizeof(*p));
05735 }
05736 
05737 
05738 /********************************************************/
05739 /* Thread function to wait on a particular driver event */
05740 /********************************************************/
05741 
05742 static void *
05743 edt_wait_event_thread(void *pObj)
05744 
05745 {
05746     EdtEventHandler *p = (EdtEventHandler *) pObj;
05747     pthread_t tmp;
05748 
05749     if (p)
05750     {
05751         while (p->active)
05752         {
05753             /* sema_post(&p->sema_thread); */
05754             if (p->continuous == 0)
05755                 edt_ioctl(p->owner, EDTS_WAIT_EVENT_ONCE, &p->event_type);
05756             else
05757                 edt_ioctl(p->owner, EDTS_WAIT_EVENT, &p->event_type);
05758 
05759             if (p->active && p->callback)
05760                 p->callback(p->data);
05761 
05762             if (p->continuous == 0)
05763             {
05764                 edt_ioctl(p->owner, EDTS_DEL_EVENT_FUNC, &p->event_type);
05765 
05766                 /* Need this later for thr_join() in set_event_func() */
05767                 tmp = p->thrdid;
05768                 edt_clear_event_func(p);
05769                 p->thrdid = tmp;
05770 
05771                 break;
05772             }
05773         }
05774     }
05775 
05776     pthread_exit(NULL);
05777 
05778     return pObj;
05779 }
05780 
05781 /* *******************************************************/
05782 /* Delete an event handler                               */
05783 /* *******************************************************/
05784 
05785 int
05786 edt_remove_event_func(EdtDev * edt_p, int event_type)
05787 {
05788     EdtEventHandler *p;
05789 
05790     if (edt_p == NULL || event_type < 0 || event_type >= EDT_MAX_KERNEL_EVENTS)
05791     {
05792         /* out of range */
05793         return -1;
05794     }
05795 
05796     p = &edt_p->event_funcs[event_type];
05797 
05798     /*
05799     * Try and close the thread gracefully
05800     */
05801 
05802     if (p->active)
05803     {
05804         p->active = FALSE;
05805 
05806         edt_ioctl(edt_p, EDTS_DEL_EVENT_FUNC, &event_type);
05807 
05808         pthread_join(p->thrdid, NULL);
05809 
05810         edt_clear_event_func(p);
05811     }
05812 
05813     return 0;
05814 }
05815 #endif   /* NOT PTHREAD */
05816 
05817 #elif defined(_AIX) || defined(__hpux)
05818 
05819 /* *******************************************************
05820 * Add an event function for an event_type
05821 * Name is derived from event type - only works
05822 * for "base events" defined for all boards
05823 * *******************************************************/
05824 
05825 int
05826 edt_set_event_func(EdtDev * edt_p, int event_type, EdtEventFunc f, void *data,
05827                    int continuous)
05828 {
05829     return -1;
05830 }
05831 
05832 /********************************************************
05833 * Close everything and zero memory
05834 ********************************************************/
05835 
05836 static
05837 void
05838 edt_clear_event_func(EdtEventHandler * p)
05839 
05840 {
05841 
05842 }
05843 
05844 
05845 /********************************************************
05846 * Thread function to wait on a particular driver event *
05847 ********************************************************/
05848 
05849 static void *
05850 edt_wait_event_thread(void *pObj)
05851 
05852 {
05853     return NULL;
05854 }
05855 
05856 /* *******************************************************
05857 * Delete an event handler                                                               *
05858 * *******************************************************/
05859 
05860 int
05861 edt_remove_event_func(EdtDev * edt_p, int event_type)
05862 {
05863     return -1;
05864 }
05865 
05866 #else
05867 
05868 int
05869 edt_remove_event_func(EdtDev * edt_p, int event_type)
05870 {
05871     return -1;
05872 }
05873 
05874 #endif                          /* _NT_ */
05875 
05876 int
05877 edt_enable_event(EdtDev * edt_p, int event_type)
05878 {
05879     edt_msg(EDTDEBUG, "edt_enable_event(type %d)\n", event_type) ;
05880 
05881     if (edt_p == NULL 
05882         || (event_type < 0)
05883         || (event_type >= EDT_MAX_KERNEL_EVENTS))
05884     {
05885         /* out of range */
05886         return -1;
05887     }
05888 
05889 #ifdef _NT_
05890     edt_get_kernel_event(edt_p, event_type) ;
05891 #endif
05892 
05893     edt_ioctl(edt_p, EDTS_ADD_EVENT_FUNC, &event_type);
05894 
05895     return 0 ;
05896 }
05897 
05898 int
05899 edt_wait_event(EdtDev * edt_p, int event_type, int timeoutval)
05900 {
05901     int ret = 0 ;
05902     edt_msg(EDTDEBUG, "edt_wait_event(type %d)\n", event_type) ;
05903 #ifdef _NT_
05904     {
05905         HANDLE event;
05906         int rc;
05907 
05908         if (!edt_p->event_funcs[event_type].wait_event)
05909         {
05910             edt_get_kernel_event(edt_p, event_type);
05911         }
05912 
05913         event = edt_p->event_funcs[event_type].wait_event;
05914 
05915         /* wait for event */
05916 
05917         if (timeoutval == 0)
05918             timeoutval = INFINITE;
05919 
05920         rc = WaitForSingleObject(event, timeoutval);
05921 
05922         if (rc == WAIT_TIMEOUT)
05923         {
05924             /* edt_msg(EDTDEBUG, "timeout...\n");*/
05925 
05926             /* deal with timeout */
05927 
05928             edt_do_timeout(edt_p);
05929 
05930             ret = 1 ;
05931         }
05932     }
05933 #else
05934     edt_ioctl(edt_p, EDTS_WAIT_EVENT, &event_type);
05935 #endif
05936 
05937     edt_msg(EDTDEBUG, "edt_wait_event(type %d)\n", event_type, ret) ;
05938 
05939     return(ret) ;
05940 }
05941 
05942 
05947 int
05948 edt_reset_event_counter(EdtDev * edt_p, int event_type)
05949 {
05950     return edt_ioctl(edt_p, EDTS_RESET_EVENT_COUNTER, &event_type);
05951 }
05952 
05953 
05954 
05966 int
05967 edt_stop_buffers(EdtDev * edt_p)
05968 
05969 {
05970     unsigned int finish_current = 1;
05971 
05972     edt_msg(EDTDEBUG, "edt_stop_buffers\n");
05973     edt_ioctl(edt_p, EDTS_STOPBUF, &finish_current);
05974     return 0;
05975 }
05976 
05993 int
05994 edt_reset_ring_buffers(EdtDev * edt_p, uint_t bufnum)
05995 
05996 {
05997     bufcnt_t     curdone;
05998     int     curbuf = -1;
05999 
06000     curdone = edt_done_count(edt_p);
06001     edt_cancel_current_dma(edt_p);
06002     if (edt_p->ring_buffer_numbufs)
06003     {
06004         curbuf = curdone % edt_p->ring_buffer_numbufs;
06005         edt_set_buffer(edt_p, bufnum);
06006     }
06007     edt_msg(EDTDEBUG, "edt_reset_ring_buffers buf %d curdone %d curbuf %d\n",
06008         bufnum, curdone, curbuf);
06009     return 0;
06010 }
06011 
06025 int
06026 edt_abort_dma(EdtDev * edt_p)
06027 
06028 {
06029     edt_msg(EDTDEBUG, "edt_abort_dma\n");
06030     edt_reset_ring_buffers(edt_p, edt_done_count(edt_p));
06031     return 0;
06032 }
06033 
06047 int
06048 edt_abort_current_dma(EdtDev * edt_p)
06049 
06050 {
06051     edt_msg(EDTDEBUG, "edt_abort_current_dma\n");
06052     edt_reset_ring_buffers(edt_p, edt_done_count(edt_p) + 1);
06053     return 0;
06054 }
06055 
06066 int
06067 edt_ring_buffer_overrun(EdtDev *edt_p)
06068 
06069 {
06070     bufcnt_t   dmacount;
06071 
06072     dmacount = edt_done_count(edt_p);
06073 
06074     if (dmacount >= edt_p->donecount + edt_p->ring_buffer_numbufs)
06075         return (1);
06076     else
06077         return (0);
06078 }
06079 
06080 
06081 #ifdef P16D
06082 
06093 u_short
06094 p16d_get_command(EdtDev * edt_p)
06095 {
06096     return (edt_reg_read(edt_p, P16_COMMAND));
06097 }
06098 
06110 void
06111 p16d_set_command(EdtDev * edt_p, u_short val)
06112 {
06113     edt_reg_write(edt_p, P16_COMMAND, val);
06114 }
06115 
06126 u_short
06127 p16d_get_config(EdtDev * edt_p)
06128 {
06129     return (edt_reg_read(edt_p, P16_CONFIG));
06130 }
06131 
06143 void
06144 p16d_set_config(EdtDev * edt_p, u_short val)
06145 {
06146     edt_reg_write(edt_p, P16_CONFIG, val);
06147 }
06148 
06159 u_short
06160 p16d_get_stat(EdtDev * edt_p)
06161 {
06162     return (edt_reg_read(edt_p, P16_STATUS));
06163 }
06164 
06165 #endif                          /* P16D */
06166 
06167 
06182 int
06183 edt_parse_unit_channel(const char *instr, 
06184                        char *dev, 
06185                        const char *default_dev,
06186                        int *channel_ptr)
06187 {
06188     int     unit = -1;
06189     int         channel = -1;
06190     size_t              last;
06191 
06192     char    retdev[256];
06193     char    str[256];
06194 
06195 
06196     edt_msg(EDTDEBUG, "edt_parse_unit_channel %s dev %s default %s: ", 
06197         instr, dev, default_dev);
06198 
06199     if (default_dev)
06200         strcpy(retdev, default_dev);
06201     else
06202         strcpy(retdev, EDT_INTERFACE);
06203 
06204     strcpy(str,instr);
06205 
06206     if (strlen(str))
06207     {
06208         last = strlen(str)-1;
06209 
06210         /* find the channel or unit */
06211 
06212         if (isdigit(str[last]))
06213         {
06214             while (last && isdigit(str[last]))
06215             {
06216                 last--;
06217             }
06218 
06219             if (!isdigit(str[last]))
06220             {
06221                 last++;
06222             }
06223 
06224             channel = atoi(str+last);
06225 
06226             if (str[0] != '/' && str[0] != '\\')
06227                 str[last] = 0;
06228 
06229             if (last>0)
06230                 last--;
06231 
06232             if (last && str[last] == '_')
06233             {
06234 
06235                 last--;
06236 
06237                 if (isdigit(str[last]))
06238                 {
06239                     size_t enddigit = last;
06240                     char checkstr[80];
06241 
06242                     while (last && isdigit(str[last]))
06243                     {
06244                         last--;
06245                     }
06246 
06247                     if (!isdigit(str[last]))
06248                     {
06249                         last++;
06250                     }
06251 
06252                     strncpy(checkstr,str+last,(enddigit - last)+1);
06253 
06254                     unit = atoi(checkstr);
06255 
06256                     if (str[0] != '/' && str[0] != '\\')
06257                         str[last] = 0;
06258 
06259                 }       
06260                 else
06261                 {
06262                     unit = channel;
06263                     channel = -1;
06264                 }
06265             }
06266             else
06267             {
06268                 unit = channel;
06269                 channel = -1;
06270             }
06271 
06272         }
06273         else
06274             unit = 0;
06275     }
06276     else
06277         unit = 0;
06278     
06279     if (str[0])
06280         strcpy(retdev, str);
06281 
06282     strcpy(dev, retdev);
06283 
06284     if (channel_ptr && (channel != -1))
06285         *channel_ptr = channel;
06286 
06287     return (unit);
06288 }
06289 
06318 int
06319 edt_parse_unit(const char *str, char *dev, const char *default_dev)
06320 {
06321     int channel = 0;
06322 
06323     return edt_parse_unit_channel(str,dev,default_dev, &channel);
06324 
06325 
06326 }
06327 int
06328 edt_serial_wait(EdtDev * edt_p, int msecs, int count) 
06329 {
06330     edt_buf tmp;
06331     int     ret;
06332 
06333     tmp.desc = msecs;
06334     tmp.value = count;
06335     edt_ioctl(edt_p, EDTS_SERIALWAIT, &tmp);
06336     ret = (u_int) tmp.value;
06337 
06338     edt_msg(EDTDEBUG, "edt_serial_wait(%d, %d) %d\n", msecs, count, ret);
06339     return (ret);
06340 }
06341 
06375 int                        
06376 edt_ref_tmstamp(EdtDev *edt_p, u_int val)
06377 
06378 {
06379     return edt_ioctl(edt_p,EDTS_REFTMSTAMP,&val);
06380 
06381 }
06382 
06383 uint_t
06384 edt_get_bufbytecount(EdtDev * edt_p, u_int *cur_buffer)
06385 {
06386     uint_t args[2] ;
06387 
06388     if (edt_ioctl(edt_p, EDTG_BUFBYTECOUNT, &args) < 0)
06389         edt_msg_perror(EDTFATAL, "edt_ioctl(EDTG_BUFBYTECOUNT)");
06390 
06391     if (cur_buffer)
06392         *cur_buffer = args[1] ;
06393     return (args[0]);
06394 }
06395 
06396 
06397 void
06398 edt_dmasync_fordev(EdtDev *edt, int bufnum, int offset, int bytecount)
06399 {
06400     u_int args[3] ;
06401 
06402     args[0] = bufnum ;
06403     args[1] = offset ;
06404     args[2] = bytecount ;
06405 
06406     edt_ioctl(edt, EDTS_DMASYNC_FORDEV, args) ;
06407 }
06408 
06409 void
06410 edt_dmasync_forcpu(EdtDev *edt, int bufnum, int offset, int bytecount)
06411 {
06412     u_int args[3] ;
06413 
06414     args[0] = bufnum ;
06415     args[1] = offset ;
06416     args[2] = bytecount ;
06417 
06418     edt_ioctl(edt, EDTS_DMASYNC_FORCPU, args) ;
06419 }
06420 
06421 /* return true if machine is little_endian */
06422 int
06423 edt_little_endian()
06424 {
06425     u_short test;
06426     u_char *byte_p;
06427 
06428     byte_p = (u_char *) & test;
06429     *byte_p++ = 0x11;
06430     *byte_p = 0x22;
06431     if (test == 0x1122)
06432     {
06433         edt_msg(EDTDEBUG, "edt_endian: BIG (SPARC, PowerPC)\n");
06434         return (0);
06435     }
06436     else
06437     {
06438         edt_msg(EDTDEBUG, "edt_endian: LITTLE (X86, AMD, SPARCv9)\n");
06439         return (1);
06440     }
06441 }
06442 
06475 int
06476 edt_set_buffer_size(EdtDev * edt_p, uint_t index, uint_t size, uint_t write_flag)
06477 
06478 {
06479 
06480     buf_args sysargs;
06481 
06482     if (edt_p->ring_buffers[index])
06483     {
06484         if (size > (u_int) edt_p->rb_control[index].allocated_size)
06485         {
06486             edt_msg_perror(EDTFATAL, "edt_set_buffer_size: Attempt to set size greater than allocated\n");
06487             return -1;
06488         }
06489 
06490         edt_p->rb_control[index].size = size;
06491         sysargs.index = index;
06492         sysargs.writeflag = write_flag;
06493         sysargs.addr = 0;
06494         sysargs.size = size;
06495 
06496         return edt_ioctl(edt_p, EDTS_BUF, &sysargs);
06497 
06498     }
06499     else
06500     {
06501         edt_msg_perror(EDTFATAL, "edt_set_buffer_size: Attempt to set size on unallocated buffer\n");
06502 
06503         return -1;
06504     }
06505 }
06506 
06523 int
06524 edt_set_max_buffers(EdtDev *edt_p, int newmax)
06525 
06526 {
06527     edt_msg(EDTDEBUG, "edt_set_max_buffers\n");
06528 
06529     return 
06530         edt_ioctl(edt_p, EDTS_MAX_BUFFERS, &newmax);
06531 }
06532 
06546 int
06547 edt_get_max_buffers(EdtDev *edt_p)
06548 
06549 {
06550     u_int val;
06551 
06552     if (edt_p->devid == DMY_ID) val = MAX_DMA_BUFFERS ;
06553     else edt_ioctl(edt_p, EDTG_MAX_BUFFERS, &val);
06554 
06555     return val;
06556 
06557 }
06558 
06559 
06560 void
06561 edt_resume(EdtDev * edt_p)
06562 {
06563     u_int dmy ;
06564 
06565     edt_msg(EDTDEBUG, "edt_resume\n") ;
06566     edt_ioctl(edt_p, EDTS_RESUME, &dmy);
06567 }
06568 
06593 uint_t
06594 edt_get_todo(EdtDev * edt_p)
06595 {
06596     u_int todo ;
06597     if (edt_p->devid == DMY_ID)
06598         todo = dmy_started ;
06599     else
06600         edt_ioctl(edt_p, EDTG_TODO, &todo);
06601     edt_msg(EDTDEBUG, "edt_get_todo: %d\n",todo) ;
06602     return todo;
06603 }
06604 
06605 uint_t
06606 edt_get_drivertype(EdtDev * edt_p)
06607 {
06608     u_int type ;
06609     edt_ioctl(edt_p, EDTG_DRIVER_TYPE, &type);
06610     edt_msg(EDTDEBUG, "edt_get_drivertype: %x\n",type) ;
06611     return type;
06612 }
06613 
06614 /* only for testing */
06615 int
06616 edt_set_drivertype(EdtDev *edt_p, u_int type)
06617 {
06618     edt_msg(EDTDEBUG, "edt_set_drivertype\n");
06619     return edt_ioctl(edt_p, EDTS_DRIVER_TYPE, &type);
06620 }
06621 
06645 int
06646 edt_get_reftime(EdtDev * edt_p, u_int * timep) 
06647 {
06648     /* we return sec and nsec - change to usec */
06649     u_int   timevals[2];
06650 
06651     edt_ioctl(edt_p, EDTG_REFTIME, &timevals[0]);
06652     edt_msg(EDTDEBUG, "%x %x ",
06653         timevals[0],
06654         timevals[1]) ;
06655     timep[0] = timevals[0];
06656     timep[1] = timevals[1];
06657     return (timevals[1]) ;
06658 }
06659 
06660 void
06661 edt_set_timetype(EdtDev * edt_p, u_int type)
06662 {
06663     edt_ioctl(edt_p, EDTS_TIMETYPE, &type);
06664 }
06665 
06666 void
06667 edt_set_abortintr(EdtDev * edt_p, u_int val)
06668 {
06669     edt_ioctl(edt_p, EDTS_ABORTINTR, &val);
06670 }
06671 
06672 
06673 caddr_t
06674 edt_mapmem(EdtDev *edt_p, u_int addr, int size)
06675 {
06676     caddr_t     ret;
06677 #if defined(VXWORKS) || defined(_NT_) || defined(__APPLE__)
06678     edt_buf tmp;
06679 
06680     tmp.value = size;
06681     tmp.desc = addr;
06682 
06683     edt_ioctl(edt_p, EDTS_MAPMEM, &tmp);
06684     /* KLUDGE */
06685     ret = (caddr_t) tmp.desc ;
06686     edt_msg(EDTDEBUG, "edt_mapmem(%x, %x) %x %x\n", addr, size, tmp.desc,tmp.value);
06687     return (ret);
06688 #else
06689     ret = (caddr_t) mmap((caddr_t)0, size, PROT_READ|PROT_WRITE,
06690         MAP_SHARED, edt_p->fd, addr);
06691     if (ret == ((caddr_t)-1)) {
06692         perror("mmap call");
06693         return(0) ;
06694     }
06695     return(ret) ;
06696 #endif
06697 }
06698 
06699 u_int edt_get_mappable_size(EdtDev *edt_p)
06700 
06701 {
06702     u_int value = 0;
06703 
06704     edt_ioctl(edt_p, EDTG_MEMSIZE, &value);
06705 
06706     return value;
06707 
06708 }
06709 
06710 
06711 #ifdef __sun
06712 
06718 static id_t
06719 schedinfo(char *name, short *maxpri)
06720 {
06721     pcinfo_t info;
06722     tsinfo_t *tsinfop;
06723     rtinfo_t *rtinfop;
06724 
06725     (void) strcpy(info.pc_clname, name);
06726     if (priocntl(0L, 0L, PC_GETCID, (char *) &info) == -1L)
06727     {
06728         return (-1);
06729     }
06730     if (strcmp(name, "TS") == 0)
06731     {
06732         tsinfop = (struct tsinfo *) info.pc_clinfo;
06733         *maxpri = tsinfop->ts_maxupri;
06734     }
06735     else if (strcmp(name, "RT") == 0)
06736     {
06737         rtinfop = (struct rtinfo *) info.pc_clinfo;
06738         *maxpri = rtinfop->rt_maxpri;
06739     }
06740     else
06741     {
06742         return (-1);
06743     }
06744     return (info.pc_cid);
06745 }
06746 
06751 void
06752 edt_set_RT(u_int pri)
06753 {
06754     pcparms_t pcparms;
06755     rtparms_t *rtparmsp;
06756     id_t    rtID;
06757     short   maxrtpri;
06758 
06759     /* Get highest valid RT priority. */
06760     if ((rtID = schedinfo("RT", &maxrtpri)) == -1)
06761     {
06762         edt_msg_perror(EDTFATAL, "schedinfo failed for RT");
06763         exit(2);
06764     }
06765 
06766     /* Change proc to RT, highest prio - 1, default time slice */
06767     pcparms.pc_cid = rtID;
06768     rtparmsp = (struct rtparms *) pcparms.pc_clparms;
06769     rtparmsp->rt_pri = maxrtpri - (1 + pri) ;
06770     rtparmsp->rt_tqnsecs = RT_TQDEF;
06771 
06772     if (priocntl(P_LWPID, P_MYID, PC_SETPARMS, (char *) &pcparms) == -1)
06773     {
06774         edt_msg_perror(EDTFATAL, "PC_SETPARMS failed");
06775         exit(3);
06776     }
06777 }
06778 #endif /* __sun */
06779 
06780 
06781 #ifdef PCD
06782 /*
06783 * SSE (fast serial) support.
06784 */
06785 
06786 /* These bits are in hi word of long, must split into two to do AND's, OR's */
06787 #define XPLLBYP (0x1<<17)
06788 #define XPLLCLK (0x1<<18)
06789 #define XPLLDAT (0x1<<19)
06790 #define XPLLSTB (0x1<<20)
06791 
06792 #define XC_X16  (0x00)          /* PC Only: hi for SCLK=16MHz, not SCLK=CCLK */
06793 #define XC_AVSEL (0x80)         /* GP Only: hi for SCLK=AVCLK, not SCLK=16MHz*/
06794 
06795 #define XC_CCLK (0x01)          /* These codes interpreted by sse_wpp() */
06796 #define XC_DIN  (0x02)          /*  Xilinx config data and clock */
06797 #define XC_PROG (0x04)          /*  inverted in sse_wpp() when driving PROGL */
06798 #define XC_INITL (0x04)         /* Actual bit positions in status register */
06799 #define XC_DONE  (0x08)
06800 
06801 /* Write encoded data to parallel port data register */
06802 static void
06803 sse_wpp(EdtDev *edt_p, int val)
06804 {
06805     unsigned char bits;
06806 
06807     bits = edt_intfc_read(edt_p, PCD_FUNCT) & 0x08;     /* Preserve SWAPEND */
06808 
06809     if (val & XC_DIN)   bits |= 0x04;
06810     if (val & XC_PROG)  bits |= 0x01;
06811     if (val & XC_AVSEL) bits |= 0x80;
06812 
06813     edt_intfc_write(edt_p, PCD_FUNCT, bits);
06814 
06815     if (val & XC_CCLK)          /* strobe the clock hi then low */
06816     {
06817         edt_intfc_write(edt_p, PCD_FUNCT, (unsigned char) (bits | 0x02));
06818         edt_intfc_write(edt_p, PCD_FUNCT, bits);
06819     }
06820 
06821     edt_msg(EDTDEBUG, "sse_wpp(%02x)  ", bits);
06822 }
06823 
06824 
06825 static int
06826 sse_spal(EdtDev * edt_p, int v)
06827 {
06828     edt_msleep(1);
06829     edt_intfc_write(edt_p, PCD_PAL0, (unsigned char) (v >> 0));
06830     edt_intfc_write(edt_p, PCD_PAL1, (unsigned char) (v >> 8));
06831     edt_intfc_write(edt_p, PCD_PAL2, (unsigned char) (v >> 16));
06832 
06833     return (edt_intfc_read(edt_p, PCD_PAL3));
06834 }
06835 
06836 static void
06837 sse_xosc(EdtDev * edt_p, int val)
06838 {
06839     int     n, s;       /* First set up MC12430 lines, CLK=0, DAT=0, STB=0 */
06840     int   gspv = edt_intfc_read(edt_p, PCD_PAL0)
06841         | edt_intfc_read(edt_p, PCD_PAL1) << 8 
06842         | edt_intfc_read(edt_p, PCD_PAL2) << 16;
06843 
06844     gspv = (gspv & ~XPLLBYP & ~XPLLCLK & ~XPLLDAT & ~XPLLSTB);
06845     sse_wpp(edt_p, 0);
06846 
06847     edt_msleep(1);              /* Shut down AVSEL */
06848 
06849     for (n = 13; n >= 0; n--)
06850     {                           /* Send 14 bits of data to MC12430 */
06851         s = val & (0x1 << n);   /* get the current data bit */
06852 
06853         if (s)
06854         {
06855             sse_spal(edt_p, gspv | XPLLDAT);    /* Set up data, then clock it */
06856             sse_spal(edt_p, gspv | XPLLDAT | XPLLCLK);
06857         }
06858         else
06859         {
06860             sse_spal(edt_p, gspv);      /* Strobe clock only, no data */
06861             sse_spal(edt_p, gspv | XPLLCLK);
06862         }
06863 
06864         edt_msg(EDTDEBUG, "sse_xosc:  n:%d  s:%x\n", n, (s != 0));
06865     }
06866 
06867     sse_spal(edt_p, gspv | XPLLSTB);    /* Strobe serial_load */
06868     sse_spal(edt_p, gspv);              /* Clear the strobe */
06869 
06870 
06871     if ((val >> 11) == 6)
06872     {
06873         gspv |= XPLLBYP;
06874         sse_spal(edt_p, gspv);
06875 
06876         sse_wpp(edt_p, XC_AVSEL);       /* On GP, drive SCLK from AV9110 */
06877     }
06878     else
06879         sse_wpp(edt_p, 0);
06880 
06881 
06882     if (XC_X16)
06883         sse_wpp(edt_p, XC_X16);         /* On PC, drive SCLK with 16 MHz ref */
06884 }
06885 
06886 
06887 double
06888 sse_set_out_clk(EdtDev * edt_p, double fmhz)
06889 {                               /* Set ECL clock to freq specified in MHz */
06890     int     m, n, t, hex, nn, fx;
06891     edt_pll avp;
06892     double  avf = 0.0; /* should this have a more reasonable value? --doug */
06893 
06894     if (fmhz < 0)
06895     {
06896         printf("sse_set_pll_freq: Invalid argument %f\n", fmhz);
06897         return 0;
06898     }
06899 
06900     fx = (int) fmhz;
06901 
06902     if ((fmhz > 800.0) || (fmhz < 0.000050))
06903     {
06904         printf("Error, %f MHz requested.  Min of 0.000050, max of 800Mhz\n",
06905             fmhz);
06906         return (0);
06907     }
06908     else if (fx > 400)
06909     {
06910         t = 0;
06911         n = 3;
06912         m = fx / 2;
06913         nn = 1;
06914     }                           /* Every 2 MHz */
06915     else if (fx > 200)
06916     {
06917         t = 0;
06918         n = 0;
06919         m = fx;
06920         nn = 2;
06921     }                           /* Every 1 MHz */
06922     else if (fx > 100)
06923     {
06924         t = 0;
06925         n = 1;
06926         m = fx * 2;
06927         nn = 4;
06928     }                           /* Every 500 KHz */
06929     else if (fx >= 50)
06930     {
06931         t = 0;
06932         n = 2;
06933         m = fx * 4;
06934         nn = 8;
06935     }                           /* Every 250 KHz */
06936     else
06937     {
06938         avf = edt_find_vco_frequency(edt_p, fmhz * 1E6, (double) 30E6, &avp, 0);
06939         if (avf != 0)
06940             edt_set_out_clk(edt_p, &avp);       /* Load AV9110 */
06941         t = 6;
06942         n = 3;
06943         m = 200;
06944         nn = 4;                 /* Put MC12430 in bypass, use AV9110 */
06945     }
06946 
06947     hex = (t << 11) | (n << 9) | m;
06948 
06949     sse_xosc(edt_p, hex);       /* Load MC12430 hw */
06950 
06951     if (t != 6)
06952     {
06953         edt_msg(EDTDEBUG,
06954             "sse_set_out_clk:  %f MHz  MC12430: t:%d  n:%d  m:%d  hex:0x%04x\n",
06955             (2.0 * m / nn), t, n, m, hex);
06956         return (2.0 * m / nn);  /* Freq of MC12430 in MHz */
06957     }
06958     else
06959     {
06960         edt_msg(EDTDEBUG,
06961             "sse_set_out_clk: %f MHz AV9110:  m:%d n:%d v:%d r:%d h:%d l:%d x:%d\n",
06962             (avf / 1E6), avp.m, avp.n, avp.v, avp.r, avp.h, avp.l, avp.x);
06963         return (avf / 1E6);     /* Freq of AV9110 in MHz */
06964     }
06965 }
06966 
06967 
06968 
06969 
06970 void
06971 sse_shift(EdtDev *edt_p, int shift)
06972 {
06973     int n ;
06974     unsigned char  old;
06975 
06976     if (shift)
06977     {
06978         old = edt_intfc_read(edt_p, PCD_PAL1) & ~0x02;
06979         edt_intfc_write(edt_p, PCD_PAL1, old);
06980 
06981         for (n = 0; n < shift; n++)
06982         {
06983             edt_msleep(1);
06984             edt_intfc_write(edt_p, PCD_PAL1, (unsigned char) (0x02 | old));
06985             edt_msleep(1);
06986             edt_intfc_write(edt_p, PCD_PAL1, old);
06987         }
06988     }
06989 }
06990 /*
06991 To swallow a clock on channel 0, strobe bit 9,  so PCD_PAL1 0x02
06992 To swallow a clock on channel 1, strobe bit 21, so PCD_PAL2 0x20
06993 */
06994 void
06995 sse_shift_chan(EdtDev *edt_p, int shift, int channel)
06996 {
06997     int n ;
06998     unsigned char  old;
06999 
07000     if (shift) {
07001         if (channel==0) {
07002             old = edt_intfc_read(edt_p, PCD_PAL1) & ~0x02;
07003             edt_intfc_write(edt_p, PCD_PAL1, old);
07004 
07005             for (n = 0; n < shift; n++)
07006             {
07007                 edt_msleep(1);
07008                 edt_intfc_write(edt_p, PCD_PAL1, (unsigned char) (0x02 | old));
07009                 edt_msleep(1);
07010                 edt_intfc_write(edt_p, PCD_PAL1, old);
07011             }
07012         } else {
07013             old = edt_intfc_read(edt_p, PCD_PAL2) & ~0x20;
07014             edt_intfc_write(edt_p, PCD_PAL2, old);
07015 
07016             for (n = 0; n < shift; n++)
07017             {
07018                 edt_msleep(1);
07019                 edt_intfc_write(edt_p, PCD_PAL2, (unsigned char) (0x20 | old));
07020                 edt_msleep(1);
07021                 edt_intfc_write(edt_p, PCD_PAL2, old);
07022             }
07023         }
07024     }
07025 }
07026 #endif /* PCD */
07027 
07028 
07029 #ifdef P11W
07030 
07031 #include "p11w.h"
07032 
07033 u_short
07034 p11w_get_command(EdtDev * edt_p)
07035 {
07036     return (edt_reg_read(edt_p, P11_COMMAND));
07037 }
07038 
07039 void
07040 p11w_set_command(EdtDev * edt_p, u_short val)
07041 {
07042     edt_reg_write(edt_p, P11_COMMAND, val);
07043 }
07044 
07045 u_short
07046 p11w_get_config(EdtDev * edt_p)
07047 {
07048     return (edt_reg_read(edt_p, P11_CONFIG));
07049 }
07050 
07051 void
07052 p11w_set_config(EdtDev * edt_p, u_short val)
07053 {
07054     edt_reg_write(edt_p, P11_CONFIG, val);
07055 }
07056 
07057 u_short
07058 p11w_get_data(EdtDev * edt_p)
07059 {
07060     return (edt_reg_read(edt_p, P11_DATA));
07061 }
07062 
07063 void
07064 p11w_set_data(EdtDev * edt_p, u_short val)
07065 {
07066     edt_reg_write(edt_p, P11_DATA, val);
07067 }
07068 
07069 u_short
07070 p11w_get_stat(EdtDev * edt_p)
07071 {
07072     return (edt_reg_read(edt_p, P11_STATUS));
07073 }
07074 
07075 u_int
07076 p11w_get_count(EdtDev * edt_p)
07077 {
07078     return (edt_reg_read(edt_p, P11_COUNT));
07079 }
07080 
07081 /*
07082 * The following routine is deprecated.  Use the one following
07083 * this, p11w_set_abortdma_onintr().     Mark  6/04
07084 */
07085 void
07086 p11w_abortdma_onattn(EdtDev *edt_p, int flag)
07087 {
07088     int arg = 0x11 ;
07089     u_short readcmd ;
07090 
07091 
07092     if (flag)
07093     {
07094         edt_ioctl(edt_p, P11G_READ_COMMAND, &readcmd) ;
07095         readcmd |= P11W_EN_ATT ;
07096         edt_ioctl(edt_p, P11S_READ_COMMAND, &readcmd) ;
07097 
07098         edt_ioctl(edt_p, EDTS_CUSTOMER, &arg) ;
07099     }
07100     else
07101     {
07102         edt_ioctl(edt_p, P11G_READ_COMMAND, &readcmd) ;
07103         readcmd &= ~P11W_EN_ATT ;
07104         edt_ioctl(edt_p, P11S_READ_COMMAND, &readcmd) ;
07105 
07106         arg = 0 ;
07107         edt_ioctl(edt_p, EDTS_CUSTOMER, &arg) ;
07108     }
07109 }
07110 
07111 void
07112 p11w_set_abortdma_onintr(EdtDev *edt_p, int flag)
07113 {
07114     u_short readcmd, writecmd ;
07115 
07116     if (flag == 0)
07117     {
07118         edt_ioctl(edt_p, P11G_READ_COMMAND, &readcmd) ;
07119         readcmd &= ~P11W_EN_ATT ;
07120         edt_ioctl(edt_p, P11S_READ_COMMAND, &readcmd) ;
07121 
07122         edt_ioctl(edt_p, P11G_WRITE_COMMAND, &writecmd) ;
07123         writecmd &= ~P11W_EN_ATT ;
07124         edt_ioctl(edt_p, P11S_WRITE_COMMAND, &writecmd) ;
07125     }
07126 
07127     edt_ioctl(edt_p, EDTS_ABORTDMA_ONINTR, &flag) ;
07128 
07129     if (flag)
07130     {
07131         edt_ioctl(edt_p, P11G_READ_COMMAND, &readcmd) ;
07132         readcmd |= P11W_EN_ATT ;
07133         edt_ioctl(edt_p, P11S_READ_COMMAND, &readcmd) ;
07134 
07135         edt_ioctl(edt_p, P11G_WRITE_COMMAND, &writecmd) ;
07136         writecmd |= P11W_EN_ATT ;
07137         edt_ioctl(edt_p, P11S_WRITE_COMMAND, &writecmd) ;
07138     }
07139 }
07140 
07141 #endif                          /* P11W */
07142 
07153 int
07154 edt_device_id(EdtDev *edt_p)
07155 {
07156     if (edt_p)
07157         return edt_p->devid;
07158     return -1;
07159 }
07160 
07175 int
07176 edt_check_1_vs_4(EdtDev *edt_p)
07177 {   
07178     char name[129];
07179     int pci_channels = 4;
07180 
07181     edt_x_get_fname(edt_p, name);
07182 
07183     if (isdigit(name[strlen(name)-1]))
07184     {
07185         if (strlen(name) >= 2 && isdigit(name[strlen(name)-2]))
07186         {
07187             pci_channels = atoi(name + strlen(name)-2);
07188         }
07189         else
07190         {
07191             pci_channels = atoi(name + strlen(name)-1);
07192         }
07193     }
07194 
07195     return pci_channels;
07196 }
07197 
07198 
07209 int
07210 edtdev_channels_from_type(EdtDev *edt_p)
07211 
07212 {
07213 
07214     switch(edt_p->devid) {
07215   case PCD20_ID:
07216   case PCD40_ID:
07217   case PCD60_ID:
07218 
07219   case PGP20_ID:
07220   case PGP40_ID:
07221   case PGP60_ID:
07222   case PGP_ECL_ID:
07223   case PDVFOI_ID:
07224   case PDVAERO_ID:
07225 
07226   case PDVCL2_ID:
07227       return 4;
07228 
07229   case PSS4_ID:
07230   case PGS4_ID:
07231   case PCDFOX_ID:
07232   case PCDA_ID:
07233   case PCDCL_ID:
07234   case PDVFOX_ID:
07235   case PE4DVFOX_ID:
07236   case PE8DVFOX_ID:
07237       return edt_check_1_vs_4(edt_p);
07238 
07239   case PDVFCI_USPS_ID:
07240   case PE4DVFCI_ID:
07241   case PE8DVFCI_ID:
07242   case PE8DVCLS_ID:
07243       return 2;
07244 
07245   case PE4DVCL_ID:
07246   case PE8DVCL_ID:
07247   case PDVCL_ID:
07248       return 3;
07249 
07250   case P53B_ID:
07251       return 34;
07252 
07253   case PCD_16_ID:
07254   case PSS16_ID:
07255   case PGS16_ID:
07256   case PCDA16_ID:
07257   case PE8LX16_ID:
07258   case PE8LX16_LS_ID:
07259     case PE4AMC16_ID:
07260        
07261       return 16;
07262 
07263   case PE8LX64_ID:
07264       return 64;
07265 
07266     }
07267 
07268     return 1;
07269 
07270 }
07271 
07277 int
07278 edt_devtype_from_id(int id)
07279 {
07280     switch(id)
07281     {
07282     case P11W_ID:               return p11w;
07283     case P16D_ID:               return p16d;
07284 
07285     case PDV_ID:                
07286     case PDVA_ID:               
07287     case PDVA16_ID:             
07288     case PDVK_ID:               
07289     case PDVRGB_ID:             
07290     case PDV44_ID:              
07291     case PDVCL_ID:              
07292     case PDVCL2_ID:             
07293 
07294     case PE4DVCL_ID:            
07295     case PE8DVCL_ID:            
07296     case PE8DVCLS_ID:           
07297 
07298     case PDVAERO_ID:            return pdv;
07299 
07300 
07301 
07302     case PCD20_ID:              
07303     case PCD40_ID:              
07304     case PCD60_ID:              
07305     case PCDA_ID:               
07306     case PCDCL_ID:              
07307     case PGP20_ID:              
07308     case PGP40_ID:              
07309     case PGP60_ID:              
07310 
07311     case PGP_THARAS_ID:         
07312     case PGP_ECL_ID:            
07313     case PCD_16_ID:             
07314     case PCDA16_ID:             
07315 
07316     case PDVFCI_AIAG_ID:        
07317     case PDVFCI_USPS_ID:        
07318     case PCDFCI_SIM_ID:         
07319     case PCDFCI_PCD_ID:         
07320     case PCDFOX_ID:             
07321     case PDVFOX_ID:             
07322     case PE4DVFOX_ID:           
07323     case PE8DVFOX_ID:           
07324     case P53B_ID:               
07325     case PDVFOI_ID:             
07326     case PSS4_ID:               
07327     case PSS16_ID:              
07328     case PGS4_ID:               
07329     case PGS16_ID:              
07330     case PE8LX1_ID:             
07331     case PE8LX16_LS_ID:         
07332     case PE8LX16_ID:            
07333     case PE8LX64_ID:            
07334     case PE4AMC16_ID:           return pcd;
07335 
07336     case DMY_ID:                
07337     case DMYK_ID:               return dummy;
07338 
07339     default:                    return unknown;
07340     }
07341 }
07342 
07343 
07344 
07349 char *
07350 edt_idstr(int id)
07351 {
07352     switch(id)
07353     {
07354     case P11W_ID:               return("pci 11w");
07355     case P16D_ID:               return("pci 16d");
07356     case PDV_ID:                return("pci dv");
07357     case PDVA_ID:               return("pci dva");
07358     case PDVA16_ID:             return("pci dva16");
07359     case PDVK_ID:               return("pci dvk");
07360     case PDVRGB_ID:             return("pci dv-rgb");
07361     case PDV44_ID:              return("pci dv44");
07362     case PDVCL_ID:              return("pci dv c-link");
07363     case PDVCL2_ID:             return("pci dv cls");
07364     case PE4DVCL_ID:            return("pcie4 dv c-link");
07365     case PE8DVCL_ID:            return("pcie8 dv c-link");
07366     case PE8DVCLS_ID:           return("pcie8 dv cls");
07367     case PDVAERO_ID:            return("pcd dv aero serial");
07368     case PCD20_ID:              return("pci cd-20");
07369     case PCD40_ID:              return("pci cd-40");
07370     case PCD60_ID:              return("pci cd-60");
07371     case PCDA_ID:               return("pci cda");
07372     case PCDCL_ID:              return("pci cd cl");
07373     case PGP20_ID:              return("pci gp-20");
07374     case PGP40_ID:              return("pci gp-40");
07375     case PGP60_ID:              return("pci gp-60");
07376 
07377     case PGP_THARAS_ID:         return("pci gp-tharas");
07378     case PGP_ECL_ID:            return("pci gp-ecl");
07379     case PCD_16_ID:             return("pci cd-16");
07380     case PCDA16_ID:             return("pci cda16");
07381 
07382     case PDVFCI_AIAG_ID:        return("pci-fci aiag");
07383     case PDVFCI_USPS_ID:        return("pci-fci usps");
07384     case PCDFCI_SIM_ID:         return("pci-fci sim");
07385     case PCDFCI_PCD_ID:         return("pci-fci pcd");
07386     case PCDFOX_ID:             return("pcd fox");
07387     case PDVFOX_ID:             return("pci dv fox");
07388     case PE4DVFOX_ID:           return("pcie4 dv fox");
07389     case PE8DVFOX_ID:           return("pcie8 dv fox");
07390     case P53B_ID:               return("pci 53b");
07391     case PDVFOI_ID:             return("pdv foi");
07392     case PSS4_ID:               return("pci ss-4");
07393     case PSS16_ID:              return("pci ss-16");
07394     case PGS4_ID:               return("pci gs-4");
07395     case PGS16_ID:              return("pci gs-16");
07396     case PE8LX1_ID:             return("pcie8 lx-1");
07397     case PE8LX16_LS_ID:         return("pcie8 lx-16 (slow)");
07398     case PE8LX16_ID:            return("pcie8 lx-16");
07399     case PE8LX64_ID:            return("pcie8 lx-64");
07400     case PE4AMC16_ID:           return("pcie4 AMC16");
07401     case DMY_ID:                return("dummy");
07402     case DMYK_ID:               return("dummy pci dvk/44/foi");
07403     default:                    return("unknown");
07404     }
07405 }
07406 
07407 
07414 #if defined(VXWORKS) || defined(TEST_VXWORKS)
07415 /* writable command string for vxworks calling edt_system() */
07416 char edt_vxw_cmdstr[512];
07417 
07418 /*
07419 * The following two arrays are used to register a function name with a
07420 * function pointer for vxworks calling edt_system().  Only 32 unique
07421 * program names are supported; most programs use less than 5.
07422 *
07423 * STRATEGY:  Preference is simplicity, but works with most applications.
07424 */
07425 static char *program_func_name[32] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07426 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07427 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07428 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
07429 static void * edt_vx_system_func[32] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07430 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07431 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07432 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
07433 
07434 /*
07435 * VxWorks programs calling edt_system() must first register the progam name
07436 * and the program function.
07437 */
07438 int
07439 edt_vx_system_register_func(const char *funcstr, int (funcptr)(char *))
07440 {
07441     int i;
07442 
07443     for (i = 0; i < 32; i++)
07444     {
07445         if (program_func_name[i] == NULL)
07446             break;
07447     }
07448 
07449     if (i == 32)
07450         return(-1);
07451     else
07452     {
07453         program_func_name[i] =  edt_alloc(strlen(funcstr) + 1);
07454         strcpy(program_func_name[i], funcstr);
07455         edt_vx_system_func[i] = funcptr;
07456         return 0;
07457     }
07458 }
07459 #endif
07460 
07461 int
07462 edt_system(const char *cmdstr)
07463 {
07464 #if defined(_NT_)
07465 
07466     int ret;
07467     char *newstr = malloc(512) ;
07468     char *p = newstr ;
07469     int nowait = 0;
07470     char *arg[32] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07471         NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07472         NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07473         NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07474     };
07475     int i ;
07476 
07477     if (cmdstr == NULL || *cmdstr == '\0')
07478         return(0) ;
07479 
07480     strncpy(newstr, cmdstr, 511) ;
07481     for (i = 0; (i < 32) && (p && *p); i++)
07482     {
07483         while (*p == ' ' || *p == '\t')
07484             *p++ = '\0' ;
07485 
07486         arg[i] = p ;
07487 
07488         while (*p != ' ' && *p != '\t' && *p != '\0')
07489             ++ p ;
07490     }
07491 
07492     if (*arg[i-1] == '&')
07493     {
07494         arg[i-1] = NULL;
07495         nowait = 1;
07496     }
07497 
07498     ret = spawnv((nowait) ? _P_NOWAIT : _P_WAIT, arg[0], arg);
07499     free(newstr);
07500     return ret;
07501 #elif defined(VXWORKS) || defined(TEST_VXWORKS)
07502     /*
07503     * VxWorks programs calling edt_system() must first register the progam name
07504     * and the program function.  Here the string argument to edt_system() is
07505     * parsed into the command name and options.  The command name is looked up
07506     * and matched with a function pointer, then the function is called with
07507     * the option string.
07508     */
07509     {
07510         int i;
07511         char *cmd;
07512         char *opts;
07513         char *tmp;
07514         int (*fnp)(char *);
07515 
07516         strncpy(edt_vxw_cmdstr, cmdstr, 511);
07517         cmd = edt_vxw_cmdstr;
07518         opts = strchr(edt_vxw_cmdstr, ' ');
07519 
07520         if (opts)
07521             *opts++ = '\0';
07522 
07523         tmp = strrchr(edt_vxw_cmdstr, '/');
07524         if (tmp)
07525             cmd = tmp + 1;
07526 
07527 
07528         edt_msg(EDTDEBUG, "VXWORKS_test: edt_system(%s, %s)\n", cmd, opts);
07529 #if defined(TEST_VXWORKS)
07530         printf("VXWORKS_test: edt_system(%s, %s)\n", cmd, opts);
07531 #endif
07532 
07533         for (i = 0; i < 32; i++)
07534         {
07535             if (program_func_name[i] == NULL)
07536                 return -1;
07537             else if (strncmp(program_func_name[i], cmd, 511) == 0)
07538             {
07539                 fnp = (int (*)(char*)) edt_vx_system_func[i];
07540                 edt_msg(EDTDEBUG, "VXWORKS_test: found name %s func %p\n", cmd, fnp);
07541                 return fnp(opts);
07542             }
07543         }
07544 
07545         if (i == 32) /* Not found */
07546         {
07547             edt_msg(EDTDEBUG, "VXWORKS_test: name not found %s, must be registered with edt_vx_system_register_func()\n", cmd);
07548             return -1;
07549         }
07550         return(0);
07551     }
07552 #else
07553 
07554     int ret ;
07555 
07556     ret = system(cmdstr) ;
07557 
07558 #if defined(__sun) || defined(__linux__) || defined(__APPLE__)
07559     if (ret == -1 || WIFEXITED(ret) == 0)
07560         return -1 ;
07561     else
07562         return WEXITSTATUS(ret) ;
07563 #else
07564     return ret ;
07565 #endif
07566 #endif
07567 }
07568 
07569 #define MEZZ_PATH_FIELD_CHAR '|'
07570 
07571 char *
07572 edt_get_last_bitpath(EdtDev *edt_p)
07573 
07574 {
07575     FILE *f;
07576     static char cache_name[MAXPATH];
07577 
07578 
07579     sprintf(cache_name, ".interface_bitfile.%d", edt_p->unit_no);
07580 
07581     if ((f = fopen(cache_name, "r")))
07582     {
07583 
07584         volatile char *throwaway = fgets(cache_name, MAXPATH, f);
07585 
07586         if (strlen(cache_name))
07587         {
07588 
07589         if (cache_name[strlen(cache_name)-1] == '\n')
07590             cache_name[strlen(cache_name)-1] = 0;
07591         }
07592 
07593         fclose(f);
07594 
07595         return cache_name;
07596     }
07597 
07598     return NULL;
07599 }
07600 
07601 
07602 void
07603 edt_set_last_bitpath(EdtDev *edt_p, const char *fullpath)
07604 
07605 {
07606     FILE *f;
07607     char cache_name[MAXPATH];
07608 
07609     sprintf(cache_name, ".interface_bitfile.%d", edt_p->unit_no);
07610 
07611     if ((f = fopen(cache_name, "w")))
07612     {
07613 
07614         fputs(fullpath, f);
07615 
07616         fclose(f);
07617 
07618     }
07619 }
07620 
07621 
07635 int
07636 edt_set_mezz_chan_bitpath(EdtDev *edt_p, const char *bitpath, int channel)
07637 {
07638     edt_bitpath pathbuf, chan0, chan1;
07639     const char *s1;
07640     int sp;
07641     int rc;
07642 
07643     /* scan back for / in path - we may not have room for full path */
07644 
07645     if (strlen(bitpath))
07646     {
07647         sp = (int) strlen(bitpath) - 1;
07648 
07649         while (sp >= 0 && bitpath[sp] != '/' && bitpath[sp] != '\\')
07650             sp --;
07651 
07652         if (sp >= 0)
07653             sp++;
07654         else
07655             sp = 0;
07656     }
07657     else
07658         sp = 0;
07659 
07660     s1 = bitpath + sp;
07661 
07662     edt_get_mezz_chan_bitpath(edt_p,chan0, sizeof(chan0),0);
07663     edt_get_mezz_chan_bitpath(edt_p,chan1, sizeof(chan1),1);
07664 
07665     if (channel == 0)
07666         sprintf(pathbuf,"%s%c%s",s1,MEZZ_PATH_FIELD_CHAR,chan1);
07667     else
07668         sprintf(pathbuf,"%s%c%s",chan0, MEZZ_PATH_FIELD_CHAR, s1);
07669 
07670     rc = edt_ioctl(edt_p, EDTS_MEZZ_BITPATH, pathbuf);
07671 
07672         edt_get_mezz_chan_bitpath(edt_p, edt_p->bfd.mezz_name0,
07673                 sizeof(edt_p->bfd.mezz_name0),0);
07674         edt_get_mezz_chan_bitpath(edt_p, edt_p->bfd.mezz_name1,
07675                 sizeof(edt_p->bfd.mezz_name1),1);
07676 
07677     return rc;
07678 }
07679 
07680 
07695 int
07696 edt_get_mezz_chan_bitpath(EdtDev *edt_p, char *bitpath, int size, int channel)
07697 {
07698     int ret = 0 ;
07699     edt_bitpath pathbuf ;
07700     char *s2, *s3;
07701     int sp;
07702     /* split into channels */
07703 
07704     ret = edt_ioctl(edt_p, EDTG_MEZZ_BITPATH, pathbuf);
07705 
07706     s2 = pathbuf;
07707     sp = 0;
07708     while (sp < (int)strlen(pathbuf) && pathbuf[sp] != MEZZ_PATH_FIELD_CHAR)
07709         sp++;
07710 
07711     s3 = s2 + sp;
07712     if (s3[0] == MEZZ_PATH_FIELD_CHAR)
07713     {
07714         s3[0] = 0;
07715         s3++;
07716     }
07717 
07718     if (channel == 0)
07719         strncpy(bitpath, s2, size - 1) ;
07720     else
07721         strncpy(bitpath, s3, size - 1) ;
07722 
07723     return ret ;
07724 }
07725 
07737 int
07738 edt_set_mezz_bitpath(EdtDev *edt_p, const char *bitpath)
07739 {
07740     edt_bitpath pathbuf;
07741     int rc;
07742     int i = (int) strlen(bitpath)-1;
07743 
07744     while (i>= 0 && bitpath[i] != '\\' && bitpath[i] != '/')
07745         i--;
07746 
07747     if (i >= 0)
07748         i++;
07749     else
07750         i = 0;
07751 
07752     strncpy(pathbuf, bitpath+i, sizeof(edt_bitpath) - 1) ;
07753     rc =  edt_ioctl(edt_p, EDTS_MEZZ_BITPATH, pathbuf);
07754 
07755     return rc;
07756 }
07757 
07758 
07772 int
07773 edt_get_mezz_bitpath(EdtDev *edt_p, char *bitpath, int size)
07774 {
07775     int ret = 0 ;
07776     edt_bitpath pathbuf ;
07777 
07778     ret = edt_ioctl(edt_p, EDTG_MEZZ_BITPATH, pathbuf);
07779     strncpy(bitpath, pathbuf, size - 1) ;
07780     return ret ;
07781 }
07782 
07783 
07795 int
07796 edt_set_bitpath(EdtDev *edt_p, const char *bitpath)
07797 {
07798     edt_bitpath pathbuf ;
07799     int rc;
07800 
07801     strncpy(pathbuf, bitpath, sizeof(edt_bitpath) - 1) ;
07802     rc =  edt_ioctl(edt_p, EDTS_BITPATH, pathbuf);
07803 
07804     edt_get_bitname(edt_p, edt_p->bfd.bitfile_name,
07805         sizeof(edt_p->bfd.bitfile_name));
07806 
07807     edt_set_last_bitpath(edt_p, bitpath);    
07808 
07809     return rc;
07810 }
07811 
07812 
07826 int
07827 edt_get_bitpath(EdtDev *edt_p, char *bitpath, int size)
07828 {
07829     int ret = 0 ;
07830     edt_bitpath pathbuf ;
07831     pathbuf[0] = '\0';
07832     ret = edt_ioctl(edt_p, EDTG_BITPATH, pathbuf);
07833 
07834     strncpy(bitpath, pathbuf, size - 1) ;
07835     return ret ;
07836 }
07837 
07851 int
07852 edt_get_bitname(EdtDev *edt_p, char *bitpath, int size)
07853 {
07854     int ret = 0 ;
07855     char *name;
07856     edt_bitpath pathbuf ;
07857 
07858     pathbuf[0] = '\0';
07859     ret = edt_ioctl(edt_p, EDTG_BITPATH, pathbuf);
07860 
07861     /*  Remove the leading path from the bitfile name */
07862     if ((name = strrchr(pathbuf, '/')) || (name = strrchr(pathbuf, '\\')))
07863         ++ name;
07864     else
07865         name = pathbuf;
07866 
07867     strcpy(bitpath, name) ;
07868 
07869     return ret ;
07870 }
07871 
07883 int
07884 edt_get_driver_version(EdtDev *edt_p, char *version, int size)
07885 {
07886     int ret = 0 ;
07887     edt_version_string vbuf ;
07888 
07889     ret = edt_ioctl(edt_p, EDTG_VERSION, vbuf);
07890 
07891     strncpy(version, vbuf, size - 1) ;
07892     return ret ;
07893 }
07894 
07907 int
07908 edt_get_driver_buildid(EdtDev *edt_p, char *build, int size)
07909 {
07910     int ret = 0 ;
07911     edt_version_string vbuf ;
07912 
07913     ret = edt_ioctl(edt_p, EDTG_BUILDID, vbuf);
07914 
07915     strncpy(build, vbuf, size - 1) ;
07916     return ret ;
07917 }
07918 
07919 static char * edt_library_version = EDT_LIBRARY_VERSION;
07920 static char * edt_library_buildid = FULLBUILD;
07921 
07931 int
07932 edt_get_library_version(EdtDev *edt_p, char *version, int size)
07933 {
07934     strncpy(version, edt_library_version, size - 1) ;
07935     return 0 ;
07936 }
07937 
07947 int
07948 edt_get_library_buildid(EdtDev *edt_p, char *build, int size)
07949 {
07950     strncpy(build, edt_library_buildid, size - 1) ;
07951     return 0 ;
07952 }
07953 
07954 
07958 int
07959 edt_check_version(EdtDev *edt_p)
07960 
07961 {
07962     edt_version_string check;
07963 
07964     edt_get_driver_version(edt_p, check, sizeof(check));
07965 
07966     return (!strcmp(check,edt_library_version));
07967 
07968 }
07969 
07973 static u_int
07974 epr_cfg(EdtDev *edt_p, int addr)
07975 {
07976     int ret ;
07977     edt_buf buf ;
07978     buf.desc = addr ;
07979     if ((addr<0) || (addr>0x3c)) {
07980         edt_msg(EDTWARN, "epr_cfg: addr out of range\n");
07981         return(0);
07982     } 
07983     ret = edt_ioctl(edt_p,EDTG_CONFIG,&buf) ;
07984     if (ret < 0)
07985     {
07986         edt_perror("EDTG_CONFIG") ;
07987     }
07988     return(u_int) (buf.value) ;
07989 }
07990 
07991 static void
07992 epw_cfg(EdtDev *edt_p, int addr, int value)
07993 {
07994     int ret ;
07995     edt_buf buf ;
07996     buf.desc = addr ;
07997     if ((addr<0) || (addr>0x3c)) {
07998         edt_msg(EDTWARN, "epw_cfg: addr out of range\n");
07999         return;
08000     } 
08001     buf.value = value ;
08002     ret = edt_ioctl(edt_p,EDTS_CONFIG,&buf) ;
08003     if (ret < 0)
08004     {
08005         edt_perror("EDTS_CONFIG") ;
08006     }
08007 }
08008 
08014 int
08015 edt_pci_reboot(EdtDev *edt_p)
08016 {
08017     int  addr, data;
08018     int  buf[0x40];
08019     int  rst, copy, new;
08020     int  ret = 0;
08021     FILE *fd2;
08022     char *tmpfname = "TMPfPciReboot.cfg";
08023 
08024     if ((fd2 = fopen(tmpfname, "wb")) == NULL)  {
08025         edt_msg(EDTFATAL,"edt_pci_reboot: Couldn't write to temp file %s\n", tmpfname);
08026         return -1;
08027     }
08028     for (addr=0; addr<=0x3c; addr+=4) {
08029         data  = epr_cfg(edt_p, addr);
08030         buf[addr] = data;
08031         putc(data, fd2);
08032         putc(data>>8, fd2);
08033         putc(data>>16, fd2);
08034         putc(data>>24, fd2);
08035         /* printf("%02x:  %08x\n", addr, data); */
08036     }
08037     fclose(fd2);
08038     edt_msg(EDTDEBUG, "Wrote config space state out to %s\n", tmpfname);
08039 
08040     edt_reg_write(edt_p, 0x01000085, 0x40) ;
08041     edt_msleep(2000) ;
08042 
08043     edt_msg(EDTDEBUG, "  copy     reset     new\n");
08044     for (addr=0; addr<=0x3c; addr+=4) {
08045         rst  = epr_cfg(edt_p, addr);
08046         copy  =  buf[addr];
08047         epw_cfg(edt_p, addr, copy) ;
08048         new  = epr_cfg(edt_p, addr);
08049 
08050         edt_msg(EDTDEBUG, "%02x:  %08x  %08x  %08x       ", addr, copy, rst, new);
08051         if      (copy != new)   edt_msg(EDTDEBUG, "ERROR\n");
08052         else if (rst != new)    edt_msg(EDTDEBUG, "changed\n");
08053         else                    edt_msg(EDTDEBUG, "\n");
08054 
08055         /* specifically check line cache reg to make sure it was reset by OS after cleared */
08056         if (addr == 0x0c)
08057         {
08058             if ((rst & 0xff) == (new & 0xff))
08059                 ret = -1;
08060         }
08061 
08062     }
08063     return ret;
08064 }
08065 
08069 int
08070 edt_set_merge(EdtDev * edt_p, u_int size, int span, u_int offset, u_int count)
08071 {
08072     edt_merge_args tmp;
08073     int     ret;
08074 
08075     tmp.line_size = size ;
08076     tmp.line_span = span;
08077     tmp.line_offset = offset;
08078     tmp.line_count = count;
08079     ret = edt_ioctl(edt_p, EDTS_MERGEPARMS, &tmp);
08080     return (ret);
08081 }
08082 
08083 /* flip the bits inside a byte */
08084 u_char
08085 edt_flipbits(u_char val)
08086 {
08087     int     i;
08088     u_char  ret = 0;
08089 
08090     for (i = 0; i < 8; i++)
08091     {
08092         if (val & (1 << i))
08093             ret |= 0x80 >> i;
08094     }
08095     return (ret);
08096 }
08097 /* 
08098 *
08099 * edt_set_kernel_buffers
08100 *
08101 * Turn on or off th