00001
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
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
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 static u_int dmy_started = 0 ;
00086
00087
00088 int dump_reg_access = 0;
00089
00090
00091 static u_char *intfc_dump = 0;
00092 static u_char *base_dump = 0;
00093 static u_char *dma_reg_dump = 0;
00094
00095 static int get_xref_info_params(char *str, char *fpga, char *sn, char *mtype, char *moffs, char *mnum, char *desc, char *rsvd1, char *rsvd2);
00096 static int isdigit_str(char *s);
00097
00098 int dump_ir_access = 0;
00099
00100 void edt_set_dump_reg_access(int on)
00101
00102 {
00103 if (intfc_dump == NULL)
00104 {
00105 intfc_dump = (u_char *) calloc(256,1);
00106 base_dump = (u_char *) calloc(256,1);
00107 dma_reg_dump = (u_char *) calloc(256,1);
00108 }
00109
00110 dump_reg_access = on;
00111
00112 }
00113
00114 int edt_get_dump_reg_access()
00115
00116 {
00117 return dump_reg_access;
00118 }
00119
00120 void edt_set_dump_ir_access(u_int on)
00121
00122 {
00123 dump_ir_access = on;
00124 if (on)
00125 edt_set_dump_reg_access(on);
00126
00127 }
00128
00129 void edt_set_dump_reg_address(u_int reglow, u_int n, u_int on)
00130
00131 {
00132 int type = (reglow >> 16) & 0xf;
00133 u_int i;
00134 u_int start = reglow & 0xff;
00135 u_int nmax;
00136
00137 if (type == 3)
00138 nmax = 8;
00139 else
00140 nmax = 256;
00141
00142 if (start + n > nmax-1)
00143 n = nmax-start;
00144
00145 if (intfc_dump == NULL)
00146 edt_set_dump_reg_access(TRUE);
00147
00148 switch(type)
00149 {
00150
00151 case 0:
00152 for (i=start; i< start+n;i++)
00153 base_dump[i] = on;
00154
00155 break;
00156
00157 case 1:
00158 for (i=start; i< start+n;i++)
00159 intfc_dump[i] = on;
00160
00161 break;
00162
00163 case 3:
00164 if (n > 8)
00165 n = 8;
00166
00167 for (i=start; i< start+n;i++)
00168 dma_reg_dump[i] = on;
00169
00170 break;
00171
00172 }
00173
00174 }
00175
00176 u_char
00177 is_reg_dumpable(u_int regvalue)
00178
00179 {
00180 int type = EDT_REG_TYPE(regvalue);
00181
00182 int offset = regvalue & 0xff;
00183 int class = EDT_REG_CLASS(regvalue);
00184
00185 if (class == 1)
00186 return dump_ir_access;
00187
00188 switch(type)
00189 {
00190 case 0:
00191 return base_dump[offset];
00192 case 1:
00193 return intfc_dump[offset];
00194 case 3:
00195 return dma_reg_dump[offset];
00196
00197 }
00198
00199 return 0;
00200 }
00201
00202 void
00203 edt_setenv_reg_dump(const char *s)
00204
00205 {
00206 char test[128];
00207 int low;
00208 int high;
00209 size_t index;
00210 int range=0;
00211 int in_number=0;
00212 int tindex=0;
00213
00214 for (index=0;index<strlen(s)+1;index++)
00215 {
00216 switch(s[index]) {
00217 case '0':
00218 case '1':
00219 case '2':
00220 case '3':
00221 case '5':
00222 case '6':
00223 case '7':
00224 case '8':
00225 case '9':
00226 case 'A':
00227 case 'B':
00228 case 'C':
00229 case 'D':
00230 case 'E':
00231 case 'F':
00232 case 'a':
00233 case 'b':
00234 case 'c':
00235 case 'd':
00236 case 'e':
00237 case 'f':
00238 in_number=1;
00239 test[tindex++]=s[index];
00240 break;
00241
00242 case ':':
00243 case ' ':
00244 case 0:
00245
00246 if (in_number)
00247 {
00248 test[tindex] = 0;
00249 if (range)
00250 high=strtol(test,NULL,16);
00251 else
00252 low=strtol(test,NULL,16);
00253 if (range)
00254 edt_set_dump_reg_address(low | INTFC_BYTE,(high-low+1),1);
00255 else
00256 edt_set_dump_reg_address(low | INTFC_BYTE,1,1);
00257 range=0;
00258 in_number=0;
00259 tindex=0;
00260 }
00261 break;
00262 case '-':
00263 if (in_number)
00264 {
00265 test[tindex] = 0;
00266 low=strtol(test,NULL,16);
00267 range=1;
00268 in_number=0;
00269 tindex=0;
00270 }
00271 break;
00272 }
00273 }
00274 }
00275
00276 #ifndef _NT_
00277
00278 extern int errno;
00279
00280 static void
00281 edt_set_errno(int val)
00282
00283 {
00284 errno = val;
00285 }
00286
00287 #else
00288
00289 #define edt_set_errno(val)
00290
00291 #endif
00292
00293
00294
00295 int edt_clear_wait_status(EdtDev *edt_p);
00296
00297 #ifndef SECTOR_SIZE
00298 #define SECTOR_SIZE 512
00299 #endif
00300
00301 #ifndef PAGESIZE
00302 #define PAGESIZE 4096
00303 #endif
00304
00305 #define DEFAULT_BUFFER_GRANULARITY PAGESIZE
00306 #define MINHEADERSIZE SECTOR_SIZE
00307
00308 #define EDTDEBUG EDTLIB_MSG_INFO_2
00309 #define EDTFATAL EDTLIB_MSG_FATAL
00310 #define EDTWARN EDTLIB_MSG_WARNING
00311
00312 #if defined(__APPLE__)
00313 void *edt_mac_open(char *classname, int unit, int channel);
00314 void *edt_mac_ioctl(void *dataPort, int code, void *eis);
00315 #endif
00316
00317 #ifdef _NT_
00318 static u_int WINAPI
00319 edt_wait_event_thread(void *);
00320
00321 int
00322 edt_get_kernel_event(EdtDev *edt_p, int event_num);
00323 static
00324 void
00325 edt_clear_event_func(EdtEventHandler * p);
00326
00327 #else
00328 #ifndef VXWORKS
00329 static void *
00330 edt_wait_event_thread(void *);
00331 #endif
00332
00333 #endif
00334
00335 #ifndef VXWORKS
00336 static char *BaseEventNames[] =
00337 {
00338 NULL,
00339 EDT_EODMA_EVENT_NAME,
00340 EDT_BUF_EVENT_NAME,
00341 EDT_STAT_EVENT_NAME,
00342 EDT_P16D_DINT_EVENT_NAME,
00343 EDT_P11W_ATTN_EVENT_NAME,
00344 EDT_P11W_CNT_EVENT_NAME,
00345 EDT_PDV_ACQUIRE_EVENT_NAME,
00346 EDT_EVENT_PCD_STAT1_NAME,
00347 EDT_EVENT_PCD_STAT2_NAME,
00348 EDT_EVENT_PCD_STAT3_NAME,
00349 EDT_EVENT_PCD_STAT4_NAME,
00350 EDT_PDV_STROBE_EVENT_NAME,
00351 EDT_EVENT_P53B_SRQ_NAME,
00352 EDT_EVENT_P53B_INTERVAL_NAME,
00353 EDT_EVENT_P53B_MODECODE_NAME,
00354 EDT_EVENT_P53B_DONE_NAME,
00355 EDT_PDV_EVENT_FVAL_NAME,
00356 EDT_PDV_EVENT_TRIGINT_NAME,
00357 EDT_EVENT_TEMP_NAME,
00358 NULL
00359 };
00360 #endif
00361
00362 #ifdef USB
00363
00371 u_int
00372 usb_reg_read (EdtDev *edt_p, u_int desc)
00373 {
00374 int i, addr;
00375 u_int retval = 0 ;
00376 unsigned char setup[3];
00377 unsigned char buf[5];
00378 int bytes;
00379
00380 if (usb_claim_interface(edt_p->usb_p, 0) < 0)
00381 {
00382 edt_set_errno(EBUSY); ;
00383 return 0 ;
00384 }
00385
00386 addr = EDT_REG_ADDR(desc) ;
00387
00388 for (i = 0; i < EDT_REG_SIZE(desc); i++)
00389 {
00390 setup[0] = 0x03 ;
00391 setup[1] = addr ;
00392
00393
00394 if ((usb_bulk_write(edt_p->usb_p, 0x01, setup, 2,
00395 edt_p->usb_rtimeout)) < 0)
00396 {
00397 usb_release_interface(edt_p->usb_p, 0);
00398 edt_set_errno(EINVAL); ;
00399 return 0 ;
00400 }
00401
00402
00403 bytes = usb_bulk_read(edt_p->usb_p, 0x81, buf, 1, edt_p->usb_rtimeout);
00404
00405 if (bytes < 1)
00406 {
00407 extern int errno ;
00408 usb_release_interface(edt_p->usb_p, 0);
00409 edt_set_errno(EINVAL); ;
00410 return 0 ;
00411 }
00412
00413 ++addr ;
00414 retval |= ((u_int) buf[0] << (i * 8)) ;
00415 }
00416
00417 usb_release_interface(edt_p->usb_p, 0);
00418
00419 return retval ;
00420 }
00421
00429 void
00430 usb_reg_write(EdtDev *edt_p, u_int desc, u_int value)
00431 {
00432 int i, addr, size;
00433 unsigned char setup[4];
00434 unsigned char buf[4];
00435
00436 if (usb_claim_interface(edt_p->usb_p, 0) < 0)
00437 {
00438 edt_set_errno(EBUSY); ;
00439 return ;
00440 }
00441
00442 addr = EDT_REG_ADDR(desc) ;
00443
00444 for (i = 0; i < EDT_REG_SIZE(desc); i++)
00445 {
00446 if (EDT_REG_TYPE(desc) == REMOTE_USB_TYPE)
00447 {
00448 setup[0] = 0x04;
00449 setup[1] = addr ;
00450 setup[2] = value & 0xff ;
00451 size = 3 ;
00452 }
00453 else if (EDT_REG_TYPE(desc) == LOCAL_USB_TYPE)
00454 {
00455 setup[0] = 0x01;
00456 setup[1] = value & 0xff ;
00457 size = 2 ;
00458 }
00459
00460
00461 if ((usb_bulk_write(edt_p->usb_p, 0x01, setup, size,
00462 edt_p->usb_wtimeout)) < 0)
00463 {
00464 usb_release_interface(edt_p->usb_p, 0);
00465 edt_set_errno(EINVAL); ;
00466 return ;
00467 }
00468
00469 addr++ ;
00470 value >>= 8 ;
00471 }
00472
00473 usb_release_interface(edt_p->usb_p, 0);
00474 }
00475
00476
00477
00478
00479
00480 struct usb_device *edt_find_usb_board(int unit)
00481 {
00482 struct usb_bus *p;
00483 struct usb_device *q;
00484
00485 for (p = usb_busses; p; p = p->next)
00486 {
00487 q = p->devices;
00488 while(q)
00489 {
00490 if ((q->descriptor.idVendor==0x04b4) &&
00491 (q->descriptor.idProduct=0x8613))
00492 return q;
00493 else
00494 q = q->next;
00495 }
00496 }
00497
00498 return NULL;
00499 }
00500 #endif
00501
00502
00503 static int edt_parse_devname(EdtDev *edt_p, char *edt_devname, int unit, int channel);
00504
00505 EdtDev * edt_open_device_struct(EdtDev *edt_p,
00506 const char *device_name,
00507 int unit, int channel,
00508 int verbose)
00509
00510 {
00511
00512 static char *debug_env = NULL;
00513 u_int dmy;
00514 int edt_debug;
00515 static char *debug_file = NULL;
00516 int level;
00517
00518 if ((debug_env == NULL)
00519 && ((debug_env = (char *) getenv("EDTDEBUG")) != NULL)
00520 && *debug_env != '0')
00521 {
00522 edt_debug = atoi(debug_env);
00523 level = edt_msg_default_level();
00524 if (edt_debug > 0)
00525 {
00526 level |= EDTLIB_MSG_INFO_1;
00527 level |= EDTLIB_MSG_INFO_2;
00528 }
00529 edt_msg_set_level(edt_msg_default_handle(), level);
00530
00531 if ((debug_file == NULL)
00532 && ((debug_file = (char *) getenv("EDTDEBUGFILE")) != NULL)
00533 && *debug_file != '0')
00534 {
00535 edt_msg_set_name(edt_msg_default_handle(), debug_file);
00536 }
00537
00538 edt_msg(EDTDEBUG, "environment DEBUG set to %d: enabling debug in edtlib\n", edt_debug);
00539 }
00540
00541 if(verbose)
00542 edt_msg(EDTDEBUG, "edt_open_device(%s, %d)\n", device_name, unit);
00543
00544 if ((strncmp(device_name, "dmy", 3) == 0) || (strncmp(device_name, "DMY", 3) == 0))
00545 edt_p->devid = DMY_ID;
00546 #ifdef USB
00547 else if (strncasecmp(device_name, "usb", 3) == 0)
00548 edt_p->devtype = USB_ID;
00549 #endif
00550
00551
00552 if (edt_parse_devname(edt_p, (char *) device_name, unit, channel) != 0)
00553 {
00554 edt_msg(EDTFATAL, "Illegal EDT device name (edt_open_device): %s\n", device_name);
00555 return NULL;
00556 }
00557
00558 edt_p->unit_no = unit;
00559 edt_p->channel_no = channel;
00560
00561 #ifdef USB
00562 if (edt_p->devtype == USB_ID)
00563 {
00564 struct usb_device *current_device = NULL;
00565
00566 usb_init();
00567 usb_find_busses();
00568 usb_find_devices();
00569
00570 current_device = edt_find_usb_board(unit);
00571
00572 if(current_device==NULL)
00573 {
00574 edt_set_errno(ENODEV); ;
00575 return NULL;
00576 }
00577
00578 edt_p->usb_p = usb_open(current_device);
00579
00580
00581
00582
00583
00584
00585
00586 edt_p->usb_bulk_read_endpoint = 0x80 + (channel * 2) + 2 ;
00587 edt_p->usb_bulk_write_endpoint = (channel * 2) + 2 ;
00588
00589 }
00590 else
00591 #endif
00592 {
00593
00594 #ifdef _NT_
00595 edt_p->fd = CreateFile(edt_p->edt_devname,
00596 GENERIC_READ | GENERIC_WRITE,
00597 FILE_SHARE_READ | FILE_SHARE_WRITE,
00598 NULL,
00599 edt_p->devid == (DMY_ID) ? OPEN_ALWAYS
00600 : OPEN_EXISTING,
00601 FILE_ATTRIBUTE_NORMAL,
00602 NULL);
00603
00604 if (edt_p->fd == INVALID_HANDLE_VALUE)
00605 {
00606 if (verbose)
00607 edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", device_name);
00608
00609 return (NULL);
00610 }
00611 #else
00612 #if defined (__APPLE__)
00613
00614 if (verbose)
00615 edt_msg(EDTWARN, "edt_devname %s unit %d channel %d\n",edt_p->edt_devname,unit,channel) ;
00616 if (edt_p->devid != DMY_ID)
00617 {
00618 int nchannels = 0;
00619 int dummy = 0;
00620
00621
00622
00623
00624 if ((edt_p->fd = edt_mac_open(edt_p->edt_devname, unit, 0)) <= 0)
00625 return NULL;
00626
00627 edt_p->channel_no = 0;
00628 nchannels = edt_ioctl(edt_p, EDTG_MAXCHAN, &dummy);
00629 if (channel < nchannels)
00630 {
00631 edt_mac_close(edt_p->fd);
00632 edt_p->channel_no = channel;
00633 if ((edt_p->fd = edt_mac_open(edt_p->edt_devname, unit, channel)) <= 0 )
00634 {
00635 if (verbose)
00636 edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", edt_p->edt_devname);
00637 return (NULL);
00638 }
00639
00640 edt_ioctl(edt_p, EDTG_DEVID, &edt_p->devid);
00641 if (edt_is_pdv(edt_p))
00642 {
00643 if (strncmp(device_name, "pdv", 3) != 0)
00644 {
00645 if (verbose)
00646 printf("%s not match for pdv\n",edt_p->edt_devname) ;
00647 close(edt_p->fd) ;
00648 return(NULL);
00649 }
00650 }
00651 else if (edt_is_pcd(edt_p))
00652 {
00653 if (strncmp(device_name, "pcd", 3) != 0)
00654 {
00655 if (verbose)
00656 printf("%s not match for pcd\n",edt_p->edt_devname) ;
00657 close(edt_p->fd) ;
00658 return(NULL);
00659 }
00660 }
00661 }
00662 else
00663 {
00664 edt_msg(EDTWARN, "EDT %s open failed. Channel number %d is larger than max allowed %d\n", edt_p->edt_devname, channel, nchannels-1);
00665 return NULL;
00666 }
00667 }
00668 else
00669 {
00670 if (!edt_p->fd)
00671 {
00672 if ((edt_p->fd = open(edt_p->edt_devname, O_RDWR|O_CREAT, 0666)) < 0 )
00673 {
00674 if (verbose)
00675 edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", edt_p->edt_devname);
00676 return (NULL);
00677 }
00678 }
00679
00680 }
00681 #else
00682
00683 if ((edt_p->fd = open(edt_p->edt_devname, O_RDWR, 0666)) < 0 )
00684 {
00685 if (verbose)
00686 edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", edt_p->edt_devname);
00687 return (NULL);
00688 }
00689
00690 #if defined( __linux__) || defined(__sun)
00691 fcntl(edt_p->fd, F_SETFD, FD_CLOEXEC);
00692 #endif
00693
00694 #endif
00695 #endif
00696 }
00697
00698
00699
00700 edt_msg(EDTDEBUG, "edt_open for %s unit %d succeeded\n", device_name, unit);
00701
00702 if (edt_p->devid != DMY_ID)
00703 {
00704 edt_ioctl(edt_p, EDTG_DEVID, &edt_p->devid);
00705 edt_ioctl(edt_p, EDTS_RESETCOUNT, &dmy);
00706 dmy = edt_p->channel_no ;
00707
00708 edt_p->DMA_channels = edtdev_channels_from_type(edt_p);
00709
00710 #ifdef _NT_
00711 edt_get_kernel_event(edt_p, EDT_EVENT_BUF);
00712 edt_get_kernel_event(edt_p, EDT_EVENT_STAT);
00713 if (edt_p->devid == P53B_ID)
00714 {
00715 edt_get_kernel_event(edt_p, EDT_EVENT_P53B_SRQ);
00716 edt_get_kernel_event(edt_p, EDT_EVENT_P53B_INTERVAL);
00717 edt_get_kernel_event(edt_p, EDT_EVENT_P53B_MODECODE);
00718 edt_get_kernel_event(edt_p, EDT_EVENT_P53B_DONE);
00719 }
00720 #endif
00721 }
00722
00723 edt_p->devtype = edt_devtype_from_id(edt_p->devid);
00724 edt_p->donecount = 0;
00725 edt_p->tmpbuf = 0;
00726 edt_p->dd_p = 0;
00727 edt_p->b_count = 0;
00728 edt_p->buffer_granularity = DEFAULT_BUFFER_GRANULARITY;
00729 edt_p->mezz.id = MEZZ_ID_UNKNOWN;
00730 edt_p->reg_fifo_io = NULL;
00731 edt_p->reg_fifo_cnt = NULL;
00732 edt_p->reg_fifo_ctl = NULL;
00733 edt_p->reg_intfc_off = NULL;
00734 edt_p->reg_intfc_dat = NULL;
00735
00736
00737 return edt_p;
00738 }
00739
00740
00741 EdtDev *edt_open_device(const char *device_name, int unit, int channel, int verbose)
00742
00743 {
00744 EdtDev *edt_p;
00745
00746 if ((edt_p = (EdtDev *) calloc(1, sizeof(EdtDev))) == NULL)
00747 {
00748 char errstr[128];
00749 sprintf(errstr, "edtlib: malloc (%x) in edt_open failed\n", (int)sizeof(EdtDev));
00750 edt_msg_perror(EDTWARN, errstr);
00751 return (NULL);
00752 }
00753
00754 return edt_open_device_struct(
00755 edt_p,
00756 device_name,
00757 unit, channel, verbose);
00758 }
00759
00783 EdtDev *
00784 edt_open(const char *device_name, int unit)
00785 {
00786
00787 return edt_open_device(device_name, unit, 0, 1);
00788 }
00789
00790
00804 EdtDev *
00805 edt_open_quiet(const char *device_name, int unit)
00806 {
00807 return edt_open_device(device_name, unit, 0, 0);
00808 }
00809
00837 EdtDev *
00838 edt_open_channel(const char *device_name, int unit, int channel)
00839 {
00840 return edt_open_device(device_name, unit, channel, 1);
00841 }
00842
00851 static int
00852 edt_parse_devname(EdtDev *edt_p, char *device_name, int unit, int channel)
00853 {
00854
00855 char *format;
00856
00857 char dev_string[512];
00858
00859 if (!device_name)
00860 return -1;
00861
00862 if (device_name[0] == '\\' || device_name[0] == '/')
00863 {
00864 strcpy(edt_p->edt_devname, device_name);
00865 }
00866 else if (edt_p->devid == DMY_ID)
00867 {
00868 #ifdef _NT_
00869 format = ".\\%s%d" ;
00870 #else
00871 format = "./%s%d" ;
00872 #endif
00873 (void) sprintf(edt_p->edt_devname, format, device_name, unit) ;
00874 }
00875 else
00876 {
00877 int i;
00878
00879 strncpy(dev_string, device_name,511);
00880
00881 for (i=0;dev_string[i]; i++)
00882 dev_string[i] = tolower(dev_string[i]);
00883
00884 #ifdef _NT_
00885 dev_string[0] = toupper(dev_string[0]);
00886 #endif
00887
00888 #if defined(__linux__)
00889 if (strcmp(dev_string, "pcd") == 0)
00890 strcpy(dev_string, "pcicd");
00891 #endif
00892
00893
00894 #ifdef _NT_
00895
00896 #ifdef WDF_DRIVER
00897 if (channel > 0)
00898 {
00899 format = "\\\\.\\%s%d\\%d_%d";
00900 }
00901 else
00902 {
00903 format = "\\\\.\\%s%d\\%d_%d";
00904 }
00905 (void) sprintf(edt_p->edt_devname, format, dev_string, unit, unit, channel);
00906 #else
00907 if (channel > 0)
00908 {
00909 format = "\\\\.\\%s%d_%d";
00910 }
00911 else
00912 {
00913 format = "\\\\.\\%s%d";
00914 }
00915 (void) sprintf(edt_p->edt_devname, format, dev_string, unit, channel);
00916
00917
00918 #endif
00919
00920 #else
00921 if (channel > 0)
00922 {
00923 format = "/dev/%s%d_%d";
00924 }
00925 else
00926 {
00927 format = "/dev/%s%d";
00928 }
00929 (void) sprintf(edt_p->edt_devname, format, dev_string, unit, channel);
00930 #endif
00931
00932 }
00933 edt_msg(EDTDEBUG, "parse open to %s\n",edt_p->edt_devname) ;
00934
00935 return 0;
00936 }
00937
00948 int
00949 edt_close_device(EdtDev *edt_p)
00950
00951 {
00952 u_int i;
00953 #ifdef __sun
00954 EdtEventHandler *p;
00955 #endif
00956
00957 edt_msg(EDTDEBUG, "edt_close()\n");
00958
00959 for (i = 0; i < EDT_MAX_KERNEL_EVENTS; i++)
00960 {
00961
00962
00963 #ifdef __sun
00964 p = &edt_p->event_funcs[i];
00965 if (p->active)
00966 {
00967 p->active = 0;
00968
00969 edt_ioctl(p->owner, EDTS_DEL_EVENT_FUNC, &i);
00970 edt_ioctl(p->owner, EDTS_CLR_EVENT, &i);
00971 sema_destroy(&p->sema_thread);
00972 thr_join(NULL, NULL, NULL);
00973 }
00974 #else
00975 #ifndef NO_PTHREAD
00976
00977 edt_remove_event_func(edt_p, i);
00978 #endif
00979 #endif
00980 }
00981
00982 if (edt_p->ring_buffers_configured)
00983 edt_disable_ring_buffers(edt_p);
00984
00985 if (edt_p->fd)
00986 {
00987 #ifdef _NT_
00988 CloseHandle(edt_p->fd);
00989 #else
00990 #if defined (__APPLE__)
00991 edt_mac_close(edt_p->fd) ;
00992 #else
00993 close(edt_p->fd);
00994 #endif
00995 #endif
00996 }
00997
00998 return 0;
00999 }
01000
01001 int
01002 edt_close(EdtDev *edt_p)
01003
01004 {
01005 edt_close_device(edt_p);
01006
01007 free(edt_p);
01008
01009 return 0;
01010 }
01011
01012 #ifdef __sun
01013
01014 typedef struct
01015 {
01016 uint_t index;
01017 uint_t writeflag;
01018 EdtDev *edt_p;
01019 } thr_buf_args;
01020
01021 static void *
01022 aio_thread( void *arg)
01023
01024 {
01025 thr_buf_args *bufp = (thr_buf_args *) arg;
01026 int ret;
01027 u_char *addr;
01028 uint_t size;
01029 int index;
01030 EdtDev *edt_p;
01031 extern int errno;
01032
01033 edt_p = bufp->edt_p;
01034 index = bufp->index;
01035 addr = edt_p->ring_buffers[index];
01036 size = edt_p->rb_control[index].size;
01037
01038
01039
01040
01041
01042
01043 edt_msg(EDTDEBUG, "start %s for %d addr %x\n",
01044 bufp->writeflag ? "write" : "read", index, (u_int) addr);
01045 edt_set_errno(0);;
01046 if (bufp->writeflag)
01047 ret = pwrite(edt_p->fd, addr, size, index * 512);
01048 else
01049 ret = pread(edt_p->fd, addr, size, index * 512);
01050 if (ret == -1)
01051 {
01052 char errstr[128];
01053
01054 if (errno)
01055 perror("pread");
01056 sprintf(errstr, "aio buffer %d at 0x%x", index, (u_int) addr);
01057 edt_msg_perror(EDTDEBUG, errstr);
01058 edt_msg_perror(EDTDEBUG, "aiothread\n");
01059 }
01060 edt_msg(EDTDEBUG, "end aiothread for %d\n", index);
01061 return (0);
01062 }
01063
01064 #endif
01065
01073 int
01074 edt_use_umem_lock(EdtDev *edt_p, u_int use_lock)
01075 {
01076 int ret = 0 ;
01077 if (edt_p->ring_buffers_configured)
01078 {
01079 printf("Can't change umem lock method when ring buffers active\n") ;
01080 return(1) ;
01081 }
01082 edt_msg(EDTDEBUG, "use umem lock %d ",use_lock) ;
01083 ret = edt_ioctl(edt_p, EDTS_UMEM_LOCK, &use_lock) ;
01084 edt_msg(EDTDEBUG, "returns %d\n",ret) ;
01085 if (ret)
01086 {
01087 edt_msg(EDTDEBUG,
01088 "Can't use Umem lock expect on solaris 2.8 or above\n") ;
01089 }
01090 else
01091 {
01092 edt_msg(EDTDEBUG,"Setting umem lock\n") ;
01093 }
01094 return(ret) ;
01095 }
01096
01097 int
01098 edt_get_umem_lock(EdtDev *edt_p)
01099 {
01100 u_int using_lock ;
01101 edt_ioctl(edt_p, EDTG_UMEM_LOCK, &using_lock) ;
01102 edt_msg(EDTDEBUG,"Using lock returns %d\n",using_lock) ;
01103 return(using_lock) ;
01104 }
01105
01116 int
01117 edt_get_numbufs(EdtDev *edt_p)
01118
01119 {
01120 int nb = 0;
01121 edt_ioctl(edt_p, EDTG_NUMBUFS, &nb);
01122 return nb;
01123 }
01124
01125 #ifdef __sun
01126
01127 void
01128 edt_sun_lock_mem(EdtDev *edt_p, int index, int write_flag, EdtRingBuffer *pring)
01129
01130 {
01131 int using_lock = 0 ;
01132 int count;
01133 thr_buf_args bufargs;
01134
01135 using_lock = edt_get_umem_lock(edt_p) ;
01136
01137 if (!using_lock)
01138 {
01139 bufargs.edt_p = edt_p;
01140 bufargs.index = index;
01141 bufargs.writeflag = write_flag;
01142
01143 edt_msg(EDTDEBUG, "%d buffer thread\n", index);
01144 if (thr_create(NULL, 0,
01145 aio_thread,
01146 (void *) &bufargs, THR_BOUND,
01147 &pring->ring_tid))
01148 {
01149 edt_msg_perror(EDTWARN, "thr_create");
01150 }
01151 count = index + 1;
01152
01153 edt_msg(EDTDEBUG, "Before WAITN");
01154 edt_ioctl(edt_p, EDTS_WAITN, &count);
01155 edt_msg(EDTDEBUG, "After WAITN");
01156 }
01157 }
01158
01159 #endif
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178 static int
01179 edt_configure_ring_buffer(EdtDev * edt_p,
01180 int index,
01181 int bufsize,
01182 int write_flag,
01183 unsigned char *pdata)
01184
01185 {
01186 buf_args sysargs;
01187 int allocated_size = bufsize;
01188 EdtRingBuffer *pring;
01189 int rc;
01190
01191 if (index < 0 || index >= MAX_DMA_BUFFERS)
01192 {
01193 edt_set_errno(EINVAL);
01194
01195 fprintf(stderr,
01196 "invalid buffer index %d < 0 or >= MAX_DMA_BUFFERS (%d)\n",
01197 index, MAX_DMA_BUFFERS);
01198 return -1;
01199 }
01200
01201 pring = &edt_p->rb_control[index];
01202
01203
01204
01205 pring->size = bufsize;
01206 pring->write_flag = write_flag;
01207
01208 if (pdata || (edt_p->mmap_buffers))
01209 {
01210 pring->owned = FALSE;
01211 if (edt_p->fullbufsize)
01212 allocated_size = edt_p->fullbufsize;
01213 }
01214 else
01215 {
01216 #ifdef _NT_
01217
01218 if (allocated_size & (SECTOR_SIZE-1))
01219 allocated_size = ((allocated_size / SECTOR_SIZE)+1)* SECTOR_SIZE;
01220 #endif
01221 pdata =
01222 edt_alloc(allocated_size);
01223 pring->owned = TRUE;
01224 }
01225
01226 pring->allocated_size = allocated_size;
01227
01228 edt_p->ring_buffers[index] = pdata;
01229
01230 sysargs.index = index;
01231 sysargs.writeflag = write_flag;
01232 #ifdef WIN32
01233 sysargs.addr = (uint64_t) (pdata);
01234 #else
01235 sysargs.addr = (uint64_t) ((unsigned long)pdata);
01236 #endif
01237
01238 sysargs.size = bufsize;
01239
01240 if (edt_p->mmap_buffers)
01241 {
01242 if ((rc = edt_ioctl(edt_p, EDTS_BUF_MMAP, &sysargs)) == 0)
01243 {
01244 #ifdef __sun
01245 edt_sun_lock_mem(edt_p, index, write_flag, pring);
01246 #endif
01247 return 0;
01248
01249 }
01250 else
01251 {
01252 edt_msg(EDT_MSG_FATAL, "Unable to configure ring buffer\n");
01253 edt_msg(EDT_MSG_FATAL, "rc = %d\n", rc);
01254 return rc;
01255 }
01256 }
01257 else if (edt_ioctl(edt_p, EDTS_BUF, &sysargs) == 0)
01258 {
01259 #ifdef __sun
01260 edt_sun_lock_mem(edt_p, index, write_flag, pring);
01261 #endif
01262 return 0;
01263 }
01264 return (-1);
01265 }
01266
01267
01268
01269
01270
01271
01272 int
01273 edt_add_ring_buffer(EdtDev * edt_p,
01274 unsigned int bufsize,
01275 int write_flag,
01276 void *pdata)
01277 {
01278
01279 int index = -1;
01280
01281 int i;
01282
01283 if (!edt_p->mmap_buffers)
01284 {
01285
01286
01287
01288 for (i = 0; i < MAX_DMA_BUFFERS; i++)
01289 if (edt_p->ring_buffers[i] == NULL)
01290 break;
01291
01292 if (i == MAX_DMA_BUFFERS)
01293 return -1;
01294
01295 index = i;
01296
01297 edt_p->ring_buffer_numbufs++;
01298
01299 edt_ioctl(edt_p, EDTS_NUMBUFS, &edt_p->ring_buffer_numbufs);
01300
01301 edt_configure_ring_buffer(edt_p, index, bufsize, write_flag, (u_char *) pdata);
01302 }
01303
01304 return index;
01305 }
01306
01307
01308
01309
01310
01311
01312
01313
01314 int
01315 edt_configure_channel_ring_buffers(EdtDev *edt_p, int bufsize, int numbufs,
01316 int write_flag, unsigned char **bufarray)
01317 {
01318 return edt_configure_ring_buffers(edt_p, bufsize, numbufs,
01319 write_flag, bufarray) ;
01320 }
01321
01322 static
01323 int edt_check_ring_buf_parms(EdtDev *edt_p, int numbufs, int bufsize,
01324 unsigned char *pdata, unsigned char ** bufarray)
01325
01326 {
01327
01328 int maxbufs;
01329
01330 if (!edt_p)
01331 {
01332 edt_msg_perror(EDTFATAL, "Invalid edt handle\n");
01333 return -1;
01334 }
01335
01336
01337
01338 if (bufsize & 0x01)
01339 {
01340 edt_set_errno(EINVAL); ;
01341
01342 edt_msg_perror(EDTFATAL, "edt_configure_ring_buffers: bufsize must be an even number of bytes\n") ;
01343 return -1 ;
01344 }
01345 maxbufs = edt_get_max_buffers(edt_p) ;
01346 if (numbufs > maxbufs)
01347 {
01348
01349 edt_set_errno(EINVAL); ;
01350
01351 edt_msg_perror(EDTFATAL,
01352 "edt_configure_ring_buffers: number of bufs exceeds maximum\n") ;
01353 edt_msg_perror(EDTFATAL,
01354 "use edt_set_max_buffers to increase max\n") ;
01355 return -1 ;
01356 }
01357
01358 edt_p->mmap_buffers = edt_get_mmap_buffers(edt_p);
01359
01360 if (edt_p->mmap_buffers)
01361 {
01362 if (edt_p->buffer_granularity < PAGE_SIZE)
01363 edt_p->buffer_granularity = PAGE_SIZE;
01364
01365 }
01366
01367 if (edt_p->mmap_buffers && ((pdata != NULL) || (bufarray != NULL)))
01368 {
01369
01370 edt_set_errno(EINVAL); ;
01371
01372 edt_msg_perror(EDTFATAL,
01373 "edt_configure_ring_buffers: can't pass in user pointer when using mmap kernel buffers\n") ;
01374
01375 return -1;
01376 }
01377
01378 return 0;
01379 }
01380
01381 caddr_t
01382 edt_reserve_kernel_mem(EdtDev *edt_p, u_int totalsize)
01383
01384 {
01385 caddr_t p = NULL;
01386 buf_args sysargs;
01387
01388 memset(&sysargs, 0, sizeof(sysargs));
01389
01390 sysargs.size = totalsize;
01391
01392 edt_ioctl(edt_p, EDTS_ALLOC_KBUFFER,&sysargs);
01393
01394 p = (caddr_t) sysargs.addr;
01395
01396 return p;
01397
01398 }
01399
01400
01401 #define EDT_DMAMEM_OFFSET 0x10000000
01402
01403 int
01404 edt_unmap_dmamem(EdtDev *edt_p)
01405 {
01406
01407 #ifdef __linux__
01408
01409 if (edt_p->base_buffer)
01410 munmap(edt_p->base_buffer, edt_p->totalsize);
01411 #elif defined(WIN32)
01412
01413 caddr_t p = NULL;
01414 buf_args sysargs;
01415
01416 memset(&sysargs, 0, sizeof(sysargs));
01417
01418 sysargs.size = 0;
01419
01420 edt_ioctl(edt_p, EDTS_ALLOC_KBUFFER,&sysargs);
01421
01422 #endif
01423
01424 return 0;
01425 }
01426
01427 caddr_t
01428 edt_map_dmamem(EdtDev *edt_p)
01429 {
01430
01431 caddr_t ret = NULL;
01432
01433 #ifdef __linux__
01434 int pagen = EDT_DMAMEM_OFFSET;
01435
01436 ret = (caddr_t) mmap((caddr_t)0, edt_p->totalsize, PROT_READ|PROT_WRITE,
01437 MAP_SHARED, edt_p->fd, pagen);
01438
01439 #elif defined(WIN32)
01440
01441
01442 ret = (caddr_t) edt_p->base_buffer;
01443
01444 #endif
01445
01446 if (ret == ((caddr_t)-1)) {
01447 perror("mmap call");
01448 return(0) ;
01449 }
01450
01451 return(ret) ;
01452 }
01453
01454 static int
01455 edt_allocate_ring_buffer_memory(EdtDev *edt_p, int bufsize, int numbufs, u_char *user_mem, u_char **buffers)
01456
01457 {
01458
01459 unsigned char * bp;
01460 int i;
01461
01462 edt_p->fullbufsize = edt_get_total_bufsize(edt_p, bufsize, edt_p->header_size);
01463
01464 edt_p->totalsize = edt_p->fullbufsize * numbufs;
01465
01466 #ifdef __linux__
01467 if (edt_p->mmap_buffers)
01468 {
01469
01470
01471
01472 for (i=0;i<numbufs;i++)
01473 buffers[i] = NULL;
01474
01475 return 0;
01476 }
01477 #endif
01478
01479
01480 if (edt_p->base_buffer)
01481 {
01482 edt_free(edt_p->base_buffer);
01483 edt_p->base_buffer = NULL;
01484 }
01485
01486 if (user_mem)
01487 {
01488 bp = user_mem;
01489 }
01490 else
01491 {
01492
01493
01494 if (edt_p->mmap_buffers)
01495 {
01496
01497 edt_p->ring_buffers_allocated = TRUE;
01498 edt_p->base_buffer = (u_char *) edt_reserve_kernel_mem(edt_p, edt_p->totalsize);
01499 }
01500 else
01501 {
01502 edt_p->ring_buffers_allocated = TRUE;
01503 edt_p->base_buffer = edt_alloc(edt_p->totalsize);
01504 }
01505
01506 if (!edt_p->base_buffer)
01507 {
01508 edt_msg_perror(EDTFATAL, "Unable to allocate buffer memory\n");
01509 return -1;
01510 }
01511
01512 bp = edt_p->base_buffer;
01513
01514
01515 }
01516
01517 if (edt_p->header_offset < 0)
01518 bp += ((int) edt_p->header_size);
01519
01520 for (i=0;i<numbufs;i++)
01521 {
01522 buffers[i] = bp;
01523 bp += edt_p->fullbufsize;
01524 }
01525
01526
01527 return 0;
01528
01529 }
01530
01531
01578 static int
01579 edt_setup_ring_buffers(EdtDev *edt_p, int bufsize, int numbufs,
01580 int write_flag, unsigned char *pdata, unsigned char **bufarray)
01581 {
01582 int i;
01583 int rc;
01584
01585 u_char *localbuf[MAX_DMA_BUFFERS];
01586 u_char ** buffers;
01587
01588 buffers = (bufarray != NULL)?bufarray:localbuf;
01589
01590 if ((rc = edt_check_ring_buf_parms(edt_p, numbufs, bufsize, pdata, bufarray)) != 0)
01591 return rc;
01592
01593 if (edt_p->ring_buffers_configured)
01594 edt_disable_ring_buffers(edt_p);
01595
01596 edt_p->nextwbuf = 0;
01597 edt_p->donecount = 0;
01598 edt_p->ring_buffer_bufsize = bufsize;
01599 edt_p->ring_buffer_numbufs = numbufs;
01600
01601 if (write_flag)
01602 edt_set_direction(edt_p, EDT_WRITE);
01603 else
01604 edt_set_direction(edt_p, EDT_READ);
01605
01606 edt_p->write_flag = write_flag;
01607
01608 edt_ioctl(edt_p, EDTS_NUMBUFS, &numbufs);
01609
01610 if (bufarray == NULL)
01611 {
01612 if (edt_allocate_ring_buffer_memory(edt_p, bufsize, numbufs, pdata, buffers) != 0)
01613 return -1;
01614
01615 edt_p->ring_buffers_allocated = !edt_p->mmap_buffers && (pdata == NULL);
01616 }
01617
01618 for (i = 0; i < numbufs; i++)
01619 {
01620 if (edt_configure_ring_buffer(edt_p, i,
01621 bufsize,
01622 write_flag,
01623 buffers[i]) == 0)
01624 {
01625
01626 }
01627 else
01628 {
01629 return -1;
01630 }
01631 }
01632
01633 if (edt_p->mmap_buffers)
01634 {
01635 u_char *bp;
01636
01637 edt_p->base_buffer = (u_char *) edt_map_dmamem(edt_p);
01638 bp = edt_p->base_buffer;
01639
01640 for (i=0;i<numbufs;i++)
01641 {
01642 edt_p->ring_buffers[i] = bp;
01643 bp += edt_p->fullbufsize;
01644 }
01645
01646
01647 bp = edt_p->base_buffer;
01648 for (i=0; i<(int)edt_p->totalsize;i += PAGE_SIZE)
01649 bp[i] = 0x5a;
01650
01651
01652 }
01653
01654 edt_p->ring_buffers_configured = 1;
01655
01656 return 0;
01657 }
01658
01659
01660
01661 void edt_set_buffer_granularity(EdtDev *edt_p, u_int granularity)
01662
01663 {
01664 edt_p->buffer_granularity = granularity;
01665 }
01666
01667
01678 int
01679 edt_get_total_bufsize(EdtDev *edt_p,
01680 int bufsize,
01681 int header_size)
01682
01683 {
01684 int fullbufsize;
01685
01686 fullbufsize = header_size + bufsize;
01687
01688 if (edt_p->buffer_granularity)
01689 if (fullbufsize % edt_p->buffer_granularity)
01690 fullbufsize = ((fullbufsize / edt_p->buffer_granularity)+1)* edt_p->buffer_granularity;
01691
01692 return fullbufsize;
01693 }
01694
01695
01741 int
01742 edt_configure_ring_buffers(EdtDev *edt_p, int bufsize, int numbufs,
01743 int write_flag, unsigned char **bufarray)
01744 {
01745 return edt_setup_ring_buffers(edt_p, bufsize, numbufs, write_flag, NULL, bufarray);
01746
01747 }
01748
01759 int
01760 edt_configure_block_buffers_mem(EdtDev *edt_p,
01761 int bufsize,
01762 int numbufs,
01763 int write_flag,
01764 int header_size,
01765 int header_before,
01766 u_char *user_mem)
01767
01768 {
01769
01770
01771 if (header_before && header_size)
01772 {
01773 if (header_size & (SECTOR_SIZE-1))
01774 header_size = ((header_size / SECTOR_SIZE)+1)* SECTOR_SIZE;
01775 }
01776
01777
01778 edt_p->header_size = header_size;
01779 edt_p->header_offset = (header_before)? -header_size : bufsize;
01780
01781
01782 return edt_setup_ring_buffers(edt_p, bufsize, numbufs, write_flag, user_mem, NULL);
01783
01784 }
01785
01786
01865 int
01866 edt_configure_block_buffers(EdtDev *edt_p, int bufsize, int numbufs, int write_flag,
01867 int header_size, int header_before)
01868
01869 {
01870
01871 return edt_configure_block_buffers_mem(edt_p,
01872 bufsize,
01873 numbufs,
01874 write_flag,
01875 header_size,
01876 header_before,
01877 NULL);
01878
01879 }
01880
01881
01895 int
01896 edt_disable_ring_buffer(EdtDev *edt_p,
01897 int whichone)
01898
01899 {
01900 if (edt_p->ring_buffers[whichone])
01901 {
01902
01903
01904 edt_ioctl(edt_p, EDTS_FREEBUF, &whichone);
01905 edt_msg(EDTDEBUG, "free buf %d\n", whichone);
01906
01907 #ifdef __sun
01908 {
01909 u_int using_lock ;
01910 using_lock = edt_get_umem_lock(edt_p) ;
01911 if (!using_lock)
01912 {
01913 edt_msg(EDTDEBUG, "joining user buf %d tid %x\n",
01914 whichone, edt_p->rb_control[whichone].ring_tid);
01915 thr_join(edt_p->rb_control[whichone].ring_tid, NULL, NULL);
01916
01917 edt_msg(EDTDEBUG, "join user buf %d done\n", whichone);
01918 }
01919 }
01920 #endif
01921
01922 if (edt_p->rb_control[whichone].owned)
01923 {
01924 edt_msg(EDTDEBUG, "free user buf %d\n", whichone);
01925 edt_free(edt_p->ring_buffers[whichone]);
01926 }
01927
01928 edt_p->ring_buffers[whichone] = NULL;
01929
01930 }
01931 #if defined(__hpux)
01932 {
01933 int pret ;
01934 pret = plock(UNLOCK) ;
01935 }
01936 #endif
01937
01938 return 0;
01939
01940 }
01941
01942
01954 int
01955 edt_disable_ring_buffers(EdtDev *edt_p)
01956
01957 {
01958 int i;
01959
01960
01961 for (i = edt_p->ring_buffer_numbufs - 1; i >= 0 ; i--)
01962 {
01963 edt_disable_ring_buffer(edt_p,i);
01964 }
01965
01966 edt_p->ring_buffers_configured = 0;
01967 edt_p->ring_buffers_allocated = 0;
01968 #if defined(__hpux)
01969 {
01970 int pret ;
01971 pret = plock(UNLOCK) ;
01972 }
01973 #elif defined(sgi)
01974 munlockall();
01975 #endif
01976
01977 if (edt_p->base_buffer )
01978 {
01979
01980 if (edt_p->mmap_buffers)
01981 edt_unmap_dmamem(edt_p);
01982 else
01983 edt_free(edt_p->base_buffer);
01984 edt_p->base_buffer = NULL;
01985 }
01986
01987
01988 {
01989 int one = 1;
01990 edt_p->ring_buffer_numbufs = 0;
01991 edt_ioctl(edt_p, EDTS_NUMBUFS, &one);
01992 edt_ioctl(edt_p, EDTS_CLEAR_DMAID, &one);
01993 }
01994
01995 return 0;
01996 }
01997
02012 int
02013 edt_start_buffers(EdtDev *edt_p, uint_t count)
02014 {
02015 if (edt_p->devid == DMY_ID && edt_p->dd_p)
02016 dmy_started += count ;
02017 edt_msg(EDTDEBUG, "edt_start_buffers %d\n", count);
02018 edt_ioctl(edt_p, EDTS_STARTBUF, &count);
02019 return 0;
02020 }
02021
02022
02023 int
02024 edt_lockoff(EdtDev * edt_p)
02025 {
02026 int count = 0;
02027
02028 edt_ioctl(edt_p, EDTS_STARTBUF, &count);
02029 return 0;
02030 }
02031
02041 unsigned int
02042 edt_allocated_size(EdtDev *edt_p, int buffer)
02043
02044 {
02045 if (buffer >= 0 && buffer < (int) edt_p->ring_buffer_numbufs)
02046 {
02047 return edt_p->rb_control[buffer].allocated_size;
02048 }
02049 return 0;
02050 }
02051
02073 int
02074 edt_set_buffer(EdtDev *edt_p, uint_t bufnum)
02075 {
02076 edt_ioctl(edt_p, EDTS_SETBUF, &bufnum);
02077 edt_p->donecount = bufnum;
02078 if (edt_p->ring_buffer_numbufs)
02079 edt_p->nextwbuf = bufnum % edt_p->ring_buffer_numbufs;
02080 return 0;
02081 }
02082
02103 int
02104 edt_read(EdtDev *edt_p, void *buf, uint_t size)
02105 {
02106 u_char *thisbuf;
02107
02108
02109 if (size & 0x01)
02110 -- size ;
02111
02112
02113 if (edt_p->last_direction != 1)
02114 edt_set_direction(edt_p, EDT_READ);
02115
02116
02117 if (edt_p->devid != DMY_ID)
02118 {
02119
02120 if (edt_configure_ring_buffers(edt_p, size, 1, EDT_READ, NULL) != 0)
02121
02122 return -1;
02123
02124
02125 edt_start_buffers(edt_p, 1) ;
02126
02127
02128 thisbuf = edt_wait_for_buffers(edt_p, 1);
02129
02130
02131 if (edt_timeouts(edt_p))
02132 {
02133 size = edt_get_timeout_count(edt_p);
02134 edt_msg(EDTDEBUG, "edt_read timeout with count %d\n", size);
02135 }
02136
02137
02138 memcpy(buf, thisbuf, size);
02139
02140
02141 edt_disable_ring_buffers(edt_p) ;
02142
02143 }
02144
02145
02146 return (size);
02147
02148 }
02149
02173 int
02174 edt_write(EdtDev *edt_p, void *buf, uint_t size)
02175 {
02176 u_char **bufs;
02177
02178
02179 if (size & 0x01)
02180 -- size ;
02181
02182 if (edt_p->last_direction != (EDT_WRITE+1))
02183 edt_set_direction(edt_p, EDT_WRITE);
02184
02185 if (edt_p->devid != DMY_ID)
02186 {
02187
02188 if (edt_configure_ring_buffers(edt_p, size, 1, EDT_WRITE, NULL) != 0)
02189
02190 return -1;
02191
02192
02193 bufs = edt_buffer_addresses(edt_p);
02194
02195
02196 memcpy(bufs[0], buf, size);
02197
02198
02199 edt_start_buffers(edt_p, 1) ;
02200
02201
02202 (void) edt_wait_for_buffers(edt_p, 1);
02203
02204
02205 if (edt_timeouts(edt_p))
02206 {
02207 size = edt_get_timeout_count(edt_p);
02208 edt_msg(EDTDEBUG, "edt_read timeout with count %d\n", size);
02209 }
02210
02211
02212 edt_disable_ring_buffers(edt_p) ;
02213
02214 }
02215
02216
02217 return (size);
02218
02219 }
02220
02221 int
02222 edt_write_pio(EdtDev *edt_p, u_char *buf, int size)
02223
02224 {
02225 edt_sized_buffer argbuf;
02226
02227 argbuf.size = size;
02228
02229 memcpy(argbuf.data, buf, size);
02230
02231 return edt_ioctl(edt_p, EDTS_WRITE_PIO, &argbuf);
02232
02233 }
02234
02235
02248 unsigned char *
02249 edt_next_writebuf(EdtDev *edt_p)
02250
02251 {
02252 unsigned char *buf_p;
02253
02254 buf_p = edt_p->ring_buffers[edt_p->nextwbuf];
02255 edt_p->nextwbuf = ++edt_p->nextwbuf % edt_p->ring_buffer_numbufs;
02256 return buf_p;
02257 }
02258
02273 uint_t
02274 edt_next_writebuf_index(EdtDev *edt_p)
02275
02276 {
02277 uint_t ret = edt_p->nextwbuf;
02278 edt_p->nextwbuf = ++edt_p->nextwbuf % edt_p->ring_buffer_numbufs;
02279 return ret;
02280 }
02281
02294 unsigned char **
02295 edt_buffer_addresses(EdtDev *edt_p)
02296 {
02297 return (edt_p->ring_buffers);
02298 }
02299
02322 unsigned char *
02323 edt_wait_buffers_timed(EdtDev * edt_p, int count, u_int * timep)
02324 {
02325 u_char *ret;
02326
02327 edt_msg(EDTDEBUG, "edt_wait_buffers_timed()\n");
02328
02329 ret = edt_wait_for_buffers(edt_p, count);
02330 edt_get_timestamp(edt_p, timep, edt_p->donecount - 1);
02331
02332 edt_msg(EDTDEBUG, "buf %d done %s (%x %x)\n",
02333 edt_p->donecount,
02334 edt_timestring(timep),
02335 timep[0], timep[1]);
02336
02337 return (ret);
02338 }
02339
02353 unsigned char *
02354 edt_last_buffer(EdtDev * edt_p)
02355 {
02356 u_char *ret;
02357 bufcnt_t donecount;
02358 bufcnt_t last_wait;
02359 int delta;
02360
02361 donecount = edt_done_count(edt_p);
02362 last_wait = edt_p->donecount;
02363
02364 edt_msg(EDTDEBUG, "edt_last_buffer() last %d cur %d\n",
02365 last_wait, donecount);
02366
02367 delta = donecount - last_wait;
02368
02369 if (delta == 0)
02370 delta = 1;
02371
02372 ret = edt_wait_for_buffers(edt_p, delta) ;
02373 return (ret);
02374 }
02375
02397 unsigned char *
02398 edt_last_buffer_timed(EdtDev * edt_p, u_int * timep)
02399 {
02400 u_char *ret;
02401 bufcnt_t donecount;
02402 bufcnt_t last_wait;
02403 int delta;
02404
02405 donecount = edt_done_count(edt_p);
02406 last_wait = edt_p->donecount;
02407
02408 edt_msg(EDTDEBUG, "edt_last_buffer_timed() last %d cur %d\n",
02409 last_wait, donecount);
02410
02411 delta = donecount - last_wait;
02412
02413 if (delta == 0)
02414 delta = 1;
02415
02416 ret = edt_wait_buffers_timed(edt_p, delta, timep);
02417 return (ret);
02418 }
02419
02420 char *
02421 edt_timestring(u_int * timep)
02422 {
02423 static char timestr[100];
02424 struct tm *tm_p;
02425 time_t testtm ;
02426
02427
02428
02429 testtm = timep[0] ;
02430 tm_p = localtime(&testtm);
02431 timep++;
02432 sprintf(timestr, "%02d:%02d:%02d.%06d",
02433 tm_p->tm_hour,
02434 tm_p->tm_min,
02435 tm_p->tm_sec,
02436 *timep);
02437
02438 return timestr;
02439 }
02440
02458 int
02459 edt_do_timeout(EdtDev *edt_p)
02460
02461 {
02462 int dummy;
02463
02464 return edt_ioctl(edt_p,EDTS_DOTIMEOUT,&dummy);
02465
02466 }
02467
02481 int
02482 edt_inc_timeout(EdtDev *edt_p)
02483 {
02484 int dummy;
02485
02486 return edt_ioctl(edt_p,EDTS_INCTIMEOUT,&dummy);
02487
02488 }
02489
02518 unsigned char *
02519 edt_wait_for_buffers(EdtDev * edt_p, int count)
02520 {
02521 int bufnum;
02522 int ret = 0;
02523 bufcnt_t tmpcnt = count ;
02524 #ifdef _NT_
02525 int timeoutval = edt_get_rtimeout(edt_p);
02526 #endif
02527
02528 edt_msg(EDTDEBUG, "edt_wait_for_buffers(%d)\n", count);
02529
02530 if (edt_p->ring_buffer_numbufs == 0)
02531 {
02532 edt_msg(EDTDEBUG, "wait for buffers called with 0 buffers\n");
02533 return (0);
02534 }
02535 tmpcnt += edt_p->donecount;
02536
02537 #ifdef _NT_
02538
02539 edt_p->last_wait_ret = EDT_WAIT_OK;
02540
02541 if (edt_get_drivertype(edt_p) != EDT_WDM_DRIVER)
02542
02543 {
02544 HANDLE event;
02545 int rc;
02546
02547
02548 if (!edt_p->event_funcs[EDT_EVENT_BUF].wait_event)
02549 {
02550 edt_get_kernel_event(edt_p, EDT_EVENT_BUF);
02551 }
02552
02553 event = edt_p->event_funcs[EDT_EVENT_BUF].wait_event;
02554
02555 while (edt_done_count(edt_p) < tmpcnt)
02556 {
02557
02558
02559
02560 if (timeoutval == 0)
02561 timeoutval = INFINITE;
02562
02563 ret = EDT_WAIT_OK;
02564 edt_clear_wait_status(edt_p);
02565
02566 rc = WaitForSingleObject(event, timeoutval);
02567
02568 if (rc == WAIT_TIMEOUT)
02569 {
02570 if (edt_get_timeout_ok(edt_p))
02571 {
02572 ret = EDT_WAIT_OK_TIMEOUT;
02573 }
02574 else
02575 {
02576 edt_msg(EDTDEBUG, "timeout...\n");
02577
02578
02579
02580 edt_do_timeout(edt_p);
02581 ResetEvent(event) ;
02582 ret = EDT_WAIT_TIMEOUT;
02583 }
02584 break;
02585 }
02586 else if (edt_had_user_dma_wakeup(edt_p))
02587 {
02588 ret = EDT_WAIT_USER_WAKEUP;
02589 break;
02590
02591 }
02592 }
02593 }
02594 else
02595 {
02596 ret = edt_ioctl(edt_p, EDTS_WAITBUF, &tmpcnt);
02597 }
02598 #else
02599
02600 ret = edt_ioctl(edt_p, EDTS_WAITBUF, &tmpcnt);
02601 ret = edt_get_wait_status(edt_p);
02602
02603 #endif
02604
02605
02606 edt_msg(EDTDEBUG, "edt_wait_for_buffers %d done ret = %d\n", count,
02607 ret);
02608 if (ret == EDT_WAIT_OK || ret == EDT_WAIT_TIMEOUT)
02609 edt_p->donecount = tmpcnt;
02610
02611
02612
02613 if (edt_p->ring_buffer_numbufs)
02614 bufnum = (edt_p->donecount - 1) % edt_p->ring_buffer_numbufs;
02615 else
02616 return NULL;
02617
02618 #ifdef VXWORKS
02619
02620
02621 CACHE_DMA_INVALIDATE(edt_p->ring_buffers[bufnum],
02622 edt_p->rb_control[bufnum].size);
02623 #if defined(AV3_BOARD)
02624 printf("cache inv %x %x\n",
02625 edt_p->ring_buffers[bufnum], edt_p->rb_control[bufnum].size);
02626 bslPpcCacheInv(edt_p->ring_buffers[bufnum], edt_p->rb_control[bufnum].size);
02627 #endif
02628 #endif
02629
02630 edt_p->last_wait_ret = ret;
02631
02632 return (edt_p->ring_buffers[bufnum]);
02633
02634 }
02635
02660 int
02661 edt_get_timestamp(EdtDev * edt_p, u_int * timep, u_int bufnum)
02662 {
02663
02664 u_int timevals[3];
02665
02666 timevals[0] = bufnum;
02667 if (edt_p->devid == DMY_ID)
02668 {
02669 u_int inttime ;
02670 double testtime ;
02671 timevals[0] = bufnum ;
02672 testtime = edt_timestamp();
02673 inttime = (u_int)testtime ;
02674 testtime -= inttime ;
02675 *timep++ = inttime ;
02676 *timep++ = (u_int)(testtime * 1000000.0) ;
02677 }
02678 else
02679 {
02680 edt_ioctl(edt_p, EDTG_TMSTAMP, timevals);
02681
02682 edt_msg(EDTDEBUG, "%x %x %x %x ", bufnum,
02683 timevals[0],
02684 timevals[1],
02685 timevals[2]);
02686 *timep++ = timevals[1];
02687 *timep++ = timevals[2];
02688 }
02689
02690 return (timevals[0]);
02691 }
02692
02705 unsigned char *
02706 edt_wait_for_next_buffer(EdtDev *edt_p)
02707
02708 {
02709 bufcnt_t count;
02710 unsigned int bufnum;
02711 #ifdef _NT_
02712 int timeoutval = edt_get_rtimeout(edt_p);
02713 #endif
02714
02715 edt_ioctl(edt_p, EDTG_BUFDONE, &count);
02716 count++;
02717 if (edt_p->ring_buffer_numbufs == 0) {
02718
02719 return NULL;
02720 }
02721 bufnum = (count - 1) % edt_p->ring_buffer_numbufs;
02722
02723 #ifdef _NT_
02724 if (edt_get_drivertype(edt_p) != EDT_WDM_DRIVER)
02725
02726 {
02727 HANDLE event;
02728 int rc;
02729
02730 if (!edt_p->event_funcs[EDT_EVENT_BUF].wait_event)
02731 {
02732 edt_get_kernel_event(edt_p, EDT_EVENT_BUF);
02733 }
02734
02735 event = edt_p->event_funcs[EDT_EVENT_BUF].wait_event;
02736
02737 while (edt_done_count(edt_p) < (bufcnt_t) count)
02738 {
02739
02740
02741
02742 if (timeoutval == 0)
02743 timeoutval = INFINITE;
02744
02745 rc = WaitForSingleObject(event, timeoutval);
02746
02747 if (rc == WAIT_TIMEOUT)
02748 {
02749 edt_msg(EDTDEBUG, "timeout...\n");
02750
02751
02752
02753 edt_do_timeout(edt_p);
02754 ResetEvent(event) ;
02755
02756 break;
02757 }
02758
02759 }
02760
02761 }
02762 else
02763 {
02764 edt_ioctl(edt_p, EDTS_WAITBUF, &count);
02765 }
02766 #else
02767
02768 edt_ioctl(edt_p, EDTS_WAITBUF, &count);
02769
02770 #endif
02771
02772 edt_msg(EDTDEBUG, "edt_wait_for_next_buffer %d done\n", count);
02773 edt_p->donecount = count;
02774 return (edt_p->ring_buffers[bufnum]);
02775 }
02776
02777
02792 unsigned char *
02793 edt_get_current_dma_buf(EdtDev * edt_p)
02794 {
02795 unsigned int count;
02796 unsigned int bufnum;
02797 unsigned int todo ;
02798
02799
02800 edt_ioctl(edt_p, EDTG_BUFDONE, &count);
02801
02802 todo = edt_get_todo(edt_p);
02803
02804
02805
02806
02807 if (todo == 0 || todo > count)
02808 count ++;
02809
02810 bufnum = (count - 1) % edt_p->ring_buffer_numbufs;
02811
02812 return (edt_p->ring_buffers[bufnum]);
02813
02814 }
02815
02836 unsigned char *
02837 edt_check_for_buffers(EdtDev *edt_p, uint_t count)
02838 {
02839 unsigned int driver_count;
02840 unsigned int bufnum;
02841 unsigned int target;
02842
02843 target = count + edt_p->donecount;
02844 bufnum = (target - 1) % edt_p->ring_buffer_numbufs;
02845 edt_ioctl(edt_p, EDTG_BUFDONE, &driver_count);
02846 if (driver_count >= target)
02847 {
02848 return edt_wait_for_buffers(edt_p, count);
02849 }
02850 else
02851 return (NULL);
02852 }
02853
02869 bufcnt_t
02870 edt_done_count(EdtDev * edt_p)
02871 {
02872 bufcnt_t donecount = 0;
02873
02874 if (edt_p->devid == DMY_ID)
02875 {
02876 if (edt_p->dd_p)
02877 {
02878 donecount = dmy_started;
02879 }
02880 else printf("DEBUG - dd_p not set for DMY_ID\n") ;
02881 }
02882 else
02883 edt_ioctl(edt_p, EDTG_BUFDONE, &donecount);
02884 return (donecount);
02885 }
02886
02887 uint_t
02888 edt_overflow(EdtDev * edt_p)
02889 {
02890 uint_t overflow;
02891
02892 edt_ioctl(edt_p, EDTG_OVERFLOW, &overflow);
02893 return (overflow);
02894 }
02895
02896
02908 void
02909 edt_perror(char *errstr)
02910 {
02911 #ifdef _NT_
02912 LPVOID lpMsgBuf;
02913
02914 FormatMessage(
02915 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
02916 NULL,
02917 GetLastError(),
02918 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
02919 (LPTSTR) & lpMsgBuf,
02920 0,
02921 NULL
02922 );
02923
02924 edt_msg(EDTWARN, "%s: %s\n", errstr, lpMsgBuf);
02925 #else
02926 edt_msg_perror(EDTWARN, errstr);
02927 #endif
02928 }
02929
02946 u_int
02947 edt_errno(void)
02948 {
02949 #ifdef _NT_
02950 return GetLastError();
02951 #else
02952 extern int errno;
02953 return errno;
02954 #endif
02955 }
02956
02973 uint_t
02974 edt_reg_read(EdtDev * edt_p, uint_t desc)
02975 {
02976 int ret;
02977 edt_buf buf = {0, 0};
02978
02979
02980 #ifdef USB
02981 if (EDT_REG_TYPE(desc) == REMOTE_USB_TYPE)
02982 {
02983 buf.value = usb_reg_read(edt_p, desc) ;
02984 }
02985 else
02986 #endif
02987 {
02988 buf.desc = desc;
02989 ret = edt_ioctl(edt_p, EDTG_REG, &buf);
02990 if (ret < 0)
02991 return ret;
02992 }
02993
02994 if (dump_reg_access)
02995 {
02996 if (is_reg_dumpable(desc))
02997 {
02998 printf("%d: reg read %08x %08x\n", edt_p->channel_no, desc, (uint_t) buf.value);
02999 }
03000 }
03001
03002 return (u_int) buf.value;
03003 }
03004
03020 uint_t
03021 edt_reg_or(EdtDev * edt_p, uint_t desc, uint_t mask)
03022 {
03023 int ret;
03024 uint_t val;
03025 edt_buf buf;
03026
03027 buf.desc = desc;
03028 buf.value = mask;
03029 ret = edt_ioctl(edt_p, EDTS_REG_OR, &buf);
03030 if (ret < 0)
03031 edt_msg_perror(EDTFATAL, "edt_ioctl(EDT_REG_OR)");
03032
03033 if (dump_reg_access)
03034 {
03035 if (is_reg_dumpable(desc))
03036 {
03037 printf("%d: reg or %08x %08x\n", edt_p->channel_no,
03038 desc, (uint_t) buf.value);
03039 }
03040 }
03041 val = (u_int) buf.value;
03042 return val;
03043
03044 }
03045
03061 uint_t
03062 edt_reg_and(EdtDev * edt_p, uint_t desc, uint_t mask)
03063 {
03064 int ret;
03065 uint_t val;
03066 edt_buf buf;
03067
03068 buf.desc = desc;
03069 buf.value = mask;
03070 ret = edt_ioctl(edt_p, EDTS_REG_AND, &buf);
03071 if (ret < 0)
03072 edt_msg_perror(EDTFATAL, "edt_ioctl(EDT_REG_AND)");
03073
03074 if (dump_reg_access)
03075 {
03076 if (is_reg_dumpable(desc))
03077 {
03078 printf("%d: reg and %08x %08x\n", edt_p->channel_no, desc, (uint_t) buf.value);
03079 }
03080 }
03081
03082 val = (u_int) buf.value;
03083 return val;
03084 }
03085
03098 void
03099 edt_reg_clearset(EdtDev * edt_p, uint_t desc, uint_t mask)
03100 {
03101 int ret;
03102 edt_buf buf;
03103
03104 buf.desc = desc;
03105 buf.value = mask;
03106 ret = edt_ioctl(edt_p, EDTS_REG_BIT_CLEARSET, &buf);
03107 if (ret < 0)
03108 edt_msg_perror(EDTFATAL, "edt_ioctl(EDT_REG_BIT_CLEARSET)");
03109
03110 return;
03111 }
03112
03124 void
03125 edt_reg_setclear(EdtDev * edt_p, uint_t desc, uint_t mask)
03126 {
03127 int ret;
03128 edt_buf buf;
03129
03130 buf.desc = desc;
03131 buf.value = mask;
03132 ret = edt_ioctl(edt_p, EDTS_REG_BIT_SETCLEAR, &buf);
03133 if (ret < 0)
03134 edt_msg_perror(EDTFATAL, "edt_ioctl(EDT_REG_BIT_SETCLEAR)");
03135
03136 return;
03137 }
03138
03155 void
03156 edt_reg_write(EdtDev * edt_p, uint_t desc, uint_t value)
03157 {
03158 int ret;
03159 edt_buf buf;
03160
03161 #ifdef USB
03162 if (edt_p->devtype == USB_ID)
03163 {
03164 usb_reg_write(edt_p, desc, value) ;
03165 }
03166 else
03167 #endif
03168 {
03169 buf.desc = desc;
03170 buf.value = value;
03171
03172 ret = edt_ioctl(edt_p, EDTS_REG, &buf);
03173 if (ret < 0)
03174 edt_msg_perror(EDTFATAL, "write");
03175
03176 if (dump_reg_access)
03177 {
03178 if (is_reg_dumpable(desc))
03179 {
03180 printf("%d: reg write %08x %08x\n", edt_p->channel_no,
03181 desc, (uint_t) buf.value);
03182 }
03183 }
03184 }
03185 }
03186
03209 void
03210 edt_startdma_action(EdtDev * edt_p, uint_t val)
03211 {
03212 (void) edt_ioctl(edt_p, EDTS_STARTACT, &val);
03213 }
03214
03245 void
03246 edt_enddma_action(EdtDev * edt_p, uint_t val)
03247 {
03248 (void) edt_ioctl(edt_p, EDTS_ENDACT, &val);
03249 }
03250
03270 void
03271 edt_startdma_reg(EdtDev * edt_p, uint_t desc, uint_t val)
03272 {
03273 int ret;
03274 edt_buf buf;
03275
03276 buf.desc = desc;
03277 buf.value = val;
03278 ret = edt_ioctl(edt_p, EDTS_STARTDMA, &buf);
03279 if (ret < 0)
03280 edt_msg_perror(EDTFATAL, "write");
03281 }
03282
03295 void
03296 edt_enddma_reg(EdtDev * edt_p, uint_t desc, uint_t val)
03297 {
03298 int ret;
03299 edt_buf buf;
03300
03301 buf.desc = desc;
03302 buf.value = val;
03303 ret = edt_ioctl(edt_p, EDTS_ENDDMA, &buf);
03304 if (ret < 0)
03305 edt_msg_perror(EDTFATAL, "write");
03306 }
03307
03308
03309
03341 void
03342 edt_read_start_action(EdtDev * edt_p, u_int enable, u_int reg_desc,
03343 u_char set, u_char clear, u_char setclear, u_char clearset,
03344 int delay1, int delay2)
03345 {
03346 edt_buf buf;
03347 u_int delays;
03348
03349 delays = ((delay1 << 16) & 0xffff0000) | (delay2 & 0xffff);
03350 (void) edt_ioctl(edt_p, EDTS_READ_START_DELAYS, &delays);
03351
03352 buf.flags = enable;
03353 buf.desc = reg_desc;
03354 buf.value = set | (clear << 8) | (setclear << 16) | (clearset << 24);
03355
03356 (void) edt_ioctl(edt_p, EDTS_READ_STARTACT, &buf);
03357 }
03358
03359
03360
03392 void
03393 edt_read_end_action(EdtDev * edt_p, u_int enable, u_int reg_desc,
03394 u_char set, u_char clear, u_char setclear, u_char clearset,
03395 int delay1, int delay2)
03396 {
03397 edt_buf buf;
03398 u_int delays;
03399
03400 delays = ((delay1 << 16) & 0xffff0000) | (delay2 & 0xffff);
03401 (void) edt_ioctl(edt_p, EDTS_READ_END_DELAYS, &delays);
03402
03403 buf.flags = enable;
03404 buf.desc = reg_desc;
03405 buf.value = set | (clear << 8) | (setclear << 16) | (clearset << 24);
03406
03407 (void) edt_ioctl(edt_p, EDTS_READ_ENDACT, &buf);
03408 }
03409
03410
03411
03443 void
03444 edt_write_start_action(EdtDev * edt_p, u_int enable, u_int reg_desc,
03445 u_char set, u_char clear, u_char setclear, u_char clearset,
03446 int delay1, int delay2)
03447 {
03448 edt_buf buf;
03449 u_int delays;
03450
03451 delays = ((delay1 << 16) & 0xffff0000) | (delay2 & 0xffff);
03452 (void) edt_ioctl(edt_p, EDTS_WRITE_START_DELAYS, &delays);
03453
03454 buf.flags = enable;
03455 buf.desc = reg_desc;
03456 buf.value = set | (clear << 8) | (setclear << 16) | (clearset << 24);
03457
03458 (void) edt_ioctl(edt_p, EDTS_WRITE_STARTACT, &buf);
03459 }
03460
03461
03462
03494 void
03495 edt_write_end_action(EdtDev * edt_p, u_int enable, u_int reg_desc,
03496 u_char set, u_char clear, u_char setclear, u_char clearset,
03497 int delay1, int delay2)
03498 {
03499 edt_buf buf;
03500 u_int delays;
03501
03502 delays = ((delay1 << 16) & 0xffff0000) | (delay2 & 0xffff);
03503 (void) edt_ioctl(edt_p, EDTS_WRITE_END_DELAYS, &delays);
03504
03505 buf.flags = enable;
03506 buf.desc = reg_desc;
03507 buf.value = set | (clear << 8) | (setclear << 16) | (clearset << 24);
03508
03509 (void) edt_ioctl(edt_p, EDTS_WRITE_ENDACT, &buf);
03510 }
03511
03512
03513
03534 u_char
03535 edt_intfc_read(EdtDev * edt_p, uint_t offset)
03536 {
03537 u_int read;
03538
03539 read = edt_reg_read(edt_p, INTFC_BYTE | (offset & 0xffff));
03540 return ((u_char) read & 0xff);
03541 }
03542
03564 void
03565 edt_intfc_write(EdtDev * edt_p, uint_t offset, u_char data)
03566 {
03567 edt_reg_write(edt_p, INTFC_BYTE | (offset & 0xffff), data);
03568 }
03569
03604 u_short
03605 edt_intfc_read_short(EdtDev * edt_p, uint_t offset)
03606 {
03607 u_int read;
03608
03609 read = edt_reg_read(edt_p, INTFC_WORD | (offset & 0xffff));
03610 return (read & 0xffff);
03611 }
03612
03635 void
03636 edt_intfc_write_short(EdtDev * edt_p, uint_t offset, u_short data)
03637 {
03638 edt_reg_write(edt_p, INTFC_WORD | (offset & 0xffff), data);
03639 }
03640
03655 uint_t
03656 edt_intfc_read_32(EdtDev * edt_p, uint_t offset)
03657 {
03658 uint_t read;
03659
03660 read = edt_reg_read(edt_p, INTFC_32 | (offset & 0xffff));
03661 return (read);
03662 }
03663
03679 void
03680 edt_intfc_write_32(EdtDev * edt_p, uint_t offset, uint_t data)
03681 {
03682 edt_reg_write(edt_p, INTFC_32 | (offset & 0xffff), data);
03683 }
03684
03685
03686 int
03687 edt_set_rci_chan(EdtDev *edt_p, int unit, int channel)
03688 {
03689 int ret ;
03690 edt_buf buf;
03691 buf.desc = unit;
03692 buf.value = channel;
03693 edt_msg(EDTDEBUG, "set rci unit %d chan %d\n",unit,channel) ;
03694 ret = edt_ioctl(edt_p, EDTS_RCI_CHAN, &buf);
03695 return (ret) ;
03696 }
03697
03698 int
03699 edt_get_rci_chan(EdtDev *edt_p, int unit)
03700 {
03701 int channel ;
03702 edt_buf buf;
03703 buf.desc = unit;
03704 edt_ioctl(edt_p, EDTG_RCI_CHAN, &buf);
03705 channel = (u_int) buf.value ;
03706 edt_msg(EDTDEBUG, "get rci unit %d chan %d\n",unit,channel) ;
03707 return (channel) ;
03708 }
03709
03710 int
03711 edt_set_rci_dma(EdtDev * edt_p, int unit, int channel)
03712
03713 {
03714 char msg[5];
03715 sprintf(msg,"D %d",channel);
03716
03717 edt_send_msg(edt_p,unit,msg,3);
03718 edt_set_rci_chan(edt_p, unit, channel) ;
03719
03720 return 0;
03721 }
03722
03723 int
03724 edt_get_rci_dma(EdtDev * edt_p, int unit)
03725
03726 {
03727 char msgbuf[5];
03728 int channel;
03729 msgbuf[1] = 0;
03730
03731 edt_send_msg(edt_p, unit, "D", 1);
03732 edt_serial_wait(edt_p, 100, 0) ;
03733 edt_get_msg(edt_p, msgbuf, sizeof(msgbuf));
03734
03735 channel = atoi(&msgbuf[2]);
03736
03737 return channel;
03738
03739 }
03740
03755 int
03756 edt_set_burst_enable(EdtDev * edt_p, int onoff)
03757 {
03758 return (edt_ioctl(edt_p, EDTS_BURST_EN, &onoff));
03759 }
03760
03761
03775 int
03776 edt_get_burst_enable(EdtDev * edt_p)
03777 {
03778 int val;
03779
03780 edt_ioctl(edt_p, EDTG_BURST_EN, &val);
03781 return (val);
03782 }
03783
03784 int
03785 edt_set_continuous(EdtDev * edt_p, int val)
03786 {
03787 #ifdef PDV
03788 u_int tmp ;
03789 tmp = edt_p->dd_p->datapath_reg ;
03790
03791 edt_ioctl(edt_p, EDTS_PDVDPATH, &tmp);
03792 return (edt_ioctl(edt_p, EDTS_PDVCONT, &val));
03793 #else
03794 return 0;
03795 #endif
03796 }
03797
03798 void
03799 edt_reset_counts(EdtDev * edt_p)
03800 {
03801 int dmy;
03802
03803 edt_ioctl(edt_p, EDTS_RESETCOUNT, &dmy);
03804 }
03805
03806 void
03807 edt_reset_serial(EdtDev * edt_p)
03808 {
03809 int dmy;
03810
03811 dmy = edt_p->channel_no ;
03812 edt_ioctl(edt_p, EDTS_RESETSERIAL, &dmy);
03813 }
03814
03815
03816 void
03817 edt_flush_channel(EdtDev *edt_p, int channel)
03818
03819 {
03820 u_int dma_cfg = edt_reg_read(edt_p, EDT_DMA_CFG) ;
03821
03822 dma_cfg &= ~(EDT_EMPTY_CHAN | EDT_EMPTY_CHAN_FIFO) ;
03823
03824
03825
03826
03827 dma_cfg |= ((channel << EDT_EMPTY_CHAN_SHIFT) | EDT_RFIFO_ENB) ;
03828 edt_reg_write(edt_p, EDT_DMA_CFG, dma_cfg) ;
03829
03830
03831
03832
03833 dma_cfg |= EDT_EMPTY_CHAN_FIFO ;
03834 edt_reg_write(edt_p, EDT_DMA_CFG, dma_cfg) ;
03835
03836 dma_cfg &= ~EDT_EMPTY_CHAN_FIFO ;
03837 edt_reg_write(edt_p, EDT_DMA_CFG, dma_cfg) ;
03838
03839
03840 }
03841
03842 #if defined( PCD )
03843
03844 u_char
03845 pcd_get_option(EdtDev * edt_p)
03846 {
03847 return (edt_intfc_read(edt_p, PCD_OPTION));
03848 }
03849
03850 u_char
03851 pcd_get_cmd(EdtDev * edt_p)
03852 {
03853 return (edt_intfc_read(edt_p, PCD_CMD));
03854 }
03855
03856 void
03857 pcd_set_cmd(EdtDev * edt_p, u_char val)
03858 {
03859 edt_intfc_write(edt_p, PCD_CMD, val);
03860 }
03861
03862 u_char
03863 pcd_get_funct(EdtDev * edt_p)
03864 {
03865 return (edt_intfc_read(edt_p, PCD_FUNCT));
03866 }
03867
03868 void
03869 pcd_set_funct(EdtDev * edt_p, u_char val)
03870 {
03871 edt_intfc_write(edt_p, PCD_FUNCT, val);
03872 }
03873
03874 u_char
03875 pcd_get_stat(EdtDev * edt_p)
03876 {
03877 return ((u_char) edt_intfc_read(edt_p, PCD_STAT));
03878 }
03879
03880 u_char
03881 pcd_get_stat_polarity(EdtDev * edt_p)
03882 {
03883 return (edt_intfc_read(edt_p, PCD_STAT_POLARITY));
03884 }
03885
03886 void
03887 pcd_set_stat_polarity(EdtDev * edt_p, u_char val)
03888 {
03889 u_char polarity = edt_intfc_read(edt_p, PCD_STAT_POLARITY);
03890
03891 polarity &= 0xF0;
03892 polarity |= val;
03893
03894 edt_intfc_write(edt_p, PCD_STAT_POLARITY, polarity);
03895 }
03896
03897 void
03898 pcd_set_byteswap(EdtDev * edt_p, int val)
03899 {
03900 u_char tmp;
03901
03902 tmp = edt_intfc_read(edt_p, PCD_CONFIG);
03903 if (val)
03904 tmp |= PCD_BYTESWAP;
03905 else
03906 tmp &= ~PCD_BYTESWAP;
03907 edt_intfc_write(edt_p, PCD_CONFIG, tmp);
03908 }
03909
03910
03911
03912 void
03913 pcd_flush_channel(EdtDev * edt_p, int channel)
03914 {
03915 u_short ssd16_chen = edt_reg_read(edt_p, SSD16_CHEN) ;
03916
03917 ssd16_chen &= ~(1 << channel);
03918 edt_reg_write(edt_p, SSD16_CHEN, ssd16_chen) ;
03919
03920 edt_flush_channel(edt_p,channel);
03921
03922
03923 ssd16_chen |= (1 << channel);
03924 edt_reg_write(edt_p, SSD16_CHEN, ssd16_chen) ;
03925
03926 }
03927
03928
03929
03930
03931
03932
03933
03934 void
03935 pcd_pio_init(EdtDev *edt_p)
03936 {
03937 static u_char * mapaddr = 0 ;
03938
03939 if (mapaddr == 0)
03940 {
03941 mapaddr = (u_char *) edt_mapmem(edt_p, 0, 256) ;
03942 edt_p->reg_fifo_io = (u_int *)(mapaddr + (EDT_GP_OUTPUT & 0xff)) ;
03943 edt_p->reg_fifo_cnt = (u_char *)(mapaddr + (EDT_DMA_CFG & 0xff) + 3) ;
03944 edt_p->reg_fifo_ctl = (u_char *)(mapaddr + (EDT_DMA_CFG & 0xff) + 1) ;
03945 edt_p->reg_intfc_off = (volatile u_char *) mapaddr + (EDT_REMOTE_OFFSET & 0xff) ;
03946 edt_p->reg_intfc_dat = (volatile u_char *) mapaddr + (EDT_REMOTE_DATA & 0xff) ;
03947 }
03948 pcd_pio_intfc_write(edt_p, PCD_DIRB, 0xcc);
03949 pcd_pio_flush_fifo(edt_p) ;
03950 }
03951
03952 void
03953 pcd_pio_intfc_write(EdtDev *edt_p, u_int desc, u_char val)
03954 {
03955 int dmy ;
03956
03957 if (edt_p->reg_intfc_off == NULL)
03958 return;
03959
03960 *edt_p->reg_intfc_off = desc & 0xff ;
03961 dmy = *edt_p->reg_intfc_off ;
03962
03963 *edt_p->reg_intfc_dat = val ;
03964 dmy = *edt_p->reg_intfc_dat ;
03965 }
03966
03967 u_char
03968 pcd_pio_intfc_read(EdtDev *edt_p, u_int desc)
03969 {
03970 int dmy ;
03971
03972 if (edt_p->reg_intfc_off == NULL)
03973 return 0;
03974
03975 *edt_p->reg_intfc_off = desc & 0xff ;
03976 dmy = *edt_p->reg_intfc_off ;
03977
03978 return(*edt_p->reg_intfc_dat) ;
03979 }
03980
03981
03982
03983 void
03984 pcd_pio_set_direction(EdtDev *edt_p, int direction)
03985 {
03986 u_char cmd = pcd_pio_intfc_read(edt_p, PCD_CMD) ;
03987
03988 if (direction)
03989 {
03990 pcd_pio_intfc_write(edt_p, PCD_DIRA, 0x0f);
03991
03992 cmd &= ~PCD_DIR;
03993 cmd |= PCD_ENABLE;
03994
03995 }
03996 else
03997 {
03998 pcd_pio_intfc_write(edt_p, PCD_DIRA, 0xf0);
03999
04000 cmd |= PCD_DIR | PCD_ENABLE ;
04001 }
04002
04003 pcd_pio_intfc_write(edt_p, PCD_CMD, cmd);
04004 }
04005
04006 static void
04007 pcd_pio_quick_flush(EdtDev *edt_p)
04008 {
04009 u_char tmpc ;
04010
04011 if (edt_p->reg_fifo_ctl == NULL)
04012 return;
04013
04014 tmpc = *edt_p->reg_fifo_ctl ;
04015 tmpc &= ~1 ;
04016 *edt_p->reg_fifo_ctl = tmpc ;
04017 tmpc |= 1 ;
04018 *edt_p->reg_fifo_ctl = tmpc ;
04019 }
04020
04021
04022 void
04023 pcd_pio_flush_fifo(EdtDev * edt_p)
04024 {
04025 unsigned char cmd;
04026 unsigned int dmy;
04027
04028 if (edt_p->reg_intfc_off == NULL)
04029 return;
04030
04031
04032 *edt_p->reg_intfc_off = PCD_CMD & 0xff ;
04033 dmy = *edt_p->reg_intfc_off ;
04034 cmd = *edt_p->reg_intfc_dat ;
04035 cmd &= ~PCD_ENABLE;
04036 *edt_p->reg_intfc_dat = cmd ;
04037 dmy = *edt_p->reg_intfc_dat ;
04038 cmd |= PCD_ENABLE;
04039 *edt_p->reg_intfc_dat = cmd ;
04040 dmy = *edt_p->reg_intfc_dat ;
04041
04042 pcd_pio_quick_flush(edt_p) ;
04043
04044 }
04045
04046 int
04047 pcd_pio_write(EdtDev *edt_p, u_char *buf, int size)
04048 {
04049 int i;
04050 u_int *tmpl = (u_int *) buf ;
04051
04052 if (edt_p->reg_fifo_io == NULL)
04053 return -1;
04054
04055 pcd_pio_set_direction(edt_p, EDT_WRITE) ;
04056
04057 for (i = 0 ; i < size / 4 ; i++)
04058 *edt_p->reg_fifo_io = *tmpl++ ;
04059
04060 return(size);
04061 }
04062
04063 int
04064 pcd_pio_read(EdtDev *edt_p, u_char *buf, int size)
04065 {
04066 u_int *tmpl = (u_int *) buf ;
04067 int wordcnt = 0 ;
04068 int words_avail ;
04069 int words_requested = size / 4 ;
04070
04071 if (edt_p->reg_fifo_io == NULL)
04072 return -1;
04073
04074 pcd_pio_set_direction(edt_p, EDT_READ) ;
04075
04076 while (wordcnt < words_requested)
04077 {
04078 words_avail = *edt_p->reg_fifo_cnt & 0xf ;
04079
04080 while (words_avail && wordcnt < words_requested)
04081 {
04082 -- words_avail ;
04083 *tmpl = *edt_p->reg_fifo_io ;
04084 wordcnt++ ;
04085 tmpl++ ;
04086 }
04087
04088 if ((wordcnt == words_requested - 1) && (*edt_p->reg_fifo_cnt & 0x1f) == 0x10)
04089 {
04090 *tmpl = *edt_p->reg_fifo_io ;
04091 wordcnt++ ;
04092 }
04093 }
04094
04095 pcd_pio_quick_flush(edt_p);
04096
04097 return(size) ;
04098 }
04099
04100 void
04101 pcd_set_abortdma_onintr(EdtDev *edt_p, int flag)
04102 {
04103 if (flag == 0)
04104 {
04105 edt_reg_and(edt_p, PCD_CMD, ~PCD_STAT_INT_1) ;
04106 }
04107
04108 edt_ioctl(edt_p, EDTS_ABORTDMA_ONINTR, &flag) ;
04109
04110 if (flag)
04111 {
04112 edt_reg_or(edt_p, PCD_CMD, PCD_STAT_INT_1 | PCD_ENABLE) ;
04113 edt_reg_or(edt_p, PCD_STAT_POLARITY, PCD_STAT_INT_ENA) ;
04114 edt_set_remote_intr(edt_p, TRUE);
04115 }
04116 }
04117
04118 #endif
04119
04120
04121
04130 void
04131 edt_flush_fifo(EdtDev * edt_p)
04132 {
04133 uint_t tmp;
04134 unsigned char cmd;
04135 unsigned char cfg;
04136 unsigned int dmy;
04137
04138 edt_msg(EDTDEBUG, "edt_flush_fifo\n") ;
04139
04140 tmp = edt_reg_read(edt_p, EDT_DMA_INTCFG);
04141 tmp &= (~EDT_RFIFO_ENB);
04142 edt_reg_write(edt_p, EDT_DMA_INTCFG, tmp);
04143 dmy = edt_reg_read(edt_p, EDT_DMA_INTCFG);
04144
04145 if (edt_is_pcd(edt_p) || edt_p->devid == PDVAERO_ID)
04146 {
04147
04148 cmd = edt_intfc_read(edt_p, PCD_CMD);
04149 cmd &= ~PCD_ENABLE;
04150 edt_intfc_write(edt_p, PCD_CMD, cmd);
04151 dmy = edt_intfc_read(edt_p, PCD_CMD);
04152 cmd |= PCD_ENABLE;
04153 edt_intfc_write(edt_p, PCD_CMD, cmd);
04154 dmy = edt_intfc_read(edt_p, PCD_CMD);
04155 }
04156 else if (edt_is_pdv(edt_p))
04157 {
04158 int cont = edt_reg_read(edt_p, PDV_DATA_PATH) & PDV_CONTINUOUS;
04159
04160 cfg = edt_intfc_read(edt_p, PDV_CFG);
04161 cfg &= ~PDV_FIFO_RESET;
04162 edt_intfc_write(edt_p, PDV_CFG, (u_char) (cfg | PDV_FIFO_RESET));
04163 edt_intfc_write(edt_p, PDV_CMD, PDV_RESET_INTFC);
04164 edt_intfc_write(edt_p, PDV_CFG, cfg);
04165
04166 if (cont)
04167 edt_reg_or(edt_p,PDV_DATA_PATH, PDV_CONTINUOUS);
04168 }
04169
04170
04171
04172 tmp |= (EDT_RFIFO_ENB);
04173 edt_reg_write(edt_p, EDT_DMA_INTCFG, tmp);
04174 dmy = edt_reg_read(edt_p, EDT_DMA_INTCFG);
04175
04176 }
04177
04195 uint_t
04196 edt_get_bytecount(EdtDev * edt_p)
04197 {
04198 uint_t tmp;
04199
04200 if (edt_ioctl(edt_p, EDTG_BYTECOUNT, &tmp) < 0)
04201 edt_msg_perror(EDTFATAL, "edt_ioctl(EDTG_BYTECOUNT)");
04202
04203 return (tmp);
04204 }
04205
04215 uint_t
04216 edt_get_timeout_count(EdtDev * edt_p)
04217 {
04218 uint_t tmp;
04219
04220 if (edt_ioctl(edt_p, EDTG_TIMECOUNT, &tmp) < 0)
04221 edt_msg_perror(EDTFATAL, "edt_ioctl(EDTG_TIMECOUNT)");
04222
04223 return (tmp);
04224 }
04229 unsigned short
04230 edt_get_direction(EdtDev * edt_p)
04231 {
04232 unsigned short dirreg;
04233
04234
04235 dirreg = edt_intfc_read(edt_p, PCD_DIRA);
04236 dirreg |= edt_intfc_read(edt_p, PCD_DIRB) << 8;
04237 return (dirreg);
04238 }
04239
04250 int
04251 edt_cancel_current_dma(EdtDev * edt_p)
04252 {
04253 unsigned int finish_current = 0;
04254
04255 return edt_ioctl(edt_p, EDTS_STOPBUF, &finish_current);
04256 }
04257
04258
04270 void
04271 edt_set_direction(EdtDev * edt_p, int direction)
04272 {
04273
04274 u_int tmp = edt_reg_read(edt_p, EDT_DMA_INTCFG);
04275
04276 if (edt_is_pcd(edt_p) || edt_p->devid == PDVAERO_ID)
04277 {
04278 edt_ioctl(edt_p, EDTS_DIRECTION, &direction);
04279 }
04280
04281 tmp |= (EDT_RFIFO_ENB);
04282 edt_reg_write(edt_p, EDT_DMA_INTCFG, tmp);
04283
04284 edt_p->last_direction = (direction) ? 2: 1;
04285
04286 }
04287
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297
04298
04299 #ifndef TRUE
04300 #define TRUE 1
04301 #endif
04302 #ifndef FALSE
04303 #define FALSE 0
04304 #endif
04305
04306
04316 int
04317 edt_ioctl(EdtDev * edt_p, int code, void *arg)
04318 {
04319 int get, set;
04320 int size;
04321 edt_ioctl_struct eis;
04322 #ifdef __APPLE__
04323 int ret ;
04324 #endif
04325
04326 #if 0
04327 edt_msg(EDTDEBUG, "edt_ioctl(%04x, %04x)\n", code, arg);
04328 #endif
04329
04330 if (edt_p->devid == DMY_ID)
04331 return (0);
04332 memset(&eis,0, sizeof(eis));
04333 eis.device = edt_p->fd;
04334 eis.controlCode = EIO_DECODE_ACTION(code);
04335 size = EIO_DECODE_SIZE(code);
04336 set = EIO_DECODE_SET(code);
04337 get = EIO_DECODE_GET(code);
04338 eis.inSize = 0;
04339 eis.inBuffer = NULL;
04340 eis.outSize = 0;
04341 eis.outBuffer = NULL;
04342 eis.bytesReturned = 0 ;
04343 #ifdef __APPLE__
04344 eis.channel = edt_p->channel_no ;
04345 eis.unit = edt_p->unit_no ;
04346 #endif
04347
04348
04349 if (set)
04350 {
04351 eis.inSize = size;
04352 eis.inBuffer = arg;
04353 }
04354
04355 if (get)
04356 {
04357 eis.outSize = size;
04358 eis.outBuffer = arg;
04359 }
04360
04361
04362 #ifdef _NT_
04363
04364 if (!DeviceIoControl(
04365 (HANDLE) edt_p->fd,
04366 EDT_MAKE_IOCTL(EDT_DEVICE_TYPE, eis.controlCode),
04367 eis.inBuffer,
04368 eis.inSize,
04369 eis.outBuffer,
04370 eis.outSize,
04371 (LPDWORD)&eis.bytesReturned,
04372 NULL))
04373 {
04374 return -1;
04375 }
04376 return 0;
04377
04378 #else
04379 #ifdef VXWORKS
04380 return ioctl(edt_p->fd, EDT_NT_IOCTL, (int)&eis);
04381 #else
04382 #if defined(__APPLE__)
04383
04384 eis.device = edt_p->channel_no ;
04385 ret = edt_mac_ioctl((u_int)edt_p->fd, EDT_NT_IOCTL, &eis) ;
04386 return(ret);
04387 #else
04388 return ioctl(edt_p->fd, EDT_NT_IOCTL, &eis);
04389 #endif
04390 #endif
04391 #endif
04392
04393 }
04394
04395 int
04396 edt_ioctl_nt(EdtDev * edt_p, int controlCode, void *inBuffer, int inSize,
04397 void *outBuffer, int outSize, int *bytesReturned)
04398 {
04399 int ret = 0;
04400
04401 edt_ioctl_struct eis;
04402
04403 eis.device = edt_p->fd;
04404 eis.controlCode = controlCode;
04405 eis.inBuffer = inBuffer;
04406 eis.inSize = inSize;
04407 eis.outBuffer = outBuffer;
04408 eis.outSize = outSize;
04409 eis.bytesReturned = 0;
04410 #ifdef __APPLE__
04411 eis.channel = edt_p->channel_no ;
04412 eis.unit = edt_p->unit_no ;
04413 #endif
04414
04415 #ifdef _NT_
04416
04417 if (inSize == 0 && outSize == 0)
04418 return ret ;
04419
04420 if (!DeviceIoControl(
04421 eis.device,
04422 eis.controlCode,
04423 eis.inBuffer,
04424 eis.inSize,
04425 eis.outBuffer,
04426 eis.outSize,
04427 (LPDWORD) &eis.bytesReturned,
04428 NULL))
04429 {
04430
04431 }
04432
04433 #else
04434 #ifdef VXWORKS
04435 if ((ret = ioctl(eis.device, EDT_NT_IOCTL, (int)&eis)) == 0)
04436 #else
04437 #if defined(__APPLE__)
04438 if ((ret = edt_mac_ioctl((u_int)edt_p->fd, EDT_NT_IOCTL, &eis)) == 0)
04439 #else
04440 if ((ret = ioctl(eis.device, EDT_NT_IOCTL, &eis)) == 0)
04441 #endif
04442 #endif
04443 #endif
04444 {
04445 *bytesReturned = eis.bytesReturned;
04446 }
04447 return ret;
04448 }
04449
04450
04451 uint_t
04452 edt_debugval(EdtDev * edt_p)
04453 {
04454 uint_t debugval = 0;
04455
04456 return (debugval);
04457 }
04458
04470 int
04471 edt_timeouts(EdtDev * edt_p)
04472 {
04473 int timeouts;
04474
04475 if (edt_p->devid == DMY_ID)
04476 return (0);
04477 edt_ioctl(edt_p, EDTG_TIMEOUTS, &timeouts);
04478 return (timeouts);
04479 }
04480
04481 int
04482 edt_set_dependent(EdtDev * edt_p, void *addr)
04483 {
04484 if (addr == NULL)
04485 return (-1);
04486 if (edt_p->devid == DMY_ID)
04487 {
04488 #ifdef _NT_
04489 edt_p->fd = CreateFile(
04490 edt_p->edt_devname,
04491 GENERIC_READ | GENERIC_WRITE,
04492 FILE_SHARE_READ | FILE_SHARE_WRITE,
04493 NULL,
04494 OPEN_ALWAYS,
04495 FILE_ATTRIBUTE_NORMAL,
04496 NULL);
04497 #else
04498 if (edt_p->fd)
04499 {
04500
04501 }
04502 else
04503 {
04504 edt_p->fd = open(edt_p->edt_devname, O_RDWR, 0666);
04505 }
04506 #endif
04507 edt_write(edt_p, addr, sizeof(Dependent));
04508 #ifdef _NT_
04509 CloseHandle(edt_p->fd);
04510 edt_p->fd = NULL;
04511 #else
04512 close(edt_p->fd);
04513 edt_p->fd = 0;
04514 #endif
04515 return (0);
04516 }
04517 return (edt_ioctl(edt_p, EDTS_DEPENDENT, addr));
04518 }
04519
04520 int
04521 edt_get_dependent(EdtDev * edt_p, void *addr)
04522 {
04523 if (addr == NULL)
04524 return (-1);
04525 if (edt_p->devid == DMY_ID)
04526 {
04527 int ret ;
04528 #ifdef _NT_
04529 edt_p->fd = CreateFile(
04530 edt_p->edt_devname,
04531 GENERIC_READ | GENERIC_WRITE,
04532 FILE_SHARE_READ | FILE_SHARE_WRITE,
04533 NULL,
04534 OPEN_ALWAYS,
04535 FILE_ATTRIBUTE_NORMAL,
04536 NULL);
04537 #else
04538 edt_p->fd = open(edt_p->edt_devname, O_RDWR, 0666);
04539 #endif
04540 ret = edt_read(edt_p, addr, sizeof(Dependent));
04541 #ifdef _NT_
04542 CloseHandle(edt_p->fd);
04543 edt_p->fd = NULL;
04544 #else
04545 close(edt_p->fd);
04546 edt_p->fd = 0;
04547 #endif
04548 if (ret != sizeof(Dependent))
04549 return (-1) ;
04550 return (0);
04551 }
04552 return (edt_ioctl(edt_p, EDTG_DEPENDENT, addr));
04553 }
04554
04555 int
04556 edt_dump_sglist( EdtDev * edt_p, int val)
04557 {
04558 return (edt_ioctl(edt_p, EDTS_DUMP_SGLIST, &val));
04559 }
04560
04561 int
04562 edt_set_debug(EdtDev * edt_p, int val)
04563 {
04564 return (edt_ioctl(edt_p, EDTS_DEBUG, &val));
04565 }
04566
04567 int
04568 edt_get_debug(EdtDev * edt_p)
04569 {
04570 int val;
04571
04572 edt_ioctl(edt_p, EDTG_DEBUG, &val);
04573 return (val);
04574 }
04575
04589 int
04590 edt_set_rtimeout(EdtDev * edt_p, int value)
04591 {
04592 edt_msg(EDTDEBUG, "edt_set_rtimeout(%d)\n", value);
04593 return edt_ioctl(edt_p, EDTS_RTIMEOUT, &value);
04594 }
04595
04611 int
04612 edt_set_wtimeout(EdtDev * edt_p, int value)
04613 {
04614 edt_msg(EDTDEBUG, "edt_set_wtimeout(%d)\n", value);
04615 return edt_ioctl(edt_p, EDTS_WTIMEOUT, &value);
04616 }
04617
04629 int
04630 edt_get_rtimeout(EdtDev * edt_p)
04631 {
04632 int value;
04633
04634 edt_ioctl(edt_p, EDTG_RTIMEOUT, &value);
04635 return (value);
04636 }
04637
04649 int
04650 edt_get_wtimeout(EdtDev * edt_p)
04651 {
04652 int value;
04653
04654 edt_ioctl(edt_p, EDTG_WTIMEOUT, &value);
04655 return (value);
04656 }
04657
04658 int
04659 edt_get_tracebuf(EdtDev * edt_p, u_int * addr)
04660 {
04661 if (addr == NULL)
04662 return (-1);
04663 return (edt_ioctl(edt_p, EDTG_TRACEBUF, addr));
04664 }
04665
04669 int
04670 edt_send_msg(EdtDev * edt_p, int unit, const char *msg, int size)
04671 {
04672 int dummy ;
04673 ser_buf ser ;
04674 ser.unit = unit ;
04675 ser.size = size ;
04676 ser.flags = EDT_SERIAL_SAVERESP ;
04677
04678 if (size > sizeof(ser.buf))
04679 {
04680 edt_msg(EDTFATAL, "Error writing %d bytes to serial buffer\n", size);
04681 size = sizeof(ser.buf);
04682 }
04683 memcpy(ser.buf,msg,size) ;
04684
04685 edt_ioctl_nt(edt_p, ES_SERIAL, &ser, size + EDT_SERBUF_OVRHD,
04686 NULL, 0, &dummy);
04687 return (0);
04688 }
04689
04690 int
04691 edt_get_msg_unit(EdtDev * edt_p, char *msgbuf, int maxsize, int unit)
04692 {
04693 ser_buf ser ;
04694 int bytes = 0;
04695 ser.unit = unit ;
04696 ser.size = maxsize ;
04697
04698 edt_ioctl_nt(edt_p, EG_SERIAL, &ser, EDT_SERBUF_OVRHD,
04699 msgbuf, maxsize, &bytes);
04700 if (bytes < maxsize)
04701 msgbuf[bytes] = '\0';
04702 return (bytes);
04703 }
04704
04718 int
04719 edt_get_msg(EdtDev * edt_p, char *msgbuf, int maxsize)
04720 {
04721 if (edt_is_dvcl(edt_p) || edt_is_dvfox(edt_p) || edt_p->devid == PDVAERO_ID)
04722 return(edt_get_msg_unit(edt_p, msgbuf, maxsize, edt_p->channel_no)) ;
04723 else return(edt_get_msg_unit(edt_p, msgbuf, maxsize, 0)) ;
04724 }
04725
04726
04727 int
04728 edt_set_statsig(EdtDev * edt_p, int event, int sig)
04729 {
04730 edt_buf buf;
04731
04732 buf.desc = event;
04733 buf.value = sig;
04734 return (edt_ioctl(edt_p, EDTS_EVENT_SIG, &buf));
04735 }
04736
04737 int
04738 edt_set_eodma_int(EdtDev * edt_p, int sig)
04739 {
04740 return (edt_ioctl(edt_p, EDTS_EODMA_SIG, &sig));
04741 }
04742
04743 int
04744 edt_set_autodir(EdtDev * edt_p, int val)
04745 {
04746 return (edt_ioctl(edt_p, EDTS_AUTODIR, &val));
04747 }
04748
04768 int
04769 edt_set_firstflush(EdtDev * edt_p, int flag)
04770 {
04771 return (edt_ioctl(edt_p, EDTS_FIRSTFLUSH, &flag));
04772 }
04773
04774
04798 int
04799 edt_get_firstflush(EdtDev * edt_p)
04800 {
04801
04802 int val;
04803
04804 edt_ioctl(edt_p, EDTG_FIRSTFLUSH, &val);
04805
04806 return val;
04807 }
04808
04809
04810 u_char
04811 edt_set_funct_bit(EdtDev * edt_p, u_char mask)
04812 {
04813 unsigned char funct;
04814
04815 funct = edt_reg_read(edt_p, PCD_FUNCT);
04816 funct |= mask;
04817 edt_reg_write(edt_p, PCD_FUNCT, funct);
04818 return (funct);
04819 }
04820
04821 u_char
04822 edt_clr_funct_bit(EdtDev * edt_p, u_char mask)
04823 {
04824 u_char funct;
04825
04826 funct = edt_reg_read(edt_p, PCD_FUNCT);
04827 funct &= ~mask;
04828 edt_reg_write(edt_p, PCD_FUNCT, funct);
04829 return (funct);
04830 }
04831
04832
04837 static void
04838 shft_av9110(EdtDev * edt_p, u_int data, u_int numbits)
04839 {
04840 int use_pcd_method;
04841
04842 if (ID_IS_PCD(edt_p->devid) || edt_p->devid == PDVAERO_ID)
04843 use_pcd_method = 1;
04844 else
04845 use_pcd_method = 0;
04846
04847 while (numbits)
04848 {
04849 if (use_pcd_method)
04850 {
04851 if (data & 0x1)
04852 edt_set_funct_bit(edt_p, EDT_FUNCT_DATA);
04853 else
04854 edt_clr_funct_bit(edt_p, EDT_FUNCT_DATA);
04855
04856 edt_set_funct_bit(edt_p, EDT_FUNCT_CLK);
04857 edt_clr_funct_bit(edt_p, EDT_FUNCT_CLK);
04858 }
04859 else
04860 {
04861 if (data & 0x1)
04862 edt_set_pllct_bit(edt_p, EDT_FUNCT_DATA);
04863 else
04864 edt_clr_pllct_bit(edt_p, EDT_FUNCT_DATA);
04865
04866 edt_set_pllct_bit(edt_p, EDT_FUNCT_CLK);
04867 edt_clr_pllct_bit(edt_p, EDT_FUNCT_CLK);
04868
04869 }
04870 data = data >> 1;
04871 numbits--;
04872 }
04873 }
04874
04875 u_char
04876 edt_set_pllct_bit(EdtDev * edt_p, u_char mask)
04877 {
04878 unsigned char pll_ct;
04879
04880 pll_ct = edt_reg_read(edt_p, PDV_PLL_CTL);
04881 pll_ct |= mask;
04882 edt_reg_write(edt_p, PDV_PLL_CTL, pll_ct);
04883 return (pll_ct);
04884 }
04885
04886 u_char
04887 edt_clr_pllct_bit(EdtDev * edt_p, u_char mask)
04888 {
04889 u_char pll_ct;
04890
04891 pll_ct = edt_reg_read(edt_p, PDV_PLL_CTL);
04892 pll_ct &= ~mask;
04893 edt_reg_write(edt_p, PDV_PLL_CTL, pll_ct);
04894 return (pll_ct);
04895 }
04896
04897 void
04898 edt_set_out_clk(EdtDev * edt_p, edt_pll * clk_data)
04899 {
04900 int use_pcd_method;
04901
04902 unsigned char opt_e = 0;
04903 u_int svfnct;
04904
04905 if (ID_IS_PCD(edt_p->devid) || edt_p->devid == PDVAERO_ID)
04906 use_pcd_method = 1;
04907 else
04908 use_pcd_method = 0;
04909
04910 switch (clk_data->h)
04911 {
04912 case 1:
04913 opt_e = EDT_FAST_DIV1;
04914 break;
04915
04916 case 3:
04917 opt_e = EDT_FAST_DIV3;
04918 break;
04919
04920 case 5:
04921 opt_e = EDT_FAST_DIV5;
04922 break;
04923
04924 case 7:
04925 opt_e = EDT_FAST_DIV7;
04926 break;
04927
04928 default:
04929 edt_msg(EDTDEBUG, "Illegal value %d for xilinx fast clk divide\n",
04930 clk_data->h);
04931 opt_e = EDT_FAST_DIV1;
04932 clk_data->h = 1;
04933 break;
04934 }
04935 opt_e |= ((clk_data->l - 1) << EDT_X_DIVN_SHFT);
04936
04937
04938 if (use_pcd_method)
04939 {
04940 edt_reg_write(edt_p, EDT_OUT_SCALE, opt_e);
04941 edt_reg_write(edt_p, EDT_REF_SCALE, clk_data->x - 1);
04942 svfnct = edt_reg_read(edt_p, PCD_FUNCT);
04943 edt_set_funct_bit(edt_p, EDT_FUNCT_SELAV);
04944 edt_clr_funct_bit(edt_p, EDT_FUNCT_CLK);
04945
04946
04947 }
04948 else
04949 {
04950 edt_reg_write(edt_p, PDV_OUT_SCALE, opt_e);
04951 edt_reg_write(edt_p, PDV_REF_SCALE, clk_data->x - 1);
04952 svfnct = edt_reg_read(edt_p, PDV_PLL_CTL);
04953 edt_set_pllct_bit(edt_p, EDT_FUNCT_SELAV);
04954 edt_clr_pllct_bit(edt_p, EDT_FUNCT_CLK);
04955
04956 }
04957
04958
04959 svfnct &= ~EDT_FUNCT_SELAV;
04960
04961
04962 shft_av9110(edt_p, clk_data->n, 7);
04963 shft_av9110(edt_p, clk_data->m, 7);
04964
04965 if (clk_data->v == 1)
04966 shft_av9110(edt_p, 0, 1);
04967 else
04968 shft_av9110(edt_p, 1, 1);
04969
04970 switch (clk_data->r)
04971 {
04972 case 1:
04973 shft_av9110(edt_p, 0x170, 9);
04974 break;
04975
04976 case 2:
04977 shft_av9110(edt_p, 0x174, 9);
04978 break;
04979
04980 case 4:
04981 shft_av9110(edt_p, 0x178, 9);
04982 break;
04983
04984 case 8:
04985 shft_av9110(edt_p, 0x17c, 9);
04986 break;
04987
04988 default:
04989 edt_msg(EDTDEBUG, "illegal value %d for AV9110 aoutput divide\n",
04990 clk_data->r);
04991 shft_av9110(edt_p, 0x5c, 7);
04992 break;
04993 }
04994
04995
04996 if (use_pcd_method)
04997 edt_reg_write(edt_p, PCD_FUNCT, svfnct);
04998 else
04999 edt_reg_write(edt_p, PDV_PLL_CTL, svfnct);
05000
05001 }
05002
05003 u_int
05004 edt_set_sglist(EdtDev *edt_p,
05005 uint_t bufnum,
05006 uint_t *log_list,
05007 uint_t log_entrys)
05008 {
05009 int ret ;
05010 buf_args sg_args ;
05011 sg_args.index = bufnum ;
05012 sg_args.size = log_entrys ;
05013 #ifdef WIN32
05014 sg_args.addr = (uint64_t) (log_list);
05015 #else
05016 sg_args.addr = (uint64_t) ((unsigned long) log_list);
05017 #endif
05018 ret = edt_ioctl(edt_p, EDTS_SGLIST, &sg_args);
05019
05020 return ret;
05021 }
05022
05023 u_int
05024 edt_set_sgbuf(EdtDev * edt_p, u_int sgbuf, u_int bufsize, u_int bufdir, u_int verbose)
05025 {
05026 edt_set_buffer_size(edt_p, sgbuf, bufsize, bufdir) ;
05027 return 0;
05028 }
05029
05046 int
05047 edt_set_timeout_action(EdtDev * edt_p, u_int action)
05048
05049 {
05050
05051 if (!edt_p)
05052 {
05053 return -1;
05054
05055 }
05056
05057 edt_ioctl(edt_p, EDTS_TIMEOUT_ACTION, &action);
05058
05059 return 0;
05060 }
05061
05075 int
05076 edt_get_timeout_goodbits(EdtDev * edt_p)
05077
05078 {
05079
05080 u_int nGoodBits;
05081
05082 if (!edt_p)
05083 {
05084 return 0;
05085 }
05086
05087 edt_ioctl(edt_p, EDTG_TIMEOUT_GOODBITS, &nGoodBits);
05088
05089 return nGoodBits;
05090 }
05091
05105 int
05106 edt_get_goodbits(EdtDev * edt_p)
05107
05108 {
05109
05110 u_int nGoodBits;
05111
05112 if (!edt_p)
05113 {
05114 return 0;
05115 }
05116
05117 edt_ioctl(edt_p, EDTG_GOODBITS, &nGoodBits);
05118
05119 return nGoodBits;
05120 }
05121
05226 #ifdef _NT_
05227
05228 int
05229 edt_get_kernel_event(EdtDev *edt_p, int event_type)
05230
05231 {
05232 EdtEventHandler *p;
05233 char fullname[128];
05234 char *Name;
05235 char *edt_devname;
05236
05237 if (edt_p == NULL
05238 || (event_type < 0)
05239 || (event_type >= EDT_MAX_KERNEL_EVENTS)
05240 || ((Name = BaseEventNames[event_type]) == NULL)
05241 || ((p = &edt_p->event_funcs[event_type]) == NULL))
05242 {
05243
05244 edt_msg(EDTDEBUG, "Invalid argument to edt_get_kernel_event\n");
05245 return -1;
05246 }
05247
05248
05249 if (edt_p->devid == P11W_ID)
05250 edt_devname = "P11w";
05251 else if (edt_p->devid == P16D_ID)
05252 edt_devname = "P16d";
05253 else if (edt_is_pcd(edt_p))
05254 edt_devname = "Pcd";
05255 else if (edt_is_pdv(edt_p))
05256 edt_devname = "Pdv";
05257 else if (edt_is_1553(edt_p))
05258 edt_devname = "P53b";
05259 else
05260 {
05261 edt_devname = NULL;
05262 edt_msg(EDTDEBUG, "Unknown device type %d\n", edt_p->devid);
05263 return -1;
05264 }
05265
05266 sprintf(fullname, "%s%s%d%d", edt_devname, Name, edt_p->unit_no, edt_p->channel_no);
05267
05268 if ((p->wait_event =
05269 CreateEvent(NULL, FALSE, FALSE,fullname)) == NULL)
05270 {
05271 if ((p->wait_event =
05272 OpenEvent(SYNCHRONIZE, FALSE, fullname)) == NULL)
05273 {
05274
05275 edt_msg(EDTDEBUG, "Unable to open event %s\n", fullname);
05276 edt_msg_perror(EDTFATAL, "event") ;
05277
05278 return -1;
05279
05280 }
05281 else
05282 {
05283 ResetEvent(p->wait_event) ;
05284 return(0) ;
05285 }
05286
05287 }
05288 else
05289 {
05290 edt_buf argbuf ;
05291 argbuf.desc = event_type ;
05292 argbuf.value = (uint64_t)p->wait_event ;
05293 edt_ioctl(edt_p, EDTS_EVENT_HNDL, &argbuf);
05294 ResetEvent(p->wait_event) ;
05295 }
05296
05297 return 0;
05298
05299 }
05300
05301
05302
05303
05304
05305 static
05306 void
05307 edt_clear_event_func(EdtEventHandler * p)
05308
05309 {
05310 if (p->wait_thread)
05311 CloseHandle(p->wait_thread);
05312 if (p->wait_event)
05313 CloseHandle(p->wait_event);
05314 if (p->closing_event)
05315 CloseHandle(p->closing_event);
05316
05317 memset(p, 0, sizeof(*p));
05318
05319 }
05320
05321
05322
05323
05324
05325 static u_int WINAPI
05326 edt_wait_event_thread(void *pObj)
05327 {
05328 EdtEventHandler *p = (EdtEventHandler *) pObj;
05329 int rc = WAIT_OBJECT_0;
05330 HANDLE events[2];
05331 u_int tmp;
05332
05333
05334 if (p)
05335 {
05336 events[0] = p->wait_event;
05337 events[1] = p->closing_event;
05338
05339 while (p->active)
05340 {
05341
05342 #ifndef NEW_WAY
05343 rc = WaitForMultipleObjects(2, events, FALSE, INFINITE);
05344 #else
05345
05346 edt_ioctl(p->owner, EDTS_WAIT_EVENT, &p->event_type);
05347 #endif
05348
05349 if (p->active && rc == WAIT_OBJECT_0)
05350 {
05351 edt_ioctl(p->owner, EDTS_CLR_EVENT, &p->event_type);
05352
05353 if (p->callback)
05354 p->callback(p->data);
05355
05356 }
05357
05358 if (p->continuous == 0)
05359 {
05360 edt_ioctl(p->owner, EDTS_DEL_EVENT_FUNC, &p->event_type);
05361
05362
05363 tmp = p->thrdid;
05364
05365 edt_clear_event_func(p);
05366 p->thrdid = tmp;
05367
05368 break;
05369 }
05370 }
05371 }
05372 return 0;
05373 }
05374
05375
05376
05377
05378
05379
05380
05381 int
05382 edt_set_event_func(EdtDev * edt_p, int event_type, EdtEventFunc func, void *data,
05383 int continuous)
05384 {
05385 EdtEventHandler *p;
05386 char *Name;
05387 HANDLE event;
05388
05389 edt_msg(EDTDEBUG, "edt_set_event_func(type %d cont %d)\n", event_type, continuous);
05390
05391 if (edt_p == NULL || (func == NULL)
05392 || (event_type < 0)
05393 || (event_type >= EDT_MAX_KERNEL_EVENTS)
05394 || ((Name = BaseEventNames[event_type]) == NULL)
05395 || ((p = &edt_p->event_funcs[event_type]) == NULL))
05396 {
05397
05398 return -1;
05399 }
05400
05401
05402 if (p->callback)
05403 {
05404
05405
05406
05407
05408 if (p->callback == func && p->data == data)
05409 return 0;
05410 else
05411 return -1;
05412 }
05413
05414
05415 p->callback = func;
05416
05417 p->data = data;
05418
05419 p->owner = edt_p;
05420 p->active = TRUE;
05421 p->event_type = event_type;
05422 p->continuous = continuous;
05423
05424
05425
05426
05427
05428
05429
05430 edt_get_kernel_event(edt_p, event_type) ;
05431 event = edt_p->event_funcs[event_type].wait_event;
05432
05433 if (event == NULL)
05434 {
05435 edt_clear_event_func(p);
05436 return -1;
05437
05438 }
05439
05440 if ((p->closing_event = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)
05441 {
05442 edt_clear_event_func(p);
05443 return -1;
05444 }
05445 #ifdef __APPLE__
05446 if ((p->wait_thread = (mac_thread_t)
05447 _beginthreadex(NULL, 0, edt_wait_event_thread, p, CREATE_SUSPENDED,
05448 &p->thrdid)) == NULL)
05449 #else
05450 if ((p->wait_thread = (thread_t)
05451 _beginthreadex(NULL, 0, edt_wait_event_thread, p, CREATE_SUSPENDED,
05452 &p->thrdid)) == NULL)
05453 #endif
05454 {
05455 edt_clear_event_func(p);
05456 return -1;
05457 }
05458
05459
05460
05461
05462
05463
05464
05465
05466
05467
05468 event_type |= ((continuous << EDT_EVENT_MODE_SHFT) & EDT_EVENT_MODE_MASK) ;
05469 edt_ioctl(edt_p, EDTS_ADD_EVENT_FUNC, &event_type);
05470 event_type &= ~EDT_EVENT_MODE_MASK ;
05471
05472 ResumeThread(p->wait_thread);
05473
05474
05475
05476 return 0;
05477 }
05478
05479 int
05480 edt_remove_event_func(EdtDev * edt_p, int event_type)
05481
05482 {
05483 EdtEventHandler *p;
05484
05485 if (edt_p == NULL || event_type < 0 || event_type >= EDT_MAX_KERNEL_EVENTS)
05486 {
05487
05488 return -1;
05489 }
05490
05491 p = &edt_p->event_funcs[event_type];
05492
05493
05494
05495
05496
05497 if (p->wait_thread && p->wait_event)
05498 {
05499 p->active = FALSE;
05500
05501 SetEvent(p->closing_event);
05502
05503 edt_ioctl(edt_p, EDTS_DEL_EVENT_FUNC, &event_type);
05504
05505 WaitForSingleObject(p->wait_thread, INFINITE);
05506
05507 edt_clear_event_func(p);
05508
05509 }else
05510 edt_clear_event_func(p);
05511
05512 return 0;
05513 }
05514
05515 #elif defined(__sun)
05516
05517
05518
05519
05520
05521
05522
05523 int
05524 edt_set_event_func(EdtDev * edt_p, int event_type, EdtEventFunc f, void *data,
05525 int continuous)
05526 {
05527 EdtEventHandler *p;
05528 char fullname[128];
05529 char *Name;
05530
05531
05532 if (edt_p == NULL || (f == NULL)
05533 || (event_type < 0)
05534 || (event_type >= EDT_MAX_KERNEL_EVENTS)
05535 || ((Name = BaseEventNames[event_type]) == NULL)
05536 || ((p = &edt_p->event_funcs[event_type]) == NULL))
05537 {
05538
05539 return -1;
05540 }
05541
05542 if (p->active && p->callback)
05543 {
05544
05545 edt_remove_event_func(edt_p, event_type);
05546 }
05547
05548
05549
05550
05551 else if (p->thrdid)
05552 thr_join(p->thrdid, NULL, NULL);
05553
05554
05555 p->callback = f;
05556
05557 p->data = data;
05558
05559 p->owner = edt_p;
05560 p->active = TRUE;
05561 p->event_type = event_type;
05562 p->continuous = continuous;
05563
05564 sema_init(&p->sema_thread, 0, USYNC_PROCESS, NULL);
05565
05566
05567
05568
05569
05570
05571
05572
05573
05574
05575 event_type |= ((continuous << EDT_EVENT_MODE_SHFT) & EDT_EVENT_MODE_MASK) ;
05576 edt_ioctl(edt_p, EDTS_ADD_EVENT_FUNC, &event_type);
05577 event_type &= ~EDT_EVENT_MODE_MASK ;
05578
05579
05580
05581 sprintf(fullname, "%s%d%d", Name, edt_p->unit_no, edt_p->channel_no);
05582 if (thr_create(NULL, 0, edt_wait_event_thread, (void *) p,
05583 THR_NEW_LWP | THR_BOUND, &p->thrdid))
05584 {
05585 edt_msg_perror(EDTFATAL, "edt_set_event_func: thr_create");
05586 edt_msg(EDTWARN, "Unable to create eventthread %s\n", fullname);
05587 edt_msg(EDTWARN, "thr_create: use \"-lthread\" compile option\n", stderr);
05588 return -1;
05589 }
05590
05591 sema_wait(&p->sema_thread);
05592 thr_yield();
05593
05594 return 0;
05595 }
05596
05597
05598
05599
05600
05601 static
05602 void
05603 edt_clear_event_func(EdtEventHandler * p)
05604
05605 {
05606
05607 memset(p, 0, sizeof(*p));
05608 }
05609
05610
05611
05612
05613
05614
05615 static void *
05616 edt_wait_event_thread(void *pObj)
05617
05618 {
05619 EdtEventHandler *p = (EdtEventHandler *) pObj;
05620 #ifdef __APPLE__
05621 mac_thread_t;
05622 #else
05623 thread_t tmp;
05624 #endif
05625 int ret;
05626
05627 #ifdef __sun
05628 if (p->owner->use_RT_for_event_func)
05629 edt_set_RT(1) ;
05630
05631
05632 #endif
05633
05634 if (p)
05635 {
05636 while (p->active)
05637 {
05638 sema_post(&p->sema_thread);
05639 if (p->continuous == 0)
05640 edt_ioctl(p->owner, EDTS_WAIT_EVENT_ONCE, &p->event_type);
05641 else
05642 edt_ioctl(p->owner, EDTS_WAIT_EVENT, &p->event_type);
05643
05644 if (p->active && p->callback)
05645 p->callback(p->data);
05646
05647 if (p->continuous == 0)
05648 {
05649 edt_ioctl(p->owner, EDTS_DEL_EVENT_FUNC, &p->event_type);
05650
05651
05652 tmp = p->thrdid;
05653 edt_clear_event_func(p);
05654 p->thrdid = tmp;
05655
05656 break;
05657 }
05658 }
05659 }
05660
05661 thr_exit(NULL);
05662
05663 return pObj;
05664 }
05665
05666
05667
05668
05669
05670 int
05671 edt_remove_event_func(EdtDev * edt_p, int event_type)
05672 {
05673 EdtEventHandler *p;
05674
05675 if (edt_p == NULL || event_type < 0 || event_type >= EDT_MAX_KERNEL_EVENTS)
05676 {
05677
05678 return -1;
05679 }
05680
05681 p = &edt_p->event_funcs[event_type];
05682
05683
05684
05685
05686
05687 if (p->active)
05688 {
05689 p->active = FALSE;
05690
05691 edt_ioctl(edt_p, EDTS_DEL_EVENT_FUNC, &event_type);
05692
05693 thr_join(p->thrdid, NULL, NULL);
05694
05695 edt_clear_event_func(p);
05696 }
05697
05698 return 0;
05699 }
05700 #elif defined(sgi) || defined(__linux__) || defined(__APPLE__)
05701
05702 #ifndef NO_PTHREAD
05703
05704 #include <pthread.h>
05705
05706
05707
05708
05709
05710
05711
05712 int
05713 edt_set_event_func(EdtDev * edt_p, int event_type, EdtEventFunc f, void *data,
05714 int continuous)
05715 {
05716 EdtEventHandler *p;
05717 char fullname[128];
05718 char *Name;
05719
05720
05721 if (edt_p == NULL || (f == NULL)
05722 || (event_type < 0)
05723 || (event_type >= EDT_MAX_KERNEL_EVENTS)
05724 || ((Name = BaseEventNames[event_type]) == NULL)
05725 || ((p = &edt_p->event_funcs[event_type]) == NULL))
05726 {
05727
05728 return -1;
05729 }
05730
05731 if (p->active && p->callback)
05732 {
05733
05734 edt_remove_event_func(edt_p, event_type);
05735 }
05736
05737
05738
05739
05740 else if (p->thrdid)
05741 pthread_join(p->thrdid, NULL);
05742
05743
05744 p->callback = f;
05745
05746 p->data = data;
05747
05748 p->owner = edt_p;
05749 p->active = TRUE;
05750 p->event_type = event_type;
05751 p->continuous = continuous;
05752
05753
05754
05755
05756
05757
05758
05759
05760
05761
05762
05763
05764
05765 event_type |= ((continuous << EDT_EVENT_MODE_SHFT) & EDT_EVENT_MODE_MASK) ;
05766 edt_ioctl(edt_p, EDTS_ADD_EVENT_FUNC, &event_type);
05767 event_type &= ~EDT_EVENT_MODE_MASK ;
05768
05769
05770
05771 sprintf(fullname, "%s%d%d", Name, edt_p->unit_no, edt_p->channel_no);
05772 if (pthread_create(&p->thrdid, 0, edt_wait_event_thread, (void *) p)
05773 != 0)
05774 {
05775 edt_msg_perror(EDTFATAL, "edt_set_event_func: thr_create");
05776 edt_msg(EDTWARN, "Unable to create eventthread %s\n", fullname);
05777 edt_msg(EDTWARN, "thr_create: use \"-lthread\" compile option\n", stderr);
05778 return -1;
05779 }
05780
05781
05782
05783
05784 return 0;
05785 }
05786
05787
05788
05789
05790
05791 static
05792 void
05793 edt_clear_event_func(EdtEventHandler * p)
05794
05795 {
05796
05797 memset(p, 0, sizeof(*p));
05798 }
05799
05800
05801
05802
05803
05804
05805 static void *
05806 edt_wait_event_thread(void *pObj)
05807
05808 {
05809 EdtEventHandler *p = (EdtEventHandler *) pObj;
05810 pthread_t tmp;
05811
05812 if (p)
05813 {
05814 while (p->active)
05815 {
05816
05817 if (p->continuous == 0)
05818 edt_ioctl(p->owner, EDTS_WAIT_EVENT_ONCE, &p->event_type);
05819 else
05820 edt_ioctl(p->owner, EDTS_WAIT_EVENT, &p->event_type);
05821
05822 if (p->active && p->callback)
05823 p->callback(p->data);
05824
05825 if (p->continuous == 0)
05826 {
05827 edt_ioctl(p->owner, EDTS_DEL_EVENT_FUNC, &p->event_type);
05828
05829
05830 tmp = p->thrdid;
05831 edt_clear_event_func(p);
05832 p->thrdid = tmp;
05833
05834 break;
05835 }
05836 }
05837 }
05838
05839 pthread_exit(NULL);
05840
05841 return pObj;
05842 }
05843
05844
05845
05846
05847
05848 int
05849 edt_remove_event_func(EdtDev * edt_p, int event_type)
05850 {
05851 EdtEventHandler *p;
05852
05853 if (edt_p == NULL || event_type < 0 || event_type >= EDT_MAX_KERNEL_EVENTS)
05854 {
05855
05856 return -1;
05857 }
05858
05859 p = &edt_p->event_funcs[event_type];
05860
05861
05862
05863
05864
05865 if (p->active)
05866 {
05867 p->active = FALSE;
05868
05869 edt_ioctl(edt_p, EDTS_DEL_EVENT_FUNC, &event_type);
05870
05871 pthread_join(p->thrdid, NULL);
05872
05873 edt_clear_event_func(p);
05874 }
05875
05876 return 0;
05877 }
05878 #endif
05879
05880 #elif defined(_AIX) || defined(__hpux)
05881
05882
05883
05884
05885
05886
05887
05888 int
05889 edt_set_event_func(EdtDev * edt_p, int event_type, EdtEventFunc f, void *data,
05890 int continuous)
05891 {
05892 return -1;
05893 }
05894
05895
05896
05897
05898
05899 static
05900 void
05901 edt_clear_event_func(EdtEventHandler * p)
05902
05903 {
05904
05905 }
05906
05907
05908
05909
05910
05911
05912 static void *
05913 edt_wait_event_thread(void *pObj)
05914
05915 {
05916 return NULL;
05917 }
05918
05919
05920
05921
05922
05923 int
05924 edt_remove_event_func(EdtDev * edt_p, int event_type)
05925 {
05926 return -1;
05927 }
05928
05929 #else
05930
05931 int
05932 edt_remove_event_func(EdtDev * edt_p, int event_type)
05933 {
05934 return -1;
05935 }
05936
05937 #endif
05938
05939 int
05940 edt_enable_event(EdtDev * edt_p, int event_type)
05941 {
05942 edt_msg(EDTDEBUG, "edt_enable_event(type %d)\n", event_type) ;
05943
05944 if (edt_p == NULL
05945 || (event_type < 0)
05946 || (event_type >= EDT_MAX_KERNEL_EVENTS))
05947 {
05948
05949 return -1;
05950 }
05951
05952 #ifdef _NT_
05953 edt_get_kernel_event(edt_p, event_type) ;
05954 #endif
05955
05956 edt_ioctl(edt_p, EDTS_ADD_EVENT_FUNC, &event_type);
05957
05958 return 0 ;
05959 }
05960
05961 int
05962 edt_wait_event(EdtDev * edt_p, int event_type, int timeoutval)
05963 {
05964 int ret = 0 ;
05965 edt_msg(EDTDEBUG, "edt_wait_event(type %d)\n", event_type) ;
05966 #ifdef _NT_
05967 {
05968 HANDLE event;
05969 int rc;
05970
05971 if (!edt_p->event_funcs[event_type].wait_event)
05972 {
05973 edt_get_kernel_event(edt_p, event_type);
05974 }
05975
05976 event = edt_p->event_funcs[event_type].wait_event;
05977
05978
05979
05980 if (timeoutval == 0)
05981 timeoutval = INFINITE;
05982
05983 rc = WaitForSingleObject(event, timeoutval);
05984
05985 if (rc == WAIT_TIMEOUT)
05986 {
05987
05988
05989
05990
05991 edt_do_timeout(edt_p);
05992
05993 ret = 1 ;
05994 }
05995 }
05996 #else
05997 edt_ioctl(edt_p, EDTS_WAIT_EVENT, &event_type);
05998 #endif
05999
06000 edt_msg(EDTDEBUG, "edt_wait_event(type %d)\n", event_type, ret) ;
06001
06002 return(ret) ;
06003 }
06004
06005
06010 int
06011 edt_reset_event_counter(EdtDev * edt_p, int event_type)
06012 {
06013 return edt_ioctl(edt_p, EDTS_RESET_EVENT_COUNTER, &event_type);
06014 }
06015
06016
06017
06029 int
06030 edt_stop_buffers(EdtDev * edt_p)
06031
06032 {
06033 unsigned int finish_current = 1;
06034
06035 edt_msg(EDTDEBUG, "edt_stop_buffers\n");
06036 edt_ioctl(edt_p, EDTS_STOPBUF, &finish_current);
06037 return 0;
06038 }
06039
06056 int
06057 edt_reset_ring_buffers(EdtDev * edt_p, uint_t bufnum)
06058
06059 {
06060 bufcnt_t curdone;
06061 int curBufIndex = -1;
06062
06063 curdone = edt_done_count(edt_p);
06064 edt_cancel_current_dma(edt_p);
06065 if (edt_p->ring_buffer_numbufs)
06066 {
06067 curBufIndex = curdone % edt_p->ring_buffer_numbufs;
06068 edt_set_buffer(edt_p, bufnum);
06069 }
06070 edt_msg(EDTDEBUG, "edt_reset_ring_buffers buf %d curdone %d curBufIndex %d\n",
06071 bufnum, curdone, curBufIndex);
06072 return 0;
06073 }
06074
06088 int
06089 edt_abort_dma(EdtDev * edt_p)
06090
06091 {
06092 edt_msg(EDTDEBUG, "edt_abort_dma\n");
06093 edt_reset_ring_buffers(edt_p, edt_done_count(edt_p));
06094 return 0;
06095 }
06096
06110 int
06111 edt_abort_current_dma(EdtDev * edt_p)
06112
06113 {
06114 edt_msg(EDTDEBUG, "edt_abort_current_dma\n");
06115 edt_reset_ring_buffers(edt_p, edt_done_count(edt_p) + 1);
06116 return 0;
06117 }
06118
06129 int
06130 edt_ring_buffer_overrun(EdtDev *edt_p)
06131
06132 {
06133 bufcnt_t dmacount;
06134
06135 dmacount = edt_done_count(edt_p);
06136
06137 if (dmacount >= edt_p->donecount + edt_p->ring_buffer_numbufs)
06138 return (1);
06139 else
06140 return (0);
06141 }
06142
06143
06144 #ifdef P16D
06145
06156 u_short
06157 p16d_get_command(EdtDev * edt_p)
06158 {
06159 return (edt_reg_read(edt_p, P16_COMMAND));
06160 }
06161
06173 void
06174 p16d_set_command(EdtDev * edt_p, u_short val)
06175 {
06176 edt_reg_write(edt_p, P16_COMMAND, val);
06177 }
06178
06189 u_short
06190 p16d_get_config(EdtDev * edt_p)
06191 {
06192 return (edt_reg_read(edt_p, P16_CONFIG));
06193 }
06194
06206 void
06207 p16d_set_config(EdtDev * edt_p, u_short val)
06208 {
06209 edt_reg_write(edt_p, P16_CONFIG, val);
06210 }
06211
06222 u_short
06223 p16d_get_stat(EdtDev * edt_p)
06224 {
06225 return (edt_reg_read(edt_p, P16_STATUS));
06226 }
06227
06228 #endif
06229
06230
06246 int
06247 edt_parse_unit_channel(const char *instr,
06248 char *dev,
06249 const char *default_dev,
06250 int *channel_ptr)
06251 {
06252 int unit = -1;
06253 int channel = -1;
06254 size_t last;
06255
06256 char retdev[256];
06257 char str[256];
06258
06259
06260 edt_msg(EDTDEBUG, "edt_parse_unit_channel %s dev %s default %s: ",
06261 instr, dev, default_dev);
06262
06263 if (default_dev)
06264 strcpy(retdev, default_dev);
06265 else
06266 strcpy(retdev, EDT_INTERFACE);
06267
06268 strcpy(str,instr);
06269
06270 if (strlen(str))
06271 {
06272 last = strlen(str)-1;
06273
06274
06275
06276 if (isdigit(str[last]))
06277 {
06278 while (last && isdigit(str[last]))
06279 {
06280 last--;
06281 }
06282
06283 if (!isdigit(str[last]))
06284 {
06285 last++;
06286 }
06287
06288 channel = atoi(str+last);
06289
06290 if (str[0] != '/' && str[0] != '\\')
06291 str[last] = 0;
06292
06293 if (last>0)
06294 last--;
06295
06296 if (last && str[last] == '_')
06297 {
06298
06299 last--;
06300
06301 if (isdigit(str[last]))
06302 {
06303 size_t enddigit = last;
06304 char checkstr[80];
06305
06306 while (last && isdigit(str[last]))
06307 {
06308 last--;
06309 }
06310
06311 if (!isdigit(str[last]))
06312 {
06313 last++;
06314 }
06315
06316 strncpy(checkstr,str+last,(enddigit - last)+1);
06317
06318 unit = atoi(checkstr);
06319
06320 if (str[0] != '/' && str[0] != '\\')
06321 str[last] = 0;
06322
06323 }
06324 else
06325 {
06326 unit = channel;
06327 channel = -1;
06328 }
06329 }
06330 else
06331 {
06332 unit = channel;
06333 channel = -1;
06334 }
06335
06336 }
06337 else
06338 unit = 0;
06339 }
06340 else
06341 unit = 0;
06342
06343 if (dev)
06344 {
06345 if (str[0])
06346 strcpy(dev, str);
06347 else
06348 strcpy(dev, retdev);
06349 }
06350
06351 if (channel_ptr && (channel != -1))
06352 *channel_ptr = channel;
06353
06354 return (unit);
06355 }
06356
06385 int
06386 edt_parse_unit(const char *str, char *dev, const char *default_dev)
06387 {
06388 int channel = 0;
06389
06390 return edt_parse_unit_channel(str,dev,default_dev, &channel);
06391
06392
06393 }
06394 int
06395 edt_serial_wait(EdtDev * edt_p, int msecs, int count)
06396 {
06397 edt_buf tmp;
06398 int ret;
06399
06400 tmp.desc = msecs;
06401 tmp.value = count;
06402 edt_ioctl(edt_p, EDTS_SERIALWAIT, &tmp);
06403 ret = (u_int) tmp.value;
06404
06405 edt_msg(EDTDEBUG, "edt_serial_wait(%d, %d) %d\n", msecs, count, ret);
06406 return (ret);
06407 }
06408
06442 int
06443 edt_ref_tmstamp(EdtDev *edt_p, u_int val)
06444
06445 {
06446 return edt_ioctl(edt_p,EDTS_REFTMSTAMP,&val);
06447
06448 }
06449
06465 uint_t
06466 edt_get_bufbytecount(EdtDev * edt_p, u_int *cur_buffer)
06467 {
06468 uint_t args[2] ;
06469
06470 if (edt_ioctl(edt_p, EDTG_BUFBYTECOUNT, &args) < 0)
06471 edt_msg_perror(EDTFATAL, "edt_ioctl(EDTG_BUFBYTECOUNT)");
06472
06473 if (cur_buffer)
06474 *cur_buffer = args[1] ;
06475 return (args[0]);
06476 }
06477
06478
06479 void
06480 edt_dmasync_fordev(EdtDev *edt, int bufnum, int offset, int bytecount)
06481 {
06482 u_int args[3] ;
06483
06484 args[0] = bufnum ;
06485 args[1] = offset ;
06486 args[2] = bytecount ;
06487
06488 edt_ioctl(edt, EDTS_DMASYNC_FORDEV, args) ;
06489 }
06490
06491 void
06492 edt_dmasync_forcpu(EdtDev *edt, int bufnum, int offset, int bytecount)
06493 {
06494 u_int args[3] ;
06495
06496 args[0] = bufnum ;
06497 args[1] = offset ;
06498 args[2] = bytecount ;
06499
06500 edt_ioctl(edt, EDTS_DMASYNC_FORCPU, args) ;
06501 }
06502
06503
06504 int
06505 edt_little_endian()
06506 {
06507 u_short test;
06508 u_char *byte_p;
06509
06510 byte_p = (u_char *) & test;
06511 *byte_p++ = 0x11;
06512 *byte_p = 0x22;
06513 if (test == 0x1122)
06514 {
06515 edt_msg(EDTDEBUG, "edt_endian: BIG (SPARC, PowerPC)\n");
06516 return (0);
06517 }
06518 else
06519 {
06520 edt_msg(EDTDEBUG, "edt_endian: LITTLE (X86, AMD, SPARCv9)\n");
06521 return (1);
06522 }
06523 }
06524
06525
06526
06527
06528
06529 int
06530 edt_set_buffer_physaddr(EdtDev * edt_p, uint_t index, uint64_t physaddr)
06531 {
06532
06533 buf_args sysargs;
06534
06535
06536 if (edt_p->ring_buffers[index])
06537 {
06538
06539 sysargs.index = index;
06540 sysargs.addr = physaddr;
06541 sysargs.size = 0;
06542
06543 return edt_ioctl(edt_p, EDTS_BUF, &sysargs);
06544
06545 }
06546 else
06547 {
06548
06549 edt_msg_perror(EDTFATAL,
06550 "edt_set_buffer_physaddr: Attempt to set physaddr on unallocated buffer\n");
06551
06552 return -1;
06553
06554 }
06555
06556 }
06557
06558
06591 int
06592 edt_set_buffer_size(EdtDev * edt_p, uint_t index, uint_t size, uint_t write_flag)
06593
06594 {
06595
06596 buf_args sysargs;
06597
06598 if (edt_p->ring_buffers[index])
06599 {
06600 if (size > (u_int) edt_p->rb_control[index].allocated_size)
06601 {
06602 edt_msg_perror(EDTFATAL, "edt_set_buffer_size: Attempt to set size greater than allocated\n");
06603 return -1;
06604 }
06605
06606 edt_p->rb_control[index].size = size;
06607 sysargs.index = index;
06608 sysargs.writeflag = write_flag;
06609 sysargs.addr = 0;
06610 sysargs.size = size;
06611
06612 return edt_ioctl(edt_p, EDTS_BUF, &sysargs);
06613
06614 }
06615 else
06616 {
06617 edt_msg_perror(EDTFATAL, "edt_set_buffer_size: Attempt to set size on unallocated buffer\n");
06618
06619 return -1;
06620 }
06621 }
06622
06639 int
06640 edt_set_max_buffers(EdtDev *edt_p, int newmax)
06641
06642 {
06643 edt_msg(EDTDEBUG, "edt_set_max_buffers\n");
06644
06645 return
06646 edt_ioctl(edt_p, EDTS_MAX_BUFFERS, &newmax);
06647 }
06648
06662 int
06663 edt_get_max_buffers(EdtDev *edt_p)
06664
06665 {
06666 u_int val;
06667
06668 if (edt_p->devid == DMY_ID) val = MAX_DMA_BUFFERS ;
06669 else edt_ioctl(edt_p, EDTG_MAX_BUFFERS, &val);
06670
06671 return val;
06672
06673 }
06674
06675
06676 void
06677 edt_resume(EdtDev * edt_p)
06678 {
06679 u_int dmy ;
06680
06681 edt_msg(EDTDEBUG, "edt_resume\n") ;
06682 edt_ioctl(edt_p, EDTS_RESUME, &dmy);
06683 }
06684
06709 uint_t
06710 edt_get_todo(EdtDev * edt_p)
06711 {
06712 u_int todo ;
06713 if (edt_p->devid == DMY_ID)
06714 todo = dmy_started ;
06715 else
06716 edt_ioctl(edt_p, EDTG_TODO, &todo);
06717 edt_msg(EDTDEBUG, "edt_get_todo: %d\n",todo) ;
06718 return todo;
06719 }
06720
06721 uint_t
06722 edt_get_drivertype(EdtDev * edt_p)
06723 {
06724 u_int type ;
06725 edt_ioctl(edt_p, EDTG_DRIVER_TYPE, &type);
06726 edt_msg(EDTDEBUG, "edt_get_drivertype: %x\n",type) ;
06727 return type;
06728 }
06729
06730
06731 int
06732 edt_set_drivertype(EdtDev *edt_p, u_int type)
06733 {
06734 edt_msg(EDTDEBUG, "edt_set_drivertype\n");
06735 return edt_ioctl(edt_p, EDTS_DRIVER_TYPE, &type);
06736 }
06737
06761 int
06762 edt_get_reftime(EdtDev * edt_p, u_int * timep)
06763 {
06764
06765 u_int timevals[2];
06766
06767 edt_ioctl(edt_p, EDTG_REFTIME, &timevals[0]);
06768 edt_msg(EDTDEBUG, "%x %x ",
06769 timevals[0],
06770 timevals[1]) ;
06771 timep[0] = timevals[0];
06772 timep[1] = timevals[1];
06773 return (timevals[1]) ;
06774 }
06775
06776 void
06777 edt_set_timetype(EdtDev * edt_p, u_int type)
06778 {
06779 edt_ioctl(edt_p, EDTS_TIMETYPE, &type);
06780 }
06781
06782 void
06783 edt_set_abortintr(EdtDev * edt_p, u_int val)
06784 {
06785 edt_ioctl(edt_p, EDTS_ABORTINTR, &val);
06786 }
06787
06788
06789 caddr_t
06790 edt_mapmem(EdtDev *edt_p, u_int addr, int size)
06791 {
06792 caddr_t ret;
06793 #if defined(_NT_)
06794 edt_buf tmp;
06795
06796 tmp.value = size;
06797 tmp.desc = addr;
06798
06799 edt_ioctl(edt_p, EDTS_MAPMEM, &tmp);
06800
06801 ret = (caddr_t) tmp.value ;
06802 edt_msg(EDTDEBUG, "edt_mapmem(%x, %x) %x %x\n", addr, size, tmp.desc,tmp.value);
06803 return (ret);
06804
06805 #elif defined(__APPLE__)
06806
06807
06808
06809
06810 return (addr);
06811
06812
06813 #else
06814 ret = (caddr_t) mmap((caddr_t)0, size, PROT_READ|PROT_WRITE,
06815 MAP_SHARED, edt_p->fd, addr);
06816 if (ret == ((caddr_t)-1)) {
06817 perror("mmap call");
06818 return(0) ;
06819 }
06820 return(ret) ;
06821 #endif
06822 }
06823
06824 u_int edt_get_mappable_size(EdtDev *edt_p, int bar )
06825
06826 {
06827 u_int value = 0;
06828
06829 if (bar == 1)
06830 edt_ioctl(edt_p, EDTG_MEM2SIZE, &value);
06831 else
06832 edt_ioctl(edt_p, EDTG_MEMSIZE, &value);
06833
06834 return value;
06835
06836 }
06837
06838
06839 #ifdef __sun
06840
06846 static id_t
06847 schedinfo(char *name, short *maxpri)
06848 {
06849 pcinfo_t info;
06850 tsinfo_t *tsinfop;
06851 rtinfo_t *rtinfop;
06852
06853 (void) strcpy(info.pc_clname, name);
06854 if (priocntl(0L, 0L, PC_GETCID, (char *) &info) == -1L)
06855 {
06856 return (-1);
06857 }
06858 if (strcmp(name, "TS") == 0)
06859 {
06860 tsinfop = (struct tsinfo *) info.pc_clinfo;
06861 *maxpri = tsinfop->ts_maxupri;
06862 }
06863 else if (strcmp(name, "RT") == 0)
06864 {
06865 rtinfop = (struct rtinfo *) info.pc_clinfo;
06866 *maxpri = rtinfop->rt_maxpri;
06867 }
06868 else
06869 {
06870 return (-1);
06871 }
06872 return (info.pc_cid);
06873 }
06874
06879 void
06880 edt_set_RT(u_int pri)
06881 {
06882 pcparms_t pcparms;
06883 rtparms_t *rtparmsp;
06884 id_t rtID;
06885 short maxrtpri;
06886
06887
06888 if ((rtID = schedinfo("RT", &maxrtpri)) == -1)
06889 {
06890 edt_msg_perror(EDTFATAL, "schedinfo failed for RT");
06891 exit(2);
06892 }
06893
06894
06895 pcparms.pc_cid = rtID;
06896 rtparmsp = (struct rtparms *) pcparms.pc_clparms;
06897 rtparmsp->rt_pri = maxrtpri - (1 + pri) ;
06898 rtparmsp->rt_tqnsecs = RT_TQDEF;
06899
06900 if (priocntl(P_LWPID, P_MYID, PC_SETPARMS, (char *) &pcparms) == -1)
06901 {
06902 edt_msg_perror(EDTFATAL, "PC_SETPARMS failed");
06903 exit(3);
06904 }
06905 }
06906 #endif
06907
06908
06909 #ifdef PCD
06910
06911
06912
06913
06914
06915 #define XPLLBYP (0x1<<17)
06916 #define XPLLCLK (0x1<<18)
06917 #define XPLLDAT (0x1<<19)
06918 #define XPLLSTB (0x1<<20)
06919
06920 #define XC_X16 (0x00)
06921 #define XC_AVSEL (0x80)
06922
06923 #define XC_CCLK (0x01)
06924 #define XC_DIN (0x02)
06925 #define XC_PROG (0x04)
06926 #define XC_INITL (0x04)
06927 #define XC_DONE (0x08)
06928
06929
06930 static void
06931 sse_wpp(EdtDev *edt_p, int val)
06932 {
06933 unsigned char bits;
06934
06935 bits = edt_intfc_read(edt_p, PCD_FUNCT) & 0x08;
06936
06937 if (val & XC_DIN) bits |= 0x04;
06938 if (val & XC_PROG) bits |= 0x01;
06939 if (val & XC_AVSEL) bits |= 0x80;
06940
06941 edt_intfc_write(edt_p, PCD_FUNCT, bits);
06942
06943 if (val & XC_CCLK)
06944 {
06945 edt_intfc_write(edt_p, PCD_FUNCT, (unsigned char) (bits | 0x02));
06946 edt_intfc_write(edt_p, PCD_FUNCT, bits);
06947 }
06948
06949 edt_msg(EDTDEBUG, "sse_wpp(%02x) ", bits);
06950 }
06951
06952
06953 static int
06954 sse_spal(EdtDev * edt_p, int v)
06955 {
06956 edt_msleep(1);
06957 edt_intfc_write(edt_p, PCD_PAL0, (unsigned char) (v >> 0));
06958 edt_intfc_write(edt_p, PCD_PAL1, (unsigned char) (v >> 8));
06959 edt_intfc_write(edt_p, PCD_PAL2, (unsigned char) (v >> 16));
06960
06961 return (edt_intfc_read(edt_p, PCD_PAL3));
06962 }
06963
06964 static void
06965 sse_xosc(EdtDev * edt_p, int val)
06966 {
06967 int n, s;
06968 int gspv = edt_intfc_read(edt_p, PCD_PAL0)
06969 | edt_intfc_read(edt_p, PCD_PAL1) << 8
06970 | edt_intfc_read(edt_p, PCD_PAL2) << 16;
06971
06972 gspv = (gspv & ~XPLLBYP & ~XPLLCLK & ~XPLLDAT & ~XPLLSTB);
06973 sse_wpp(edt_p, 0);
06974
06975 edt_msleep(1);
06976
06977 for (n = 13; n >= 0; n--)
06978 {
06979 s = val & (0x1 << n);
06980
06981 if (s)
06982 {
06983 sse_spal(edt_p, gspv | XPLLDAT);
06984 sse_spal(edt_p, gspv | XPLLDAT | XPLLCLK);
06985 }
06986 else
06987 {
06988 sse_spal(edt_p, gspv);
06989 sse_spal(edt_p, gspv | XPLLCLK);
06990 }
06991
06992 edt_msg(EDTDEBUG, "sse_xosc: n:%d s:%x\n", n, (s != 0));
06993 }
06994
06995 sse_spal(edt_p, gspv | XPLLSTB);
06996 sse_spal(edt_p, gspv);
06997
06998
06999 if ((val >> 11) == 6)
07000 {
07001 gspv |= XPLLBYP;
07002 sse_spal(edt_p, gspv);
07003
07004 sse_wpp(edt_p, XC_AVSEL);
07005 }
07006 else
07007 sse_wpp(edt_p, 0);
07008
07009
07010 if (XC_X16)
07011 sse_wpp(edt_p, XC_X16);
07012 }
07013
07014
07015 double
07016 sse_set_out_clk(EdtDev * edt_p, double fmhz)
07017 {
07018 int m, n, t, hex, nn, fx;
07019 edt_pll avp;
07020 double avf = 0.0;
07021
07022 if (fmhz < 0)
07023 {
07024 printf("sse_set_pll_freq: Invalid argument %f\n", fmhz);
07025 return 0;
07026 }
07027
07028 fx = (int) fmhz;
07029
07030 if ((fmhz > 800.0) || (fmhz < 0.000050))
07031 {
07032 printf("Error, %f MHz requested. Min of 0.000050, max of 800Mhz\n",
07033 fmhz);
07034 return (0);
07035 }
07036 else if (fx > 400)
07037 {
07038 t = 0;
07039 n = 3;
07040 m = fx / 2;
07041 nn = 1;
07042 }
07043 else if (fx > 200)
07044 {
07045 t = 0;
07046 n = 0;
07047 m = fx;
07048 nn = 2;
07049 }
07050 else if (fx > 100)
07051 {
07052 t = 0;
07053 n = 1;
07054 m = fx * 2;
07055 nn = 4;
07056 }
07057 else if (fx >= 50)
07058 {
07059 t = 0;
07060 n = 2;
07061 m = fx * 4;
07062 nn = 8;
07063 }
07064 else
07065 {
07066 avf = edt_find_vco_frequency(edt_p, fmhz * 1E6, (double) 30E6, &avp, 0);
07067 if (avf != 0)
07068 edt_set_out_clk(edt_p, &avp);
07069 t = 6;
07070 n = 3;
07071 m = 200;
07072 nn = 4;
07073 }
07074
07075 hex = (t << 11) | (n << 9) | m;
07076
07077 sse_xosc(edt_p, hex);
07078
07079 if (t != 6)
07080 {
07081 edt_msg(EDTDEBUG,
07082 "sse_set_out_clk: %f MHz MC12430: t:%d n:%d m:%d hex:0x%04x\n",
07083 (2.0 * m / nn), t, n, m, hex);
07084 return (2.0 * m / nn);
07085 }
07086 else
07087 {
07088 edt_msg(EDTDEBUG,
07089 "sse_set_out_clk: %f MHz AV9110: m:%d n:%d v:%d r:%d h:%d l:%d x:%d\n",
07090 (avf / 1E6), avp.m, avp.n, avp.v, avp.r, avp.h, avp.l, avp.x);
07091 return (avf / 1E6);
07092 }
07093 }
07094
07095
07096
07097
07098 void
07099 sse_shift(EdtDev *edt_p, int shift)
07100 {
07101 int n ;
07102 unsigned char old;
07103
07104 if (shift)
07105 {
07106 old = edt_intfc_read(edt_p, PCD_PAL1) & ~0x02;
07107 edt_intfc_write(edt_p, PCD_PAL1, old);
07108
07109 for (n = 0; n < shift; n++)
07110 {
07111 edt_msleep(1);
07112 edt_intfc_write(edt_p, PCD_PAL1, (unsigned char) (0x02 | old));
07113 edt_msleep(1);
07114 edt_intfc_write(edt_p, PCD_PAL1, old);
07115 }
07116 }
07117 }
07118
07119
07120
07121
07122 void
07123 sse_shift_chan(EdtDev *edt_p, int shift, int channel)
07124 {
07125 int n ;
07126 unsigned char old;
07127
07128 if (shift) {
07129 if (channel==0) {
07130 old = edt_intfc_read(edt_p, PCD_PAL1) & ~0x02;
07131 edt_intfc_write(edt_p, PCD_PAL1, old);
07132
07133 for (n = 0; n < shift; n++)
07134 {
07135 edt_msleep(1);
07136 edt_intfc_write(edt_p, PCD_PAL1, (unsigned char) (0x02 | old));
07137 edt_msleep(1);
07138 edt_intfc_write(edt_p, PCD_PAL1, old);
07139 }
07140 } else {
07141 old = edt_intfc_read(edt_p, PCD_PAL2) & ~0x20;
07142 edt_intfc_write(edt_p, PCD_PAL2, old);
07143
07144 for (n = 0; n < shift; n++)
07145 {
07146 edt_msleep(1);
07147 edt_intfc_write(edt_p, PCD_PAL2, (unsigned char) (0x20 | old));
07148 edt_msleep(1);
07149 edt_intfc_write(edt_p, PCD_PAL2, old);
07150 }
07151 }
07152 }
07153 }
07154 #endif
07155
07156
07157 #ifdef P11W
07158
07159 #include "p11w.h"
07160
07161 u_short
07162 p11w_get_command(EdtDev * edt_p)
07163 {
07164 return (edt_reg_read(edt_p, P11_COMMAND));
07165 }
07166
07167 void
07168 p11w_set_command(EdtDev * edt_p, u_short val)
07169 {
07170 edt_reg_write(edt_p, P11_COMMAND, val);
07171 }
07172
07173 u_short
07174 p11w_get_config(EdtDev * edt_p)
07175 {
07176 return (edt_reg_read(edt_p, P11_CONFIG));
07177 }
07178
07179 void
07180 p11w_set_config(EdtDev * edt_p, u_short val)
07181 {
07182 edt_reg_write(edt_p, P11_CONFIG, val);
07183 }
07184
07185 u_short
07186 p11w_get_data(EdtDev * edt_p)
07187 {
07188 return (edt_reg_read(edt_p, P11_DATA));
07189 }
07190
07191 void
07192 p11w_set_data(EdtDev * edt_p, u_short val)
07193 {
07194 edt_reg_write(edt_p, P11_DATA, val);
07195 }
07196
07197 u_short
07198 p11w_get_stat(EdtDev * edt_p)
07199 {
07200 return (edt_reg_read(edt_p, P11_STATUS));
07201 }
07202
07203 u_int
07204 p11w_get_count(EdtDev * edt_p)
07205 {
07206 return (edt_reg_read(edt_p, P11_COUNT));
07207 }
07208
07209
07210
07211
07212
07213 void
07214 p11w_abortdma_onattn(EdtDev *edt_p, int flag)
07215 {
07216 int arg = 0x11 ;
07217 u_short readcmd ;
07218
07219
07220 if (flag)
07221 {
07222 edt_ioctl(edt_p, P11G_READ_COMMAND, &readcmd) ;
07223 readcmd |= P11W_EN_ATT ;
07224 edt_ioctl(edt_p, P11S_READ_COMMAND, &readcmd) ;
07225
07226 edt_ioctl(edt_p, EDTS_CUSTOMER, &arg) ;
07227 }
07228 else
07229 {
07230 edt_ioctl(edt_p, P11G_READ_COMMAND, &readcmd) ;
07231 readcmd &= ~P11W_EN_ATT ;
07232 edt_ioctl(edt_p, P11S_READ_COMMAND, &readcmd) ;
07233
07234 arg = 0 ;
07235 edt_ioctl(edt_p, EDTS_CUSTOMER, &arg) ;
07236 }
07237 }
07238
07239 void
07240 p11w_set_abortdma_onintr(EdtDev *edt_p, int flag)
07241 {
07242 u_short readcmd, writecmd ;
07243
07244 if (flag == 0)
07245 {
07246 edt_ioctl(edt_p, P11G_READ_COMMAND, &readcmd) ;
07247 readcmd &= ~P11W_EN_ATT ;
07248 edt_ioctl(edt_p, P11S_READ_COMMAND, &readcmd) ;
07249
07250 edt_ioctl(edt_p, P11G_WRITE_COMMAND, &writecmd) ;
07251 writecmd &= ~P11W_EN_ATT ;
07252 edt_ioctl(edt_p, P11S_WRITE_COMMAND, &writecmd) ;
07253 }
07254
07255 edt_ioctl(edt_p, EDTS_ABORTDMA_ONINTR, &flag) ;
07256
07257 if (flag)
07258 {
07259 edt_ioctl(edt_p, P11G_READ_COMMAND, &readcmd) ;
07260 readcmd |= P11W_EN_ATT ;
07261 edt_ioctl(edt_p, P11S_READ_COMMAND, &readcmd) ;
07262
07263 edt_ioctl(edt_p, P11G_WRITE_COMMAND, &writecmd) ;
07264 writecmd |= P11W_EN_ATT ;
07265 edt_ioctl(edt_p, P11S_WRITE_COMMAND, &writecmd) ;
07266 }
07267 }
07268
07269 #endif
07270
07281 int
07282 edt_device_id(EdtDev *edt_p)
07283 {
07284 if (edt_p)
07285 return edt_p->devid;
07286 return -1;
07287 }
07288
07303 int
07304 edt_check_1_vs_4(EdtDev *edt_p)
07305 {
07306 char name[129];
07307 int pci_channels = 4;
07308
07309 edt_flash_get_fname(edt_p, name);
07310
07311 if (isdigit(name[strlen(name)-1]))
07312 {
07313 if (strlen(name) >= 2 && isdigit(name[strlen(name)-2]))
07314 {
07315 pci_channels = atoi(name + strlen(name)-2);
07316 }
07317 else
07318 {
07319 pci_channels = atoi(name + strlen(name)-1);
07320 }
07321 }
07322
07323 return pci_channels;
07324 }
07325
07326
07337 int
07338 edtdev_channels_from_type(EdtDev *edt_p)
07339
07340 {
07341 if (edt_is_4channel(edt_p)) return 4;
07342 if (edt_is_1or4channel(edt_p)) return edt_check_1_vs_4(edt_p);
07343 if (edt_is_2channel(edt_p)) return 2;
07344 if (edt_is_3channel(edt_p)) return 3;
07345 if (edt_is_1553(edt_p)) return 34;
07346 if (edt_is_16channel(edt_p)) return 16;
07347 if (edt_is_32channel(edt_p)) return 32;
07348 return 1;
07349
07350 }
07351
07356 int
07357 edt_devtype_from_id(int id)
07358 {
07359 if (id == P11W_ID) return p11w;
07360 if (id == P16D_ID) return p16d;
07361 if (ID_IS_PCD(id)) return pcd;
07362 if (ID_IS_PDV(id)) return pdv;
07363 if (ID_IS_DUMMY(id)) return dummy;
07364 return unknown;
07365 }
07366
07367
07368
07378 char *
07379 edt_idstring(int id, int promcode)
07380 {
07381 if (promcode == AMD_XC5VLX30T_A) {
07382 switch(id) {
07383 case PE4DVCL_ID: return ("pcie4 dva c-link");
07384 case PE8DVCL_ID: return ("pcie8 dva c-link");
07385 case PE8DVCLS_ID: return ("pcie8 dva cls");
07386 }
07387 }
07388 return edt_idstr(id);
07389 }
07390
07401 char *
07402 edt_idstr(int id)
07403 {
07404 switch(id)
07405 {
07406
07407
07408
07409
07410
07411
07412 case PE1DVVL_ID: return ("VisionLink F1");
07413 case PE4DVVL_ID: return ("VisionLink F4");
07414 case PE4DVVLSIM_ID: return ("VisionLink S4");
07415 case PE4DVVLFOX_ID: return ("VisionLink FOX4");
07416
07417 case P11W_ID: return("pci 11w");
07418 case P16D_ID: return("pci 16d");
07419 case PDV_ID: return("pci dv");
07420 case PDVA_ID: return("pci dva");
07421 case PDVA16_ID: return("pci dva16");
07422 case PDVK_ID: return("pci dvk");
07423 case PDVRGB_ID: return("pci dv-rgb");
07424 case PDV44_ID: return("pci dv44");
07425 case PDVCL_ID: return("pci dv c-link");
07426 case PDVCL2_ID: return("pci dv cls");
07427 case PE4DVCL_ID: return("pcie4 dv c-link");
07428 case PE8DVCL_ID: return("pcie8 dv c-link");
07429 case PE8DVCLS_ID: return("pcie8 dv cls");
07430 case PDVAERO_ID: return("pcd dv aero serial");
07431 case PCD20_ID: return("pci cd-20");
07432 case PCD40_ID: return("pci cd-40");
07433 case PCD60_ID: return("pci cd-60");
07434 case PCDA_ID: return("pci cda");
07435 case PCDCL_ID: return("pci cd cl");
07436 case PGP20_ID: return("pci gp-20");
07437 case PGP40_ID: return("pci gp-40");
07438 case PGP60_ID: return("pci gp-60");
07439
07440 case PGP_THARAS_ID: return("pci gp-tharas");
07441 case PGP_ECL_ID: return("pci gp-ecl");
07442 case PCD_16_ID: return("pci cd-16");
07443
07444 case PCDA16_ID: return("pci cda16");
07445 case PE4CDA_ID: return("pcie4 cda");
07446 case PE4CDA16_ID: return("pcie4 cda16");
07447
07448 case PDVFCI_AIAG_ID: return("pci-fci aiag");
07449 case PDVFCI_USPS_ID: return("pci-fci usps");
07450 case PCDFCI_SIM_ID: return("pci-fci sim");
07451 case PCDFCI_PCD_ID: return("pci-fci pcd");
07452 case PCDFOX_ID: return("pcd fox");
07453 case PDVFOX_ID: return("pci dv fox");
07454 case PE4DVFOX_ID: return("pcie4 dva fox");
07455 case PE8DVFOX_ID: return("pcie8 dva fox");
07456 case P53B_ID: return("pci 53b");
07457 case PDVFOI_ID: return("pdv foi");
07458 case PSS4_ID: return("pci ss-4");
07459 case PSS16_ID: return("pci ss-16");
07460 case PGS4_ID: return("pci gs-4");
07461 case PGS16_ID: return("pci gs-16");
07462 case PE8LX1_ID: return("pcie8 lx-1");
07463 case PE8LX16_LS_ID: return("pcie8 lx-16 (slow)");
07464 case PE8LX16_ID: return("pcie8 lx-16");
07465 case PE8LX32_ID: return("pcie8 lx-32");
07466 case PE4AMC16_ID: return("pcie4 AMC16");
07467 case PE8G3S5_ID: return("pcie8 g3s5");
07468 case PE8G3KU_ID: return("pcie8 g3ku");
07469 case WSU1_ID: return("wsu 1");
07470 case SNAP1_ID: return("snap 1");
07471 case DMY_ID: return("dummy");
07472 case DMYK_ID: return("dummy pci dvk/44/foi");
07473 case PC104ICB_ID: return("pc104 icb");
07474 case PE4BL_RADIO_ID: return("pcie4 lcr radio blade");
07475 case PE1BL_TIMING_ID: return("pcie1 lcr timing blade");
07476 case PE8BL_10GNIC_ID: return("pcie8 lcr 2x10g nic blade");
07477 case LCRBOOT_ID: return("lcr boot");
07478 case PE8G2V7_ID: return("pcie8 g2v7");
07479 case UNKNOWNAB_ID: return("unknown 00ab");
07480 case UNKNOWNAC_ID: return("unknown 00ac");
07481 case UNKNOWNAD_ID: return("unknown 00ad");
07482 case UNKNOWNAE_ID: return("unknown 00ae");
07483 case UNKNOWNAF_ID: return("unknown 00af");
07484 default: return("unknown");
07485 }
07486 }
07487
07488
07489
07490
07491
07492
07493
07494
07495
07496
07497
07498
07499
07500
07501
07502
07503
07504
07505
07506
07507
07508
07509 char *
07510 edt_get_flash_prom_header(EdtDev *edt_p, char *name)
07511 {
07512 int i;
07513 u_short stat;
07514 u_char jumpers, idbits, xidbits;
07515 int promcode;
07516 EdtPromData pdata;
07517 Edt_prominfo *ep;
07518
07519 promcode = edt_flash_prom_detect(edt_p, &stat);
07520 ep = edt_get_prominfo(promcode);
07521 jumpers = stat & 0x3;
07522 idbits = (stat >>2) & 0x1f;
07523 xidbits = stat >> 8;
07524
07525 ep = edt_get_prominfo(promcode);
07526 edt_read_prom_data(edt_p, promcode, ep->defaultseg, &pdata);
07527
07528 if (promcode > edt_get_max_promcode())
07529 sprintf(name, "unknown [%02x %02x]", idbits, xidbits);
07530 else strncpy(name, pdata.id, 127);
07531
07532 return name;
07533 }
07534
07535
07542 #if defined(VXWORKS) || defined(TEST_VXWORKS)
07543
07544 char edt_vxw_cmdstr[512];
07545
07546
07547
07548
07549
07550
07551
07552
07553 static char *program_func_name[32] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07554 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07555 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07556 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
07557 static void * edt_vx_system_func[32] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07558 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07559 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07560 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
07561
07562
07563
07564
07565
07566 int
07567 edt_vx_system_register_func(const char *funcstr, int (funcptr)(char *))
07568 {
07569 int i;
07570
07571 for (i = 0; i < 32; i++)
07572 {
07573 if (program_func_name[i] == NULL)
07574 break;
07575 }
07576
07577 if (i == 32)
07578 return(-1);
07579 else
07580 {
07581 program_func_name[i] = edt_alloc(strlen(funcstr) + 1);
07582 strcpy(program_func_name[i], funcstr);
07583 edt_vx_system_func[i] = funcptr;
07584 return 0;
07585 }
07586 }
07587 #endif
07588
07589 int
07590 edt_system(const char *cmdstr)
07591 {
07592 #if defined(_NT_)
07593
07594 int ret;
07595 char *newstr = (char *) malloc(512) ;
07596 char *p = newstr ;
07597 int nowait = 0;
07598 char *arg[32] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07599 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07600 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07601 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
07602 };
07603 int i ;
07604
07605 if (cmdstr == NULL || *cmdstr == '\0')
07606 return(0) ;
07607
07608 strncpy(newstr, cmdstr, 511) ;
07609 for (i = 0; (i < 32) && (p && *p); i++)
07610 {
07611 while (*p == ' ' || *p == '\t')
07612 *p++ = '\0' ;
07613
07614 arg[i] = p ;
07615
07616 while (*p != ' ' && *p != '\t' && *p != '\0')
07617 ++ p ;
07618 }
07619
07620 if (*arg[i-1] == '&')
07621 {
07622 arg[i-1] = NULL;
07623 nowait = 1;
07624 }
07625
07626 ret = (int)spawnv((nowait) ? _P_NOWAIT : _P_WAIT, arg[0], arg);
07627
07628 free(newstr);
07629 return ret;
07630 #elif defined(VXWORKS) || defined(TEST_VXWORKS)
07631
07632
07633
07634
07635
07636
07637
07638 {
07639 int i;
07640 char *cmd;
07641 char *opts;
07642 char *tmp;
07643 int (*fnp)(char *);
07644
07645 strncpy(edt_vxw_cmdstr, cmdstr, 511);
07646 cmd = edt_vxw_cmdstr;
07647 opts = strchr(edt_vxw_cmdstr, ' ');
07648
07649 if (opts)
07650 *opts++ = '\0';
07651
07652 tmp = strrchr(edt_vxw_cmdstr, '/');
07653 if (tmp)
07654 cmd = tmp + 1;
07655
07656
07657 edt_msg(EDTDEBUG, "VXWORKS_test: edt_system(%s, %s)\n", cmd, opts);
07658 #if defined(TEST_VXWORKS)
07659 printf("VXWORKS_test: edt_system(%s, %s)\n", cmd, opts);
07660 #endif
07661
07662 for (i = 0; i < 32; i++)
07663 {
07664 if (program_func_name[i] == NULL)
07665 return -1;
07666 else if (strncmp(program_func_name[i], cmd, 511) == 0)
07667 {
07668 fnp = (int (*)(char*)) edt_vx_system_func[i];
07669 edt_msg(EDTDEBUG, "VXWORKS_test: found name %s func %p\n", cmd, fnp);
07670 return fnp(opts);
07671 }
07672 }
07673
07674 if (i == 32)
07675 {
07676 edt_msg(EDTDEBUG, "VXWORKS_test: name not found %s, must be registered with edt_vx_system_register_func()\n", cmd);
07677 return -1;
07678 }
07679 }
07680 return(0);
07681 }
07682 #else
07683
07684 int ret ;
07685
07686 ret = system(cmdstr) ;
07687
07688 #if defined(__sun) || defined(__linux__) || defined(__APPLE__)
07689 if (ret == -1 || WIFEXITED(ret) == 0)
07690 return -1 ;
07691 else
07692 return WEXITSTATUS(ret) ;
07693 #else
07694 return ret ;
07695 #endif
07696 #endif
07697 }
07698
07699 #define MEZZ_PATH_FIELD_CHAR '|'
07700
07701 char *
07702 edt_get_last_bitpath(EdtDev *edt_p)
07703
07704 {
07705 FILE *f;
07706 static char cache_name[MAXPATH];
07707
07708
07709 sprintf(cache_name, ".interface_bitfile.%d", edt_p->unit_no);
07710
07711 if ((f = fopen(cache_name, "r")))
07712 {
07713
07714 volatile char *throwaway = fgets(cache_name, MAXPATH, f);
07715
07716 if (strlen(cache_name))
07717 {
07718
07719 if (cache_name[strlen(cache_name)-1] == '\n')
07720 cache_name[strlen(cache_name)-1] = 0;
07721 }
07722
07723 fclose(f);
07724
07725 return cache_name;
07726 }
07727
07728 return NULL;
07729 }
07730
07731
07732 void
07733 edt_set_last_bitpath(EdtDev *edt_p, const char *fullpath)
07734
07735 {
07736 FILE *f;
07737 char cache_name[MAXPATH];
07738
07739 sprintf(cache_name, ".interface_bitfile.%d", edt_p->unit_no);
07740
07741 if ((f = fopen(cache_name, "w")))
07742 {
07743
07744 fputs(fullpath, f);
07745
07746 fclose(f);
07747
07748 }
07749 }
07750
07751
07765 int
07766 edt_set_mezz_chan_bitpath(EdtDev *edt_p, const char *bitpath, int channel)
07767 {
07768 edt_bitpath pathbuf, chan0, chan1;
07769 const char *s1;
07770 int sp;
07771 int rc;
07772
07773
07774
07775 if (strlen(bitpath))
07776 {
07777 sp = (int) strlen(bitpath) - 1;
07778
07779 while (sp >= 0 && bitpath[sp] != '/' && bitpath[sp] != '\\')
07780 sp --;
07781
07782 if (sp >= 0)
07783 sp++;
07784 else
07785 sp = 0;
07786 }
07787 else
07788 sp = 0;
07789
07790 s1 = bitpath + sp;
07791
07792 edt_get_mezz_chan_bitpath(edt_p,chan0, sizeof(chan0),0);
07793 edt_get_mezz_chan_bitpath(edt_p,chan1, sizeof(chan1),1);
07794
07795 if (channel == 0)
07796 sprintf(pathbuf,"%s%c%s",s1,MEZZ_PATH_FIELD_CHAR,chan1);
07797 else
07798 sprintf(pathbuf,"%s%c%s",chan0, MEZZ_PATH_FIELD_CHAR, s1);
07799
07800 rc = edt_ioctl(edt_p, EDTS_MEZZ_BITPATH, pathbuf);
07801
07802 edt_get_mezz_chan_bitpath(edt_p, edt_p->bfd.mezz_name0,
07803 sizeof(edt_p->bfd.mezz_name0),0);
07804 edt_get_mezz_chan_bitpath(edt_p, edt_p->bfd.mezz_name1,
07805 sizeof(edt_p->bfd.mezz_name1),1);
07806
07807 return rc;
07808 }
07809
07810
07825 int
07826 edt_get_mezz_chan_bitpath(EdtDev *edt_p, char *bitpath, int size, int channel)
07827 {
07828 int ret = 0 ;
07829 edt_bitpath pathbuf ;
07830 char *s2, *s3;
07831 int sp;
07832
07833
07834 ret = edt_ioctl(edt_p, EDTG_MEZZ_BITPATH, pathbuf);
07835
07836 s2 = pathbuf;
07837 sp = 0;
07838 while (sp < (int)strlen(pathbuf) && pathbuf[sp] != MEZZ_PATH_FIELD_CHAR)
07839 sp++;
07840
07841 s3 = s2 + sp;
07842 if (s3[0] == MEZZ_PATH_FIELD_CHAR)
07843 {
07844 s3[0] = 0;
07845 s3++;
07846 }
07847
07848 if (channel == 0)
07849 strncpy(bitpath, s2, size - 1) ;
07850 else
07851 strncpy(bitpath, s3, size - 1) ;
07852
07853 return ret ;
07854 }
07855
07867 int
07868 edt_set_mezz_bitpath(EdtDev *edt_p, const char *bitpath)
07869 {
07870 edt_bitpath pathbuf;
07871 int rc;
07872 int i = (int) strlen(bitpath)-1;
07873
07874 while (i>= 0 && bitpath[i] != '\\' && bitpath[i] != '/')
07875 i--;
07876
07877 if (i >= 0)
07878 i++;
07879 else
07880 i = 0;
07881
07882 strncpy(pathbuf, bitpath+i, sizeof(edt_bitpath) - 1) ;
07883 rc = edt_ioctl(edt_p, EDTS_MEZZ_BITPATH, pathbuf);
07884
07885 return rc;
07886 }
07887
07888
07902 int
07903 edt_get_mezz_bitpath(EdtDev *edt_p, char *bitpath, int size)
07904 {
07905 int ret = 0 ;
07906 edt_bitpath pathbuf ;
07907
07908 ret = edt_ioctl(edt_p, EDTG_MEZZ_BITPATH, pathbuf);
07909 strncpy(bitpath, pathbuf, size - 1) ;
07910 return ret ;
07911 }
07912
07913
07925 int
07926 edt_set_bitpath(EdtDev *edt_p, const char *bitpath)
07927 {
07928 edt_bitpath pathbuf ;
07929 int rc;
07930
07931 strncpy(pathbuf, bitpath, sizeof(edt_bitpath) - 1) ;
07932 rc = edt_ioctl(edt_p, EDTS_BITPATH, pathbuf);
07933
07934 edt_get_bitname(edt_p, edt_p->bfd.bitfile_name,
07935 sizeof(edt_p->bfd.bitfile_name));
07936
07937 edt_set_last_bitpath(edt_p, bitpath);
07938
07939 return rc;
07940 }
07941
07942
07956 int
07957 edt_get_bitpath(EdtDev *edt_p, char *bitpath, int size)
07958 {
07959 int ret = 0 ;
07960 edt_bitpath pathbuf ;
07961 pathbuf[0] = '\0';
07962 ret = edt_ioctl(edt_p, EDTG_BITPATH, pathbuf);
07963
07964 strncpy(bitpath, pathbuf, size - 1) ;
07965 return ret ;
07966 }
07967
07981 int
07982 edt_get_bitname(EdtDev *edt_p, char *bitpath, int size)
07983 {
07984 int ret = 0 ;
07985 char *name;
07986 edt_bitpath pathbuf ;
07987
07988 pathbuf[0] = '\0';
07989 ret = edt_ioctl(edt_p, EDTG_BITPATH, pathbuf);
07990
07991
07992 if ((name = strrchr(pathbuf, '/')) || (name = strrchr(pathbuf, '\\')))
07993 ++ name;
07994 else
07995 name = pathbuf;
07996
07997 strcpy(bitpath, name) ;
07998
07999 return ret ;
08000 }
08001
08013 int
08014 edt_get_driver_version(EdtDev *edt_p, char *version, int size)
08015 {
08016 int ret = 0 ;
08017 edt_version_string vbuf ;
08018
08019 ret = edt_ioctl(edt_p, EDTG_VERSION, vbuf);
08020
08021 strncpy(version, vbuf, size - 1) ;
08022 return ret ;
08023 }
08024
08037 int
08038 edt_get_driver_buildid(EdtDev *edt_p, char *build, int size)
08039 {
08040 int ret = 0 ;
08041 edt_version_string vbuf ;
08042
08043 ret = edt_ioctl(edt_p, EDTG_BUILDID, vbuf);
08044
08045 strncpy(build, vbuf, size - 1) ;
08046 return ret ;
08047 }
08048
08049 static char * edt_library_version = EDT_LIBRARY_VERSION;
08050 static char * edt_library_buildid = FULLBUILD;
08051
08061 int
08062 edt_get_library_version(EdtDev *edt_p, char *version, int size)
08063 {
08064 strncpy(version, edt_library_version, size - 1) ;
08065 return 0 ;
08066 }
08067
08068 u_int
08069 edt_get_version_number()
08070
08071 {
08072 char id_n[64];
08073
08074 u_int vi = 0;
08075 int starti;
08076 int i;
08077
08078 strncpy(id_n, edt_library_version, 63);
08079
08080 starti = 0;
08081 for (i=0;; i++)
08082 {
08083 if (!isdigit(id_n[i]))
08084 {
08085
08086 vi = (vi << 8) | atoi(id_n+starti);
08087
08088 starti = i+1;
08089
08090 if (id_n[i] != '.')
08091 break;
08092 }
08093
08094
08095 }
08096
08097 return vi;
08098
08099
08100 }
08101
08111 int
08112 edt_get_library_buildid(EdtDev *edt_p, char *build, int size)
08113 {
08114 strncpy(build, edt_library_buildid, size - 1) ;
08115 return 0 ;
08116 }
08117
08118
08122 int
08123 edt_check_version(EdtDev *edt_p)
08124
08125 {
08126 edt_version_string check;
08127
08128 edt_get_driver_version(edt_p, check, sizeof(check));
08129
08130 return (!strcmp(check,edt_library_version));
08131
08132 }
08133
08137 static u_int
08138 epr_cfg(EdtDev *edt_p, int addr)
08139 {
08140 int ret ;
08141 edt_buf buf ;
08142 buf.desc = addr ;
08143 if ((addr<0) || (addr>0x3c)) {
08144 edt_msg(EDTWARN, "epr_cfg: addr out of range\n");
08145 return(0);
08146 }
08147 ret = edt_ioctl(edt_p,EDTG_CONFIG,&buf) ;
08148 if (ret < 0)
08149 {
08150 edt_perror("EDTG_CONFIG") ;
08151 }
08152 return(u_int) (buf.value) ;
08153 }
08154
08155 static void
08156 epw_cfg(EdtDev *edt_p, int addr, int value)
08157 {
08158 int ret ;
08159 edt_buf buf ;
08160 buf.desc = addr ;
08161 if ((addr<0) || (addr>0x3c)) {
08162 edt_msg(EDTWARN, "epw_cfg: addr out of range\n");
08163 return;
08164 }
08165 buf.value = value ;
08166 ret = edt_ioctl(edt_p,EDTS_CONFIG,&buf) ;
08167 if (ret < 0)
08168 {
08169 edt_perror("EDTS_CONFIG") ;
08170 }
08171 }
08172
08178 int
08179 edt_pci_reboot(EdtDev *edt_p)
08180 {
08181 int addr, data;
08182 int buf[0x40];
08183 int rst, copy, new_one;
08184 int ret = 0;
08185 FILE *fd2;
08186 char *tmpfname = "TMPfPciReboot.cfg";
08187
08188 if ((fd2 = fopen(tmpfname, "wb")) == NULL) {
08189 edt_msg(EDTFATAL,"edt_pci_reboot: Couldn't write to temp file %s\n", tmpfname);
08190 return -1;
08191 }
08192 for (addr=0; addr<=0x3c; addr+=4) {
08193 data = epr_cfg(edt_p, addr);
08194 buf[addr] = data;
08195 putc(data, fd2);
08196 putc(data>>8, fd2);
08197 putc(data>>16, fd2);
08198 putc(data>>24, fd2);
08199
08200 }
08201 fclose(fd2);
08202 edt_msg(EDTDEBUG, "Wrote config space state out to %s\n", tmpfname);
08203
08204 edt_reg_write(edt_p, 0x01000085, 0x40) ;
08205 edt_msleep(2000) ;
08206
08207 edt_msg(EDTDEBUG, " copy reset new\n");
08208 for (addr=0; addr<=0x3c; addr+=4) {
08209 rst = epr_cfg(edt_p, addr);
08210 copy = buf[addr];
08211 epw_cfg(edt_p, addr, copy) ;
08212 new_one = epr_cfg(edt_p, addr);
08213
08214 edt_msg(EDTDEBUG, "%02x: %08x %08x %08x ", addr, copy, rst, new_one);
08215 if (copy != new_one) edt_msg(EDTDEBUG, "ERROR\n");
08216 else if (rst != new_one) edt_msg(EDTDEBUG, "changed\n");
08217 else edt_msg(EDTDEBUG, "\n");
08218
08219
08220 if (addr == 0x0c)
08221 {
08222 if ((rst & 0xff) == (new_one & 0xff))
08223 ret = -1;
08224 }
08225
08226 }
08227 return ret;
08228 }
08229
08233 int
08234 edt_set_merge(EdtDev * edt_p, u_int size, int span, u_int offset, u_int count)
08235 {
08236 edt_merge_args tmp;
08237 int ret;
08238
08239 tmp.line_size = size ;
08240 tmp.line_span = span;
08241 tmp.line_offset = offset;
08242 tmp.line_count = count;
08243 ret = edt_ioctl(edt_p, EDTS_MERGEPARMS, &tmp);
08244 return (ret);
08245 }
08246
08247
08248 u_char
08249 edt_flipbits(u_char val)
08250 {
08251 int i;
08252 u_char ret = 0;
08253
08254 for (i = 0; i < 8; i++)
08255 {
08256 if (val & (1 << i))
08257 ret |= 0x80 >> i;
08258 }
08259 return (ret);
08260 }
08261
08262
08263
08264
08265
08266
08267
08268
08269
08270
08271
08272 int
08273 edt_set_kernel_buffers(EdtDev * edt_p, int onoff)
08274
08275 {
08276 uint_t val = (uint_t) onoff;
08277
08278 edt_ioctl(edt_p, EDTS_DRV_BUFFER, &val);
08279
08280 return val;
08281 }
08282
08283
08284
08285
08286
08287
08288
08289
08290 int
08291 edt_get_kernel_buffers(EdtDev * edt_p)
08292
08293 {
08294 uint_t val = (uint_t) -1;
08295
08296 if (edt_p->devid == DMY_ID)
08297 val = 0 ;
08298 else
08299 edt_ioctl(edt_p, EDTS_DRV_BUFFER, &val);
08300
08301 return val;
08302 }
08303
08304 int
08305 edt_set_mmap_buffers(EdtDev *edt_p, int state)
08306
08307 {
08308
08309 uint_t val = edt_get_kernel_buffers(edt_p) & ~EDT_MMAP_KBUFS;
08310
08311 val |= (state)?EDT_MMAP_KBUFS:0;
08312
08313 return edt_ioctl(edt_p, EDTS_DRV_BUFFER, &val);
08314
08315
08316 }
08317
08318 int
08319 edt_get_mmap_buffers(EdtDev *edt_p)
08320
08321 {
08322
08323 int rc = (edt_get_kernel_buffers(edt_p) & EDT_MMAP_KBUFS) != 0;
08324
08325 return rc;
08326 }
08327
08328 int
08329 edt_get_persistent_buffers(EdtDev * edt_p)
08330
08331 {
08332 uint_t val = (uint_t) -1;
08333
08334 edt_ioctl(edt_p, EDTS_DRV_BUFFER, &val);
08335
08336 printf("val = %d\n", val);
08337
08338 return (val & EDT_PERSISTENT_KBUFS) != 0;
08339 }
08340
08341 int
08342 edt_set_persistent_buffers(EdtDev * edt_p, int state)
08343
08344 {
08345
08346 uint_t val = edt_get_kernel_buffers(edt_p) & ~EDT_PERSISTENT_KBUFS;
08347
08348 val |= (state)?EDT_PERSISTENT_KBUFS:0;
08349
08350 return edt_ioctl(edt_p, EDTS_DRV_BUFFER, &val);
08351
08352 }
08353
08399 u_int
08400 edt_get_dma_info(EdtDev * edt_p, edt_dma_info *dmainfo)
08401 {
08402 edt_dma_info tmpinfo ;
08403
08404 edt_ioctl(edt_p, EDTG_DMA_INFO, &tmpinfo);
08405
08406 if (dmainfo) *dmainfo = tmpinfo ;
08407
08408 return (tmpinfo.used_dma | tmpinfo.alloc_dma | tmpinfo.active_dma) ;
08409 }
08410
08424 int
08425 edt_find_xpn(char *part_number, char *fpga)
08426 {
08427 return edt_get_xref_info("./edt_parts.xpn", (const char *)part_number, fpga, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
08428 }
08429
08462 int
08463 edt_get_xref_info(const char *path, const char *pn, char *fpga, char *sn, char *mtype, char *moffs, char *mcount, char *desc, char *rsvd1, char *rsvd2)
08464 {
08465 int ret = 0;
08466 FILE *xfp;
08467 char str[EDT_STRBUF_SIZE];
08468 char xf_pn[EDT_STRBUF_SIZE], xf_fpga[EDT_STRBUF_SIZE];
08469
08470 if ((xfp = fopen(path, "r")) == NULL)
08471 {
08472 char errmsg[EDT_STRBUF_SIZE];
08473 sprintf(errmsg, "couldn't open '%s'\n", path);
08474 edt_msg(EDTWARN, errmsg);
08475 return 0;
08476 }
08477
08478 while (fgets(str, EDT_STRBUF_SIZE, xfp) != NULL)
08479 {
08480
08481 if ((strlen(str) > 10) && (*str >= '0') && (*str <= '9'))
08482 {
08483 int n;
08484
08485
08486 if ((n = sscanf(str, "%s %s", xf_pn, xf_fpga)) == 2)
08487 {
08488
08489 if ((strlen(xf_pn) == 10) && (strcasecmp(xf_pn, pn) == 0))
08490 {
08491 ret = get_xref_info_params(str, fpga, sn, mtype, moffs, mcount, desc, rsvd1, rsvd2);
08492
08493 fclose(xfp);
08494 return ret;
08495 }
08496
08497
08498
08499 else if ((strlen(xf_pn) == 8) && (strncasecmp(xf_pn, pn, 8) == 0))
08500 {
08501 ret = get_xref_info_params(str, fpga, sn, mtype, moffs, mcount, desc, rsvd1, rsvd2);
08502 }
08503 }
08504 }
08505 }
08506
08507 fclose(xfp);
08508
08509 return ret;
08510 }
08511
08515 static int
08516 get_xref_info_params(char *str, char *fpga, char *sn, char *mtype, char *moffs, char *mcount, char *desc, char *rsvd1, char *rsvd2)
08517 {
08518 int n, ret = 0;
08519 char xf_partnum[128], xf_fpga[128], xf_sn[128], xf_mtype[128], xf_moffs[128], xf_mcount[128], xf_desc[128], xf_rsvd1[128], xf_rsvd2[128];
08520
08521 if (fpga) fpga[0] = '\0';
08522 if (sn) sn[0] = '\0';
08523 if (mtype) mtype[0] = '\0';
08524 if (moffs) moffs[0] = '\0';
08525 if (mcount) mcount[0] = '\0';
08526 if (desc) desc[0] = '\0';
08527 if (rsvd1) rsvd1[0] = '\0';
08528 if (rsvd2) rsvd2[0] = '\0';
08529
08530 n = sscanf(str, "%s %s %s %s %s %s \"%64[^\"]s\" %s", xf_partnum, xf_fpga, xf_sn, xf_mtype, xf_moffs, xf_mcount, xf_desc, xf_rsvd1, xf_rsvd2);
08531
08532
08533 if ((n > 1) && fpga && (strlen(xf_fpga) > 1) && (strlen(xf_fpga) <= 64))
08534 {
08535 strcpy(fpga, xf_fpga);
08536 ++ret;
08537 }
08538
08539
08540 if ((n > 2) && sn && (strlen(xf_sn) > 5) && (strlen(xf_sn) < 25))
08541 {
08542 int i;
08543
08544
08545 strcpy(sn, xf_sn);
08546 ++ret;
08547 for (i=strlen(xf_sn)-1; i > strlen(xf_sn) - 4; i--)
08548 {
08549 if (!isdigit(xf_sn[i]))
08550 {
08551 sn[0] = '\0';
08552 --ret;
08553 break;
08554 }
08555 }
08556 }
08557
08558
08559 if ((n > 3) && mtype && (strlen(xf_mtype) > 0) && (strlen(xf_mtype) <= 3) && isdigit_str(xf_mtype))
08560 {
08561 strcpy(mtype, xf_mtype);
08562 ++ret;
08563 }
08564
08565
08566 if ((n > 4) && moffs && (strlen(xf_moffs) > 0) && (strlen(xf_moffs) <= 3) && isdigit_str(xf_moffs))
08567 {
08568 strcpy(moffs, xf_moffs);
08569 ++ret;
08570 }
08571
08572
08573 if ((n > 5) && mcount && (strlen(xf_mcount) > 0) && (strlen(xf_mcount) <= 3) && isdigit_str(xf_mcount))
08574 {
08575 strcpy(mcount, xf_mcount);
08576 ++ret;
08577 }
08578
08579
08580 if ((n > 6) && desc && (strlen(xf_desc) > 3) && (strlen(xf_desc) <= 128))
08581 {
08582 strcpy(desc, xf_desc);
08583 ++ret;
08584 }
08585
08586
08587 if (n > 7)
08588 strcpy(rsvd1, xf_rsvd1);
08589
08590 if (n > 8)
08591 strcpy(rsvd2, xf_rsvd2);
08592
08593 return ret;
08594 }
08595
08596 static int
08597 isdigit_str(char *s)
08598 {
08599 u_int i;
08600
08601 for (i=0; i<strlen(s); i++)
08602 if ((s[i]) < '0' || s[i] > '9')
08603 return 0;
08604 return 1;
08605 }
08606
08607 int
08608 edt_user_dma_wakeup(EdtDev *edt_p)
08609 {
08610 u_int i = 1;
08611
08612 #ifdef _NT_
08613 HANDLE event;
08614 int rc;
08615
08616 if (!edt_p->event_funcs[EDT_EVENT_BUF].wait_event)
08617 {
08618 edt_get_kernel_event(edt_p, EDT_EVENT_BUF);
08619 }
08620
08621 event = edt_p->event_funcs[EDT_EVENT_BUF].wait_event;
08622
08623 rc = SetEvent(event);
08624 rc = ResetEvent(event);
08625
08626 edt_p->last_wait_ret = EDT_WAIT_USER_WAKEUP;
08627 return !rc;
08628
08629 #else
08630
08631 return edt_ioctl(edt_p,EDTS_USER_DMA_WAKEUP,&i);
08632
08633 #endif
08634
08635 }
08636
08637 int
08638 edt_had_user_dma_wakeup(EdtDev *edt_p)
08639 {
08640 u_int i = 0;
08641 #ifdef _NT_
08642 return edt_p->last_wait_ret == EDT_WAIT_USER_WAKEUP;
08643 #endif
08644 edt_ioctl(edt_p,EDTG_USER_DMA_WAKEUP,&i);
08645
08646 return i;
08647 }
08648
08649 int
08650 edt_get_wait_status(EdtDev *edt_p)
08651
08652 {
08653 u_int i = 0;
08654
08655 #ifdef _NT_
08656 return edt_p->last_wait_ret;
08657 #else
08658 edt_ioctl(edt_p,EDTG_WAIT_STATUS,&i);
08659 #endif
08660 return i;
08661
08662 }
08663
08664 int
08665 edt_clear_wait_status(EdtDev *edt_p)
08666
08667 {
08668 u_int i = 0;
08669
08670 #ifdef _NT_
08671 edt_p->last_wait_ret = 0;
08672 #else
08673 edt_ioctl(edt_p,EDTS_WAIT_STATUS,&i);
08674 #endif
08675 return i;
08676
08677 }
08678
08679 int
08680 edt_set_timeout_ok(EdtDev *edt_p, int val)
08681
08682 {
08683 return edt_ioctl(edt_p,EDTS_TIMEOUT_OK,&val);
08684 }
08685
08686 int
08687 edt_get_timeout_ok(EdtDev *edt_p)
08688
08689 {
08690 u_int i = 0;
08691
08692 edt_ioctl(edt_p,EDTG_TIMEOUT_OK,&i);
08693
08694 return i;
08695 }
08696
08697 #if 0
08698
08699 DIR *opendir(char *dirName)
08700 {
08701 printf("opendir") ;
08702 }
08703
08704 STATUS closedir(DIR *pDir)
08705 {
08706 printf("closedir") ;
08707 }
08708 struct dirent *readdir(DIR *pDir)
08709 {
08710 printf("readdir") ;
08711 }
08712
08713 #endif
08714
08715 u_int
08716 edt_set_mezz_id(EdtDev *edt_p)
08717
08718 {
08719 int ret ;
08720 edt_buf mezz_args ;
08721
08722 int chan;
08723
08724 #ifdef WIN32
08725 mezz_args.value = (uint64_t) (&edt_p->mezz);
08726 #else
08727 mezz_args.value = (uint64_t) ((unsigned long) &edt_p->mezz);
08728 #endif
08729
08730 for (chan = 0;chan<edt_p->DMA_channels;chan++)
08731 {
08732
08733 EdtDev *test_edt;
08734
08735 if (chan != edt_p->channel_no)
08736 {
08737 test_edt = edt_open_channel(EDT_INTERFACE, edt_p->unit_no, chan);
08738
08739 if (test_edt)
08740 {
08741 ret = edt_ioctl(test_edt, EDTS_MEZZ_ID, &mezz_args);
08742
08743 edt_close(test_edt);
08744 }
08745 }
08746 }
08747
08748 ret = edt_ioctl(edt_p, EDTS_MEZZ_ID, &mezz_args);
08749
08750 return ret;
08751 }
08752
08753 u_int
08754 edt_get_mezz_id(EdtDev *edt_p)
08755
08756 {
08757 int ret ;
08758 edt_buf mezz_args ;
08759 #ifdef WIN32
08760 mezz_args.value = (uint64_t) (&edt_p->mezz);
08761 #else
08762 mezz_args.value = (uint64_t) ((unsigned long) &edt_p->mezz);
08763 #endif
08764
08765 ret = edt_ioctl(edt_p, EDTG_MEZZ_ID, &mezz_args);
08766
08767 return ret;
08768 }
08769
08770
08771
08772
08773
08774
08775
08776
08777
08778
08779
08780
08781
08782
08783
08784
08785
08786
08787
08788
08789
08790
08791
08792
08793
08794
08795
08796
08797
08798
08799
08800
08801
08802
08803
08804
08805
08806
08807
08808
08809
08810
08811
08812
08813
08814
08815
08816
08817
08818
08819
08820
08821
08822
08823 #define CLK_CPLD 500
08824
08825 #define EDT_EXTBDID_IMPL 0x10
08826 #define EDT_EXTBDID_DATA 0x20
08827 #define EDT_EXTBDID_CLK 0x40
08828 #define EDT_EXTBDID_TS 0x80
08829
08830
08831
08832
08833
08834 static u_int
08835 edt_read_extbdid_val(EdtDev *edt_p)
08836
08837 {
08838 u_int ext_info = 0;
08839 int idcnt;
08840 int bdidreg;
08841
08842 for(idcnt = 31; idcnt >= 0; --idcnt)
08843 {
08844
08845 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_CLK);
08846 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS);
08847
08848
08849
08850 bdidreg = edt_intfc_read(edt_p, MEZZANINE_BD_ID);
08851
08852 if ((bdidreg & EDT_EXTBDID_DATA) != 0)
08853 ext_info |= 1 << idcnt;
08854 }
08855
08856 return ext_info;
08857
08858
08859
08860 }
08861
08862 void edt_extbdid_stop(EdtDev *edt_p)
08863 {
08864 int init;
08865
08866
08867 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_CLK);
08868 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS);
08869
08870
08871 edt_intfc_write(edt_p, MEZZANINE_BD_ID, 0);
08872 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_CLK);
08873 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_CLK | EDT_EXTBDID_DATA);
08874 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_DATA);
08875 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_DATA);
08876
08877
08878
08879 for(init = 2; init > 0; --init)
08880 {
08881 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_CLK);
08882 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS);
08883 }
08884
08885 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_CLK | EDT_EXTBDID_DATA);
08886
08887
08888 }
08889
08890
08891
08892
08893
08894 void edt_extbdid_reset(EdtDev *edt_p)
08895 {
08896 int init;
08897 int bdidreg;
08898
08899
08900
08901
08902
08903
08904 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_DATA);
08905 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_DATA);
08906 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_CLK | EDT_EXTBDID_DATA);
08907 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_CLK );
08908 edt_intfc_write(edt_p, MEZZANINE_BD_ID, 0);
08909 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_DATA);
08910 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_DATA);
08911
08912 for(init = CLK_CPLD; init > 0; --init)
08913 {
08914
08915 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_CLK);
08916 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS);
08917 }
08918
08919 bdidreg = edt_intfc_read(edt_p, MEZZANINE_BD_ID);
08920
08921 if ((bdidreg & EDT_EXTBDID_DATA) == 0)
08922 printf("After %d loops BDID databus is still low\n", init);
08923
08924
08925 edt_intfc_write(edt_p, MEZZANINE_BD_ID, 0);
08926 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_CLK);
08927 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_CLK | EDT_EXTBDID_DATA);
08928 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_CLK );
08929 edt_intfc_write(edt_p, MEZZANINE_BD_ID, 0);
08930 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_DATA);
08931 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_DATA);
08932
08933
08934
08935 for(init = 2; init > 0; --init)
08936 {
08937 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_CLK);
08938 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS);
08939 }
08940
08941
08942
08943 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_DATA);
08944 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_DATA);
08945 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_CLK | EDT_EXTBDID_DATA);
08946 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_CLK );
08947 edt_intfc_write(edt_p, MEZZANINE_BD_ID, 0);
08948 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_DATA);
08949 edt_intfc_write(edt_p, MEZZANINE_BD_ID, EDT_EXTBDID_TS | EDT_EXTBDID_DATA);
08950
08951 }
08952
08999 u_int
09000 edt_get_full_board_id(EdtDev *edt_p, int *extended_n, int *rev_id, u_int *extended_data)
09001 {
09002 u_int mezz_id;
09003 int board_id = 0;
09004 int num_blocks = 0;
09005 int ext_info = 0;
09006 int ext_data_index = 0;
09007 int tries = 2;
09008 int store = 1;
09009 int try_3x3g = 1;
09010
09011
09012 if (edt_p->mezz.id == MEZZ_ID_UNKNOWN)
09013 {
09014
09015
09016
09017 edt_get_mezz_id(edt_p);
09018
09019 edt_msleep(1);
09020
09021 if (edt_p->mezz.id == MEZZ_ID_UNKNOWN)
09022 {
09023
09024
09025
09026
09027 mezz_id = edt_intfc_read(edt_p, MEZZANINE_BD_ID);
09028 if ((mezz_id & 0x1f) == 0x12)
09029 {
09030
09031 edt_intfc_write(edt_p, (INTFC_BYTE | 0x84), 0x00);
09032 printf("edt_get_full_board_id: First time since driver load\n");
09033 board_id = -1;
09034
09035
09036 while (tries && board_id == -1)
09037 {
09038
09039
09040
09041
09042 edt_extbdid_reset(edt_p);
09043
09044
09045
09046
09047
09048 ext_info = edt_read_extbdid_val(edt_p);
09049
09050
09051
09052 num_blocks = ext_info >> 20;
09053 if(num_blocks >= 1 && num_blocks <= MAX_EXTENDED_WORDS)
09054 {
09055 board_id = (ext_info >> 8) & 0xfff;
09056
09057 if (rev_id)
09058 *rev_id = ext_info & 0xff;
09059 edt_p->mezz.extended_rev = ext_info & 0xff;
09060 }
09061 else
09062 {
09063
09064 tries--;
09065 edt_extbdid_stop(edt_p);
09066 num_blocks = 0;
09067 edt_msg(EDTWARN, "Warning: bitstream error during extended board id lookup?\n");
09068
09069 if (tries == 0 && try_3x3g == 1){
09070 edt_msg(EDTWARN, "Warning: attempting to detect 3x3g.\n");
09071
09072 edt_intfc_write(edt_p, (INTFC_BYTE | 0x84), 0x01);
09073
09074 tries = 2;
09075 try_3x3g = 0;
09076 }
09077 }
09078
09079 }
09080
09081
09082 for (ext_data_index = 0; ext_data_index < num_blocks - 1;
09083 ext_data_index ++)
09084 {
09085 ext_info = edt_read_extbdid_val(edt_p);
09086
09087 if (extended_data)
09088 extended_data[ext_data_index] = ext_info;
09089 edt_p->mezz.extended_data[ext_data_index] = ext_info;
09090
09091 }
09092
09093 edt_extbdid_stop(edt_p);
09094
09095 }
09096
09097
09098
09099 else if(mezz_id == 0x02)
09100 {
09101
09102 board_id = (mezz_id);
09103 store = 0;
09104 }
09105
09106
09107
09108 else if (mezz_id == 0xcc)
09109 {
09110
09111 board_id = (mezz_id);
09112 store = 0;
09113 }
09114
09115
09116 else if (mezz_id != 0xff)
09117 {
09118 board_id = (mezz_id & 0x0f);
09119 }
09120 else
09121 {
09122 store = 0;
09123 }
09124
09125
09126 if (store)
09127 {
09128 edt_p->mezz.id = board_id;
09129 edt_p->mezz.n_extended_words = num_blocks-1;
09130 edt_set_mezz_id(edt_p);
09131 }
09132 }
09133 }
09134
09135
09136
09137
09138 if (extended_n)
09139 *extended_n = edt_p->mezz.n_extended_words;
09140 if (rev_id)
09141 *rev_id = edt_p->mezz.extended_rev;
09142 if (extended_data)
09143 memcpy(extended_data, edt_p->mezz.extended_data, sizeof(edt_p->mezz.extended_data));
09144
09145 return edt_p->mezz.id;
09146
09147 }
09148
09163 u_int
09164 edt_get_board_id(EdtDev *edt_p)
09165 {
09166 return edt_get_full_board_id(edt_p, NULL, NULL, NULL);
09167 }
09168
09169
09170 int
09171 edt_set_ignore_signals(EdtDev *edt_p, int ignore)
09172 {
09173 return edt_ioctl(edt_p, EDTS_IGNORE_SIGNALS, &ignore);
09174 }
09175
09184 void
09185 edt_set_trace_regs(EdtDev *edt_p, u_int reg_def, u_int state)
09186
09187 {
09188
09189 u_int reg_def_mask = (state) ? reg_def | 0x80000000 : reg_def;
09190
09191 edt_ioctl(edt_p, EDTS_TRACE_REG, ®_def_mask);
09192
09193 }
09194
09195
09196
09197
09198
09199 void
09200 edt_trace_regs_enable(EdtDev *edt_p, u_int state)
09201
09202 {
09203 u_int reg_def_mask = (state) ? 1 : 0 ;
09204
09205 edt_ioctl(edt_p, EDTS_TRACE_REG, ®_def_mask);
09206
09207 }
09208
09209 void
09210 edt_set_intr_mask(EdtDev *edt_p, u_int state)
09211
09212 {
09213 edt_ioctl(edt_p, EDTS_INTR_MASK, &state);
09214 }
09215
09216 u_int
09217 edt_get_intr_mask(EdtDev *edt_p)
09218
09219 {
09220 u_int state = 0;
09221 edt_ioctl(edt_p, EDTG_INTR_MASK, &state);
09222 return state;
09223 }
09224
09225 void
09226 edt_set_remote_intr(EdtDev *edt_p, u_int onoff)
09227
09228 {
09229 u_int current;
09230 current = edt_get_intr_mask(edt_p);
09231
09232 current = (current & ~EDT_ICFG_RMT_EN_INTR) ;
09233 current |= (onoff)?EDT_ICFG_RMT_EN_INTR | EDT_ICFG_PCI_EN_INTR:0;
09234
09235 edt_set_intr_mask(edt_p, current);
09236 }
09237
09238 u_int
09239 edt_get_remote_intr(EdtDev *edt_p)
09240
09241 {
09242 return (edt_get_intr_mask(edt_p) & EDT_ICFG_RMT_EN_INTR) != 0;
09243 }
09244
09245
09254 int edt_set_sync_interval(EdtDev *edt_p, u_int interval)
09255
09256 {
09257 edt_ioctl(edt_p, EDTS_SYNC_INTERVAL, &interval);
09258 return 0;
09259 }
09260
09261
09275 int
09276 edt_enable_channels(EdtDev *edt_p, u_int mask)
09277 {
09278
09279 switch (edt_p->devid)
09280 {
09281 case PE8LX32_ID:
09282 case PE8G2V7_ID:
09283 edt_reg_or(edt_p, SSD16_CHEN32, mask);
09284 break;
09285
09286 default:
09287 edt_reg_or(edt_p, SSD16_CHEN, mask);
09288 break;
09289 }
09290
09291 return 0;
09292 }
09293
09294
09308 int
09309 edt_disable_channels(EdtDev *edt_p, u_int mask)
09310 {
09311
09312 switch (edt_p->devid)
09313 {
09314 case PE8LX32_ID:
09315 case PE8G2V7_ID:
09316 edt_reg_and(edt_p, SSD16_CHEN32, ~mask);
09317 break;
09318
09319 default:
09320 edt_reg_and(edt_p, SSD16_CHEN, ~mask);
09321 break;
09322 }
09323
09324
09325 return 0;
09326 }
09327
09341 int
09342 edt_enable_channel(EdtDev *edt_p, u_int channel)
09343 {
09344
09345 u_int enable_bit = 1 << channel;
09346
09347 switch (edt_p->devid)
09348 {
09349 case PE8LX32_ID:
09350 case PE8G2V7_ID:
09351 edt_reg_or(edt_p, SSD16_CHEN32, enable_bit);
09352 break;
09353
09354 default:
09355 edt_reg_or(edt_p, SSD16_CHEN, enable_bit);
09356 break;
09357 }
09358
09359 return 0;
09360 }
09361
09362
09363
09377 int
09378 edt_disable_channel(EdtDev *edt_p, u_int channel)
09379 {
09380
09381 u_int enable_bit = 1 << channel;
09382
09383 switch (edt_p->devid)
09384 {
09385 case PE8LX32_ID:
09386 case PE8G2V7_ID:
09387 edt_reg_and(edt_p, SSD16_CHEN32, ~enable_bit);
09388 break;
09389
09390 default:
09391 edt_reg_and(edt_p, SSD16_CHEN, ~enable_bit);
09392 break;
09393 }
09394
09395 return 0;
09396 }
09397
09415 u_int
09416 edt_bar1_read(EdtDev * edt_p, u_int offset)
09417 {
09418 u_int val;
09419
09420 val = edt_reg_read(edt_p, EDT_BAR1_REGISTER | (offset & 0x0ffffffc));
09421
09422 return val;
09423 }
09424
09444 void
09445 edt_bar1_write(EdtDev * edt_p, u_int offset, u_int data)
09446 {
09447 edt_reg_write(edt_p, EDT_BAR1_REGISTER | (offset & 0x0ffffffc), data);
09448 }
09449
09450
09468 unsigned int
09469 edt_lcr_read(EdtDev *edt_p, unsigned int regBlock, unsigned int regOffset)
09470 {
09471
09472 unsigned int regAddr = LCR_DDC_REG_SPACE | ((regBlock & 0x7F) << 12) | (regOffset & 0xFFF);
09473
09474 return edt_bar1_read(edt_p, regAddr);
09475
09476 }
09477
09478
09479
09499 void
09500 edt_lcr_write(EdtDev *edt_p, unsigned int regBlock, unsigned int regOffset, unsigned int regVal)
09501 {
09502
09503 unsigned int regAddr = LCR_DDC_REG_SPACE | ((regBlock & 0x7F) << 12) | (regOffset & 0xFFF);
09504
09505 edt_bar1_write(edt_p, regAddr, regVal);
09506
09507 }
09508
09509
09514 void
09515 edt_set_port(EdtDev *edt_p, int port)
09516
09517 {
09518 edt_p->port_no = port;
09519 }
09523 int
09524 edt_get_port(EdtDev *edt_p)
09525
09526 {
09527 return edt_p->port_no;
09528 }
09529
09530
09544 uint_t
09545 edt_ind_2_read(EdtDev * edt_p, uint_t desc, u_int *width)
09546 {
09547 int ret;
09548 edt_buf buf = {0, 0};
09549
09550 buf.desc = desc;
09551 if (width)
09552 buf.flags = *width;
09553
09554 ret = edt_ioctl(edt_p, EDTG_IND_2_REG, &buf);
09555 if (ret < 0)
09556 return ret;
09557
09558 if (width)
09559 *width = buf.flags;
09560
09561 return (u_int) buf.value;
09562 }
09563
09577 uint_t
09578 edt_ind_2_write(EdtDev * edt_p, uint_t desc, u_int value, u_int *width)
09579 {
09580 int ret;
09581 edt_buf buf = {0, 0};
09582
09583 buf.desc = desc;
09584 buf.value = value;
09585
09586 if (width)
09587 buf.flags = *width;
09588
09589 ret = edt_ioctl(edt_p, EDTS_IND_2_REG, &buf);
09590 if (ret < 0)
09591 return -1;
09592
09593 if (width)
09594 *width = buf.flags;
09595
09596 return (uint_t) buf.value;
09597
09598 }
09599
09600
09619 #ifdef WIN32
09620 #include <direct.h>
09621 #endif
09622
09623 static char pwd_home[MAXPATH];
09624
09625 const char *edt_home_dir(EdtDev *edt_p)
09626 {
09627
09628 const char *s = edt_envvar_from_devtype(edt_p->devtype);
09629
09630 if (s)
09631 return s;
09632
09633 s = getcwd(pwd_home, MAXPATH-1);
09634 if (!s)
09635 s = ".";
09636 return s;
09637
09638 }
09639
09640 const char *edt_envvar_from_devstr(const char *devstr)
09641 {
09642 const char *s;
09643 if (strcmp(devstr,"pcd") == 0)
09644 if (s = getenv("PCDHOME"))
09645 return s;
09646 if (strcmp(devstr,"pdv") == 0)
09647 if (s = getenv("PDVHOME"))
09648 return s;
09649 if (strcmp(devstr,"p11w") == 0)
09650 if (s = getenv("P11wHOME"))
09651 return s;
09652 if (strcmp(devstr,"p16d") == 0)
09653 if (s = getenv("P16dHOME"))
09654 return s;
09655 if (strcmp(devstr,"p53b") == 0)
09656 if (s = getenv("P53bHOME"))
09657 return s;
09658
09659 return NULL;
09660 }
09661
09662 const char *edt_envvar_from_devtype(const int devtype)
09663 {
09664 const char *s;
09665 const char *ret;
09666
09667 switch (devtype)
09668 {
09669 case pcd:
09670 if (s = getenv("PCDHOME"))
09671 ret = s;
09672 else ret = NULL;
09673 break;
09674 case pdv:
09675 if (s = getenv("PDVHOME"))
09676 ret = s;
09677 else ret = NULL;
09678 break;
09679 case p11w:
09680 if (s = getenv("P11wHOME"))
09681 ret = s;
09682 else ret = NULL;
09683 break;
09684 case p16d:
09685 if (s = getenv("P16dHOME"))
09686 ret = s;
09687 else ret = NULL;
09688 break;
09689 case p53b:
09690 if (s = getenv("P53bHOME"))
09691 ret = s;
09692 else ret = NULL;
09693 break;
09694 default:
09695 ret = NULL;
09696 }
09697 return ret;
09698 }