00001
00002
00003
00004 #include "edtinc.h"
00005
00006 #if defined(__linux__) || defined(__APPLE__)
00007 #include <unistd.h>
00008 #include <sys/mman.h>
00009 #include <sys/time.h>
00010 #include <sys/resource.h>
00011 #endif
00012
00013 #include <stdlib.h>
00014 #include <ctype.h>
00015
00016 #ifndef _NT_
00017 #include <sys/ioctl.h>
00018 #endif
00019
00020 #ifdef VXWORKS
00021 #include "vmLib.h"
00022 #include "cacheLib.h"
00023 extern int sysGetVmPageSize();
00024 #endif
00025
00026 #ifdef _NT_
00027
00028 #include <process.h>
00029
00030 #else
00031
00032 #ifndef VXWORKS
00033 #include <sys/errno.h>
00034 #endif
00035
00036 #endif
00037
00038 #ifdef __sun
00039 #include <thread.h>
00040 #endif
00041 #ifdef __sun
00042 #include <sys/mman.h>
00043 #endif
00044 #ifdef __sun
00045 #include <sys/priocntl.h>
00046 #include <sys/rtpriocntl.h>
00047 #include <sys/tspriocntl.h>
00048 #endif
00049
00050 #if defined(_NT_)
00051 #include <process.h>
00052 #elif defined(__sun) || defined(__linux__) || defined(__APPLE__)
00053 #include <sys/wait.h>
00054 #endif
00055
00056
00057 #ifndef PAGE_SHIFT
00058 #define PAGE_SHIFT (12)
00059 #endif
00060
00061 #ifndef PAGE_SIZE
00062 #define PAGE_SIZE (1UL << PAGE_SHIFT)
00063 #endif
00064
00065 #ifndef PAGE_MASK
00066 #define PAGE_MASK (PAGE_SIZE-1)
00067 #endif
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 static u_int dmy_started = 0 ;
00085
00086
00087 int dump_reg_access = 0;
00088
00089 void edt_set_dump_reg_access(int on)
00090
00091 {
00092 dump_reg_access = on;
00093 }
00094
00095 #ifndef _NT_
00096
00097 extern int errno;
00098
00099 static void
00100 edt_set_errno(int val)
00101
00102 {
00103 errno = val;
00104 }
00105
00106 #else
00107
00108 #define edt_set_errno(val)
00109
00110 #endif
00111
00112
00113
00114 int edt_clear_wait_status(EdtDev *edt_p);
00115
00116 #ifndef SECTOR_SIZE
00117 #define SECTOR_SIZE 512
00118 #endif
00119
00120 #ifndef PAGESIZE
00121 #define PAGESIZE 4096
00122 #endif
00123
00124 #define DEFAULT_BUFFER_GRANULARITY PAGESIZE
00125 #define MINHEADERSIZE SECTOR_SIZE
00126
00127 #define EDTDEBUG EDTLIB_MSG_INFO_2
00128 #define EDTFATAL EDTLIB_MSG_FATAL
00129 #define EDTWARN EDTLIB_MSG_WARNING
00130
00131 #if defined(__APPLE__)
00132 void *edt_mac_open(char *classname, int unit, int channel);
00133 void *edt_mac_ioctl(void *dataPort, int code, void *eis);
00134 #endif
00135
00136 #ifdef _NT_
00137 static u_int WINAPI
00138 edt_wait_event_thread(void *);
00139
00140 int
00141 edt_get_kernel_event(EdtDev *edt_p, int event_num);
00142 static
00143 void
00144 edt_clear_event_func(EdtEventHandler * p);
00145
00146 #else
00147 static void *
00148 edt_wait_event_thread(void *);
00149
00150 #endif
00151
00152 static char *BaseEventNames[] =
00153 {
00154 NULL,
00155 EDT_EODMA_EVENT_NAME,
00156 EDT_BUF_EVENT_NAME,
00157 EDT_STAT_EVENT_NAME,
00158 EDT_P16D_DINT_EVENT_NAME,
00159 EDT_P11W_ATTN_EVENT_NAME,
00160 EDT_P11W_CNT_EVENT_NAME,
00161 EDT_PDV_ACQUIRE_EVENT_NAME,
00162 EDT_EVENT_PCD_STAT1_NAME,
00163 EDT_EVENT_PCD_STAT2_NAME,
00164 EDT_EVENT_PCD_STAT3_NAME,
00165 EDT_EVENT_PCD_STAT4_NAME,
00166 EDT_PDV_STROBE_EVENT_NAME,
00167 EDT_EVENT_P53B_SRQ_NAME,
00168 EDT_EVENT_P53B_INTERVAL_NAME,
00169 EDT_EVENT_P53B_MODECODE_NAME,
00170 EDT_EVENT_P53B_DONE_NAME,
00171 EDT_PDV_EVENT_FVAL_NAME,
00172 EDT_PDV_EVENT_TRIGINT_NAME,
00173 EDT_EVENT_TEMP_NAME,
00174 NULL
00175 };
00176
00177 #ifdef USB
00178
00186 u_int
00187 usb_reg_read (EdtDev *edt_p, u_int desc)
00188 {
00189 int i, addr;
00190 u_int retval = 0 ;
00191 unsigned char setup[3];
00192 unsigned char buf[5];
00193 int bytes;
00194
00195 if (usb_claim_interface(edt_p->usb_p, 0) < 0)
00196 {
00197 edt_set_errno(EBUSY); ;
00198 return 0 ;
00199 }
00200
00201 addr = EDT_REG_ADDR(desc) ;
00202
00203 for (i = 0; i < EDT_REG_SIZE(desc); i++)
00204 {
00205 setup[0] = 0x03 ;
00206 setup[1] = addr ;
00207
00208
00209 if ((usb_bulk_write(edt_p->usb_p, 0x01, setup, 2,
00210 edt_p->usb_rtimeout)) < 0)
00211 {
00212 usb_release_interface(edt_p->usb_p, 0);
00213 edt_set_errno(EINVAL); ;
00214 return 0 ;
00215 }
00216
00217
00218 bytes = usb_bulk_read(edt_p->usb_p, 0x81, buf, 1, edt_p->usb_rtimeout);
00219
00220 if (bytes < 1)
00221 {
00222 extern int errno ;
00223 usb_release_interface(edt_p->usb_p, 0);
00224 edt_set_errno(EINVAL); ;
00225 return 0 ;
00226 }
00227
00228 ++addr ;
00229 retval |= ((u_int) buf[0] << (i * 8)) ;
00230 }
00231
00232 usb_release_interface(edt_p->usb_p, 0);
00233
00234 return retval ;
00235 }
00236
00244 void
00245 usb_reg_write(EdtDev *edt_p, u_int desc, u_int value)
00246 {
00247 int i, addr, size;
00248 unsigned char setup[4];
00249 unsigned char buf[4];
00250
00251 if (usb_claim_interface(edt_p->usb_p, 0) < 0)
00252 {
00253 edt_set_errno(EBUSY); ;
00254 return ;
00255 }
00256
00257 addr = EDT_REG_ADDR(desc) ;
00258
00259 for (i = 0; i < EDT_REG_SIZE(desc); i++)
00260 {
00261 if (EDT_REG_TYPE(desc) == REMOTE_USB_TYPE)
00262 {
00263 setup[0] = 0x04;
00264 setup[1] = addr ;
00265 setup[2] = value & 0xff ;
00266 size = 3 ;
00267 }
00268 else if (EDT_REG_TYPE(desc) == LOCAL_USB_TYPE)
00269 {
00270 setup[0] = 0x01;
00271 setup[1] = value & 0xff ;
00272 size = 2 ;
00273 }
00274
00275
00276 if ((usb_bulk_write(edt_p->usb_p, 0x01, setup, size,
00277 edt_p->usb_wtimeout)) < 0)
00278 {
00279 usb_release_interface(edt_p->usb_p, 0);
00280 edt_set_errno(EINVAL); ;
00281 return ;
00282 }
00283
00284 addr++ ;
00285 value >>= 8 ;
00286 }
00287
00288 usb_release_interface(edt_p->usb_p, 0);
00289 }
00290
00291
00292
00293
00294
00295 struct usb_device *edt_find_usb_board(int unit)
00296 {
00297 struct usb_bus *p;
00298 struct usb_device *q;
00299
00300 for (p = usb_busses; p; p = p->next)
00301 {
00302 q = p->devices;
00303 while(q)
00304 {
00305 if ((q->descriptor.idVendor==0x04b4) &&
00306 (q->descriptor.idProduct=0x8613))
00307 return q;
00308 else
00309 q = q->next;
00310 }
00311 }
00312
00313 return NULL;
00314 }
00315 #endif
00316
00317 int edt_driver_type = -1;
00318
00319 static int edt_parse_devname(EdtDev *edt_p, char *edt_devname, int unit, int channel);
00320
00321
00322 EdtDev *edt_open_device(char *device_name, int unit, int channel, int verbose)
00323
00324 {
00325 EdtDev *edt_p;
00326 static char *debug_env = NULL;
00327 u_int dmy;
00328 int edt_debug;
00329 static char *debug_file = NULL;
00330 int level;
00331
00332 if ((debug_env == NULL)
00333 && ((debug_env = (char *) getenv("EDTDEBUG")) != NULL)
00334 && *debug_env != '0')
00335 {
00336 edt_debug = atoi(debug_env);
00337 level = edt_msg_default_level();
00338 if (edt_debug > 0)
00339 {
00340 level |= EDTLIB_MSG_INFO_1;
00341 level |= EDTLIB_MSG_INFO_2;
00342 }
00343 edt_msg_set_level(edt_msg_default_handle(), level);
00344
00345 if ((debug_file == NULL)
00346 && ((debug_file = (char *) getenv("EDTDEBUGFILE")) != NULL)
00347 && *debug_file != '0')
00348 {
00349 edt_msg_set_name(edt_msg_default_handle(), debug_file);
00350 }
00351
00352 edt_msg(EDTDEBUG, "environment DEBUG set to %d: enabling debug in edtlib\n", edt_debug);
00353 }
00354
00355 if ((edt_p = (EdtDev *) calloc(1, sizeof(EdtDev))) == NULL)
00356 {
00357 char errstr[128];
00358 sprintf(errstr, "edtlib: malloc (%lx) in edt_open failed\n", sizeof(EdtDev));
00359 edt_msg_perror(EDTWARN, errstr);
00360 return (NULL);
00361 }
00362
00363 if(verbose)
00364 edt_msg(EDTDEBUG, "edt_open_device(%s, %d)\n", device_name, unit);
00365
00366 if ((strncmp(device_name, "dmy", 3) == 0) || (strncmp(device_name, "DMY", 3) == 0))
00367 edt_p->devid = DMY_ID;
00368 #ifdef USB
00369 else if (strncasecmp(device_name, "usb", 3) == 0)
00370 edt_p->devtype = USB_ID;
00371 #endif
00372
00373
00374 if (edt_parse_devname(edt_p, device_name, unit, channel) != 0)
00375 {
00376 edt_msg(EDTFATAL, "Illegal EDT device name (edt_open_device): %s\n", device_name);
00377 return NULL;
00378 }
00379
00380 edt_p->unit_no = unit;
00381 edt_p->channel_no = channel;
00382
00383 #ifdef USB
00384 if (edt_p->devtype == USB_ID)
00385 {
00386 struct usb_device *current_device = NULL;
00387
00388 usb_init();
00389 usb_find_busses();
00390 usb_find_devices();
00391
00392 current_device = edt_find_usb_board(unit);
00393
00394 if(current_device==NULL)
00395 {
00396 edt_set_errno(ENODEV); ;
00397 return NULL;
00398 }
00399
00400 edt_p->usb_p = usb_open(current_device);
00401
00402
00403
00404
00405
00406
00407
00408 edt_p->usb_bulk_read_endpoint = 0x80 + (channel * 2) + 2 ;
00409 edt_p->usb_bulk_write_endpoint = (channel * 2) + 2 ;
00410
00411 }
00412 else
00413 #endif
00414 {
00415
00416 #ifdef _NT_
00417 edt_p->fd = CreateFile(edt_p->edt_devname,
00418 GENERIC_READ | GENERIC_WRITE,
00419 FILE_SHARE_READ | FILE_SHARE_WRITE,
00420 NULL,
00421 edt_p->devid == (DMY_ID) ? OPEN_ALWAYS
00422 : OPEN_EXISTING,
00423 FILE_ATTRIBUTE_NORMAL,
00424 NULL);
00425
00426 if (edt_p->fd == INVALID_HANDLE_VALUE)
00427 {
00428 if (verbose)
00429 edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", device_name);
00430
00431 return (NULL);
00432 }
00433 #else
00434 #if defined (__APPLE__)
00435
00436 if (verbose)
00437 edt_msg(EDTWARN, "edt_devname %s unit %d channel %d\n",edt_p->edt_devname,unit,channel) ;
00438 if (edt_p->devid != DMY_ID)
00439 {
00440 if ((edt_p->fd = edt_mac_open(edt_p->edt_devname, unit, channel)) <= 0 )
00441 {
00442 if (verbose)
00443 edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", edt_p->edt_devname);
00444 return (NULL);
00445 }
00446 {
00447 edt_ioctl(edt_p, EDTG_DEVID, &edt_p->devid);
00448 if (edt_is_pdv(edt_p))
00449 {
00450 if (strncmp(device_name, "pdv", 3) != 0)
00451 {
00452 if (verbose)
00453 printf("%s not match for pdv\n",edt_p->edt_devname) ;
00454 close(edt_p->fd) ;
00455 return(NULL);
00456 }
00457 }
00458 else if (edt_is_pcd(edt_p))
00459 {
00460 if (strncmp(device_name, "pcd", 3) != 0)
00461 {
00462 if (verbose)
00463 printf("%s not match for pcd\n",edt_p->edt_devname) ;
00464 close(edt_p->fd) ;
00465 return(NULL);
00466 }
00467 }
00468 }
00469 }
00470 else
00471 {
00472 if (!edt_p->fd)
00473 {
00474 if ((edt_p->fd = open(edt_p->edt_devname, O_RDWR|O_CREAT, 0666)) < 0 )
00475 {
00476 if (verbose)
00477 edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", edt_p->edt_devname);
00478 return (NULL);
00479 }
00480 }
00481
00482 }
00483 #else
00484
00485 if ((edt_p->fd = open(edt_p->edt_devname, O_RDWR, 0666)) < 0 )
00486 {
00487 if (verbose)
00488 edt_msg(EDTWARN, "EDT %s open failed.\nCheck board installation and unit number, and try restarting the computer\n", edt_p->edt_devname);
00489 return (NULL);
00490 }
00491
00492 #if defined( __linux__) || defined(__sun)
00493 fcntl(edt_p->fd, F_SETFD, FD_CLOEXEC);
00494 #endif
00495
00496 #endif
00497 #endif
00498 }
00499
00500
00501
00502 edt_msg(EDTDEBUG, "edt_open for %s unit %d succeeded\n", device_name, unit);
00503
00504 if (edt_p->devid != DMY_ID)
00505 {
00506 edt_ioctl(edt_p, EDTG_DEVID, &edt_p->devid);
00507 edt_ioctl(edt_p, EDTS_RESETCOUNT, &dmy);
00508 dmy = edt_p->foi_unit ;
00509 edt_ioctl(edt_p, EDTS_RESETSERIAL, &dmy);
00510
00511 #ifdef _NT_
00512 edt_get_kernel_event(edt_p, EDT_EVENT_BUF);
00513 edt_get_kernel_event(edt_p, EDT_EVENT_STAT);
00514 if (edt_p->devid == P53B_ID)
00515 {
00516 edt_get_kernel_event(edt_p, EDT_EVENT_P53B_SRQ);
00517 edt_get_kernel_event(edt_p, EDT_EVENT_P53B_INTERVAL);
00518 edt_get_kernel_event(edt_p, EDT_EVENT_P53B_MODECODE);
00519 edt_get_kernel_event(edt_p, EDT_EVENT_P53B_DONE);
00520 }
00521 #endif
00522 }
00523
00524 edt_p->donecount = 0;
00525 edt_p->tmpbuf = 0;
00526 edt_p->dd_p = 0;
00527 edt_p->b_count = 0;
00528 edt_p->buffer_granularity = DEFAULT_BUFFER_GRANULARITY;
00529 edt_p->mezz.id = MEZZ_ID_UNKNOWN;
00530
00531 edt_driver_type = edt_get_drivertype(edt_p);
00532
00533 return edt_p;
00534 }
00535
00536
00560 EdtDev *
00561 edt_open(char *device_name, int unit)
00562 {
00563
00564 return edt_open_device(device_name, unit, 0, 1);
00565 }
00566
00567
00581 EdtDev *
00582 edt_open_quiet(char *device_name, int unit)
00583 {
00584 return edt_open_device(device_name, unit, 0, 0);
00585 }
00586
00614 EdtDev *
00615 edt_open_channel(char *device_name, int unit, int channel)
00616 {
00617 return edt_open_device(device_name, unit, channel, 1);
00618 }
00619
00628 static int
00629 edt_parse_devname(EdtDev *edt_p, char *device_name, int unit, int channel)
00630 {
00631
00632 char *format;
00633
00634 char dev_string[512];
00635
00636 if (!device_name)
00637 return -1;
00638
00639 if (device_name[0] == '\\' || device_name[0] == '/')
00640 {
00641 strcpy(edt_p->edt_devname, device_name);
00642 }
00643 else if (edt_p->devid == DMY_ID)
00644 {
00645 #ifdef _NT_
00646 format = ".\\%s%d" ;
00647 #else
00648 format = "./%s%d" ;
00649 #endif
00650 (void) sprintf(edt_p->edt_devname, format, device_name, unit) ;
00651 }
00652 else
00653 {
00654 int i;
00655
00656 strncpy(dev_string, device_name,511);
00657
00658 for (i=0;dev_string[i]; i++)
00659 dev_string[i] = tolower(dev_string[i]);
00660
00661 #ifdef _NT_
00662 dev_string[0] = toupper(dev_string[0]);
00663 #endif
00664
00665 #if defined(__linux__)
00666 if (strcmp(dev_string, "pcd") == 0)
00667 strcpy(dev_string, "pcicd");
00668 #endif
00669
00670
00671 #ifdef _NT_
00672 if (channel > 0)
00673 {
00674 format = "\\\\.\\%s%d_%d";
00675 }
00676 else
00677 {
00678 format = "\\\\.\\%s%d";
00679 }
00680 #else
00681 if (channel > 0)
00682 {
00683 format = "/dev/%s%d_%d";
00684 }
00685 else
00686 {
00687 format = "/dev/%s%d";
00688 }
00689 #endif
00690 (void) sprintf(edt_p->edt_devname, format, dev_string, unit, channel);
00691
00692 }
00693 edt_msg(EDTDEBUG, "parse open to %s\n",edt_p->edt_devname) ;
00694
00695 return 0;
00696 }
00697
00708 int
00709 edt_close(EdtDev *edt_p)
00710
00711 {
00712 u_int i;
00713 #ifdef __sun
00714 EdtEventHandler *p;
00715 #endif
00716
00717 edt_msg(EDTDEBUG, "edt_close()\n");
00718
00719 for (i = 0; i < EDT_MAX_KERNEL_EVENTS; i++)
00720 {
00721
00722
00723 #ifdef __sun
00724 p = &edt_p->event_funcs[i];
00725 if (p->active)
00726 {
00727 p->active = 0;
00728
00729 edt_ioctl(p->owner, EDTS_DEL_EVENT_FUNC, &i);
00730 edt_ioctl(p->owner, EDTS_CLR_EVENT, &i);
00731 sema_destroy(&p->sema_thread);
00732 thr_join(NULL, NULL, NULL);
00733 }
00734 #else
00735 #ifndef NO_PTHREAD
00736
00737 edt_remove_event_func(edt_p, i);
00738 #endif
00739 #endif
00740 }
00741
00742 if (edt_p->ring_buffers_configured)
00743 edt_disable_ring_buffers(edt_p);
00744
00745 if (edt_p->fd)
00746 {
00747 #ifdef _NT_
00748 CloseHandle(edt_p->fd);
00749 #else
00750 #if defined (__APPLE__)
00751 edt_mac_close(edt_p->fd) ;
00752 #else
00753 close(edt_p->fd);
00754 #endif
00755 #endif
00756 }
00757 free(edt_p);
00758
00759 return 0;
00760 }
00761
00773 unsigned char *
00774 edt_alloc(int size)
00775 {
00776 unsigned char *ret;
00777
00778 #ifdef _NT_
00779 ret = (unsigned char *)
00780 VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
00781 #else
00782 #if defined(AV3_BOARD) || defined(XCALIBURCOMMON)
00783 ret = (unsigned char *) edt_vmalloc(size);
00784 #else
00785 ret = (unsigned char *) valloc(size);
00786 #if defined(__linux__) || defined(sgi) || defined(VXWORKS)
00787 if (ret)
00788 {
00789 u_char *tmp_p;
00790
00791 for (tmp_p = ret; tmp_p < ret + size; tmp_p += 4096)
00792 {
00793
00794 *tmp_p = 0xa5;
00795 }
00796 }
00797 #endif
00798 #endif
00799
00800 #endif
00801 return (ret);
00802 }
00803
00812 void
00813 edt_free(uchar_t *ptr)
00814 {
00815 #ifdef _NT_
00816 VirtualFree(ptr, 0, MEM_RELEASE);
00817 #else
00818 #if defined(AV3_BOARD) || defined(XCALIBURCOMMON)
00819 edt_vfree(ptr);
00820 #else
00821 free(ptr);
00822 #endif
00823 #endif
00824 }
00825
00826
00827 #ifdef __sun
00828
00829 typedef struct
00830 {
00831 uint_t index;
00832 uint_t writeflag;
00833 EdtDev *edt_p;
00834 } thr_buf_args;
00835
00836 static void *
00837 aio_thread( void *arg)
00838
00839 {
00840 thr_buf_args *bufp = (thr_buf_args *) arg;
00841 int ret;
00842 u_char *addr;
00843 uint_t size;
00844 int index;
00845 EdtDev *edt_p;
00846 extern int errno;
00847
00848 edt_p = bufp->edt_p;
00849 index = bufp->index;
00850 addr = edt_p->ring_buffers[index];
00851 size = edt_p->rb_control[index].size;
00852
00853
00854
00855
00856
00857
00858 edt_msg(EDTDEBUG, "start %s for %d addr %x\n",
00859 bufp->writeflag ? "write" : "read", index, (u_int) addr);
00860 edt_set_errno(0);;
00861 if (bufp->writeflag)
00862 ret = pwrite(edt_p->fd, addr, size, index * 512);
00863 else
00864 ret = pread(edt_p->fd, addr, size, index * 512);
00865 if (ret == -1)
00866 {
00867 char errstr[128];
00868
00869 if (errno)
00870 perror("pread");
00871 sprintf(errstr, "aio buffer %d at 0x%x", index, (u_int) addr);
00872 edt_msg_perror(EDTDEBUG, errstr);
00873 edt_msg_perror(EDTDEBUG, "aiothread\n");
00874 }
00875 edt_msg(EDTDEBUG, "end aiothread for %d\n", index);
00876 return (0);
00877 }
00878
00879 #endif
00880
00888 int
00889 edt_use_umem_lock(EdtDev *edt_p, u_int use_lock)
00890 {
00891 int ret = 0 ;
00892 if (edt_p->ring_buffers_configured)
00893 {
00894 printf("Can't change umem lock method when ring buffers active\n") ;
00895 return(1) ;
00896 }
00897 edt_msg(EDTDEBUG, "use umem lock %d ",use_lock) ;
00898 ret = edt_ioctl(edt_p, EDTS_UMEM_LOCK, &use_lock) ;
00899 edt_msg(EDTDEBUG, "returns %d\n",ret) ;
00900 if (ret)
00901 {
00902 edt_msg(EDTDEBUG,
00903 "Can't use Umem lock expect on solaris 2.8 or above\n") ;
00904 }
00905 else
00906 {
00907 edt_msg(EDTDEBUG,"Setting umem lock\n") ;
00908 }
00909 return(ret) ;
00910 }
00911
00912 int
00913 edt_get_umem_lock(EdtDev *edt_p)
00914 {
00915 u_int using_lock ;
00916 edt_ioctl(edt_p, EDTG_UMEM_LOCK, &using_lock) ;
00917 edt_msg(EDTDEBUG,"Using lock returns %d\n",using_lock) ;
00918 return(using_lock) ;
00919 }
00920
00931 int
00932 edt_get_numbufs(EdtDev *edt_p)
00933
00934 {
00935 int nb = 0;
00936 edt_ioctl(edt_p, EDTG_NUMBUFS, &nb);
00937 return nb;
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955 static int
00956 edt_configure_ring_buffer(EdtDev * edt_p,
00957 int index,
00958 int bufsize,
00959 int write_flag,
00960 unsigned char *pdata)
00961
00962 {
00963 buf_args sysargs;
00964 int allocated_size = bufsize;
00965 EdtRingBuffer *pring;
00966 int rc;
00967
00968 if (index < 0 || index >= MAX_DMA_BUFFERS)
00969 {
00970 edt_set_errno(EINVAL);
00971
00972 fprintf(stderr,
00973 "invalid buffer index %d < 0 or >= MAX_DMA_BUFFERS (%d)\n",
00974 index, MAX_DMA_BUFFERS);
00975 return -1;
00976 }
00977
00978 pring = &edt_p->rb_control[index];
00979
00980
00981
00982 pring->size = bufsize;
00983 pring->write_flag = write_flag;
00984
00985 if (pdata || (edt_p->mmap_buffers))
00986 {
00987 pring->owned = FALSE;
00988 }
00989 else
00990 {
00991 #ifdef _NT_
00992
00993 if (allocated_size & (SECTOR_SIZE-1))
00994 allocated_size = ((allocated_size / SECTOR_SIZE)+1)* SECTOR_SIZE;
00995 #endif
00996 pdata =
00997 edt_alloc(allocated_size);
00998 pring->owned = TRUE;
00999 }
01000
01001 pring->allocated_size = allocated_size;
01002
01003 edt_p->ring_buffers[index] = pdata;
01004
01005 sysargs.index = index;
01006 sysargs.writeflag = write_flag;
01007 #ifdef WIN32
01008 sysargs.addr = (uint64_t) (pdata);
01009 #else
01010 sysargs.addr = (uint64_t) ((unsigned long)pdata);
01011 #endif
01012
01013 sysargs.size = bufsize;
01014 #ifdef __hpux
01015 bzero(sysargs.addr,sysargs.size) ;
01016 #endif
01017
01018 if (edt_p->mmap_buffers)
01019 {
01020 if ((rc = edt_ioctl(edt_p, EDTS_BUF_MMAP, &sysargs)) == 0)
01021 {
01022 #ifdef __sun
01023 int using_lock = 0 ;
01024 int count;
01025 thr_buf_args bufargs;
01026
01027 using_lock = edt_get_umem_lock(edt_p) ;
01028
01029 if (!using_lock)
01030 {
01031 bufargs.edt_p = edt_p;
01032 bufargs.index = index;
01033 bufargs.writeflag = write_flag;
01034
01035 edt_msg(EDTDEBUG, "%d buffer thread\n", index);
01036 if (thr_create(NULL, 0,
01037 aio_thread,
01038 (void *) &bufargs, THR_BOUND,
01039 &pring->ring_tid))
01040 {
01041 edt_msg_perror(EDTWARN, "thr_create");
01042 }
01043 }
01044 count = index + 1;
01045
01046 edt_msg(EDTDEBUG, "Before WAITN");
01047 edt_ioctl(edt_p, EDTS_WAITN, &count);
01048 edt_msg(EDTDEBUG, "After WAITN");
01049 #endif
01050 return 0;
01051
01052 }
01053 else
01054 {
01055 edt_msg(EDT_MSG_FATAL, "Unable to configure ring buffer\n");
01056 edt_msg(EDT_MSG_FATAL, "rc = %d\n", rc);
01057 return rc;
01058 }
01059 }
01060 else if (edt_ioctl(edt_p, EDTS_BUF, &sysargs) == 0)
01061 {
01062 #ifdef __sun
01063 int using_lock = 0 ;
01064 int count;
01065 thr_buf_args bufargs;
01066
01067 using_lock = edt_get_umem_lock(edt_p) ;
01068
01069 if (!using_lock)
01070 {
01071 bufargs.edt_p = edt_p;
01072 bufargs.index = index;
01073 bufargs.writeflag = write_flag;
01074
01075 edt_msg(EDTDEBUG, "%d buffer thread\n", index);
01076 if (thr_create(NULL, 0,
01077 aio_thread,
01078 (void *) &bufargs, THR_BOUND,
01079 &pring->ring_tid))
01080 {
01081 edt_msg_perror(EDTWARN, "thr_create");
01082 }
01083 count = index + 1;
01084
01085 edt_msg(EDTDEBUG, "Before WAITN");
01086 edt_ioctl(edt_p, EDTS_WAITN, &count);
01087 edt_msg(EDTDEBUG, "After WAITN");
01088 }
01089 #endif
01090 return 0;
01091 }
01092 return (-1);
01093 }
01094
01095
01096
01097
01098
01099
01100 int
01101 edt_add_ring_buffer(EdtDev * edt_p,
01102 unsigned int bufsize,
01103 int write_flag,
01104 void *pdata)
01105 {
01106
01107 int index = -1;
01108
01109 int i;
01110
01111 if (!edt_p->mmap_buffers)
01112 {
01113
01114
01115
01116 for (i = 0; i < MAX_DMA_BUFFERS; i++)
01117 if (edt_p->ring_buffers[i] == NULL)
01118 break;
01119
01120 if (i == MAX_DMA_BUFFERS)
01121 return -1;
01122
01123 index = i;
01124
01125 edt_p->ring_buffer_numbufs++;
01126
01127 edt_ioctl(edt_p, EDTS_NUMBUFS, &edt_p->ring_buffer_numbufs);
01128
01129 edt_configure_ring_buffer(edt_p, index, bufsize, write_flag, pdata);
01130 }
01131
01132 return index;
01133 }
01134
01135
01136
01137
01138
01139
01140
01141
01142 int
01143 edt_configure_channel_ring_buffers(EdtDev *edt_p, int bufsize, int numbufs,
01144 int write_flag, unsigned char **bufarray)
01145 {
01146 return edt_configure_ring_buffers(edt_p, bufsize, numbufs,
01147 write_flag, bufarray) ;
01148 }
01149
01150 static
01151 int edt_check_ring_buf_parms(EdtDev *edt_p, int numbufs, int bufsize,
01152 unsigned char *pdata, unsigned char ** bufarray)
01153
01154 {
01155
01156 int maxbufs;
01157
01158 if (!edt_p)
01159 {
01160 edt_msg_perror(EDTFATAL, "Invalid edt handle\n");
01161 return -1;
01162 }
01163
01164
01165
01166 if (bufsize & 0x01)
01167 {
01168 edt_set_errno(EINVAL); ;
01169
01170 edt_msg_perror(EDTFATAL, "edt_configure_ring_buffers: bufsize must be an even number of bytes\n") ;
01171 return -1 ;
01172 }
01173 maxbufs = edt_get_max_buffers(edt_p) ;
01174 if (numbufs > maxbufs)
01175 {
01176
01177 edt_set_errno(EINVAL); ;
01178
01179 edt_msg_perror(EDTFATAL,
01180 "edt_configure_ring_buffers: number of bufs exceeds maximum\n") ;
01181 edt_msg_perror(EDTFATAL,
01182 "use edt_set_max_buffers to increase max\n") ;
01183 return -1 ;
01184 }
01185
01186 edt_p->mmap_buffers = edt_get_mmap_buffers(edt_p);
01187
01188 if (edt_p->mmap_buffers)
01189 {
01190 if (edt_p->buffer_granularity < PAGE_SIZE)
01191 edt_p->buffer_granularity = PAGE_SIZE;
01192
01193 }
01194
01195 if (edt_p->mmap_buffers && ((pdata != NULL) || (bufarray != NULL)))
01196 {
01197
01198 edt_set_errno(EINVAL); ;
01199
01200 edt_msg_perror(EDTFATAL,
01201 "edt_configure_ring_buffers: can't pass in user pointer when using mmap kernel buffers\n") ;
01202
01203 return -1;
01204 }
01205
01206 return 0;
01207 }
01208
01209 #define EDT_DMAMEM_OFFSET 0x10000000
01210
01211 int
01212 edt_unmap_dmamem(EdtDev *edt_p)
01213 {
01214
01215 #ifdef __linux__
01216
01217 if (edt_p->base_buffer)
01218 munmap(edt_p->base_buffer, edt_p->totalsize);
01219
01220 #endif
01221
01222 return 0;
01223 }
01224
01225 caddr_t
01226 edt_map_dmamem(EdtDev *edt_p)
01227 {
01228
01229 caddr_t ret = NULL;
01230 int pagen = EDT_DMAMEM_OFFSET;
01231
01232
01233 #ifdef __linux__
01234
01235 ret = (caddr_t) mmap((caddr_t)0, edt_p->totalsize, PROT_READ|PROT_WRITE,
01236 MAP_SHARED, edt_p->fd, pagen);
01237 #endif
01238
01239
01240 if (ret == ((caddr_t)-1)) {
01241 perror("mmap call");
01242 return(0) ;
01243 }
01244
01245 return(ret) ;
01246 }
01247
01248 static int
01249 edt_allocate_ring_buffer_memory(EdtDev *edt_p, int bufsize, int numbufs, u_char *user_mem, u_char **buffers)
01250
01251 {
01252
01253 unsigned char * bp;
01254 int i;
01255
01256 edt_p->fullbufsize = edt_get_total_bufsize(edt_p, bufsize, edt_p->header_size);
01257
01258 edt_p->totalsize = edt_p->fullbufsize * numbufs;
01259
01260 if (edt_p->mmap_buffers)
01261 {
01262
01263 for (i=0;i<numbufs;i++)
01264 buffers[i] = NULL;
01265
01266 return 0;
01267 }
01268
01269 if (edt_p->base_buffer)
01270 {
01271 edt_free(edt_p->base_buffer);
01272 edt_p->base_buffer = NULL;
01273 }
01274
01275 if (user_mem)
01276 {
01277 bp = user_mem;
01278 }
01279 else
01280 {
01281
01282
01283 edt_p->ring_buffers_allocated = TRUE;
01284 edt_p->base_buffer = edt_alloc(edt_p->totalsize);
01285
01286 if (!edt_p->base_buffer)
01287 {
01288 edt_msg_perror(EDTFATAL, "Unable to allocate buffer memory\n");
01289 return -1;
01290 }
01291
01292 bp = edt_p->base_buffer;
01293
01294
01295 }
01296
01297 if (edt_p->header_size < 0)
01298 bp += -((int) edt_p->header_size);
01299
01300 for (i=0;i<numbufs;i++)
01301 {
01302 buffers[i] = bp;
01303 bp += edt_p->fullbufsize;
01304 }
01305
01306
01307 return 0;
01308
01309 }
01310
01311
01312 static int
01313 edt_setup_ring_buffers(EdtDev *edt_p, int bufsize, int numbufs,
01314 int write_flag, unsigned char *pdata, unsigned char **bufarray)
01315 {
01316 int i;
01317 int rc;
01318
01319 u_char *localbuf[MAX_DMA_BUFFERS];
01320 u_char ** buffers;
01321
01322 buffers = (bufarray != NULL)?bufarray:localbuf;
01323
01324 if ((rc = edt_check_ring_buf_parms(edt_p, numbufs, bufsize, pdata, bufarray)) != 0)
01325 return rc;
01326
01327 if (edt_p->ring_buffers_configured)
01328 edt_disable_ring_buffers(edt_p);
01329
01330 edt_p->nextwbuf = 0;
01331 edt_p->donecount = 0;
01332 edt_p->ring_buffer_bufsize = bufsize;
01333 edt_p->ring_buffer_numbufs = numbufs;
01334
01335 if (write_flag)
01336 edt_set_direction(edt_p, EDT_WRITE);
01337 else
01338 edt_set_direction(edt_p, EDT_READ);
01339
01340 edt_p->write_flag = write_flag;
01341
01342 edt_ioctl(edt_p, EDTS_NUMBUFS, &numbufs);
01343
01344 if (bufarray == NULL)
01345 {
01346 edt_allocate_ring_buffer_memory(edt_p, bufsize, numbufs, pdata, buffers);
01347
01348 edt_p->ring_buffers_allocated = !edt_p->mmap_buffers && (pdata == NULL);
01349 }
01350
01351 for (i = 0; i < numbufs; i++)
01352 {
01353 if (edt_configure_ring_buffer(edt_p, i,
01354 bufsize,
01355 write_flag,
01356 buffers[i]) == 0)
01357 {
01358
01359 }
01360 else
01361 {
01362 return -1;
01363 }
01364
01365 #ifdef __hpux
01366 edt_dmasync_fordev(edt_p, i, 0, 0) ;
01367 #endif
01368
01369 }
01370
01371
01372 #if defined(__hpux)
01373 {
01374 int pret ;
01375
01376 pret = plock(PROCSHLIBLOCK) ;
01377 }
01378 #elif defined(sgi)
01379 mlockall(MCL_FUTURE);
01380 #endif
01381
01382 if (edt_p->mmap_buffers)
01383 {
01384 u_char *bp;
01385
01386 edt_p->base_buffer = (u_char *) edt_map_dmamem(edt_p);
01387 bp = edt_p->base_buffer;
01388
01389 for (i=0;i<numbufs;i++)
01390 {
01391 edt_p->ring_buffers[i] = bp;
01392 bp += edt_p->fullbufsize;
01393 }
01394
01395
01396 bp = edt_p->base_buffer;
01397 for (i=0; i<(int)edt_p->totalsize;i += PAGE_SIZE)
01398 bp[i] = 0x5a;
01399
01400
01401 }
01402
01403 edt_p->ring_buffers_configured = 1;
01404
01405 return 0;
01406 }
01407
01408
01409
01410 void edt_set_buffer_granularity(EdtDev *edt_p, u_int granularity)
01411
01412 {
01413 edt_p->buffer_granularity = granularity;
01414 }
01415
01416
01427 int
01428 edt_get_total_bufsize(EdtDev *edt_p,
01429 int bufsize,
01430 int header_size)
01431
01432 {
01433 int fullbufsize;
01434
01435 fullbufsize = header_size + bufsize;
01436
01437 if (edt_p->buffer_granularity)
01438 if (fullbufsize % edt_p->buffer_granularity)
01439 fullbufsize = ((fullbufsize / edt_p->buffer_granularity)+1)* edt_p->buffer_granularity;
01440
01441 return fullbufsize;
01442 }
01443
01444
01483 int
01484 edt_configure_ring_buffers(EdtDev *edt_p, int bufsize, int numbufs,
01485 int write_flag, unsigned char **bufarray)
01486 {
01487 return edt_setup_ring_buffers(edt_p, bufsize, numbufs, write_flag, NULL, bufarray);
01488
01489 }
01490
01501 int
01502 edt_configure_block_buffers_mem(EdtDev *edt_p,
01503 int bufsize,
01504 int numbufs,
01505 int write_flag,
01506 int header_size,
01507 int header_before,
01508 u_char *user_mem)
01509
01510 {
01511
01512
01513 if (header_before && header_size)
01514 {
01515 if (header_size & (SECTOR_SIZE-1))
01516 header_size = ((header_size / SECTOR_SIZE)+1)* SECTOR_SIZE;
01517 }
01518
01519
01520 edt_p->header_size = header_size;
01521 edt_p->header_offset = (header_before)? -header_size : bufsize;
01522
01523
01524 return edt_setup_ring_buffers(edt_p, bufsize, numbufs, write_flag, user_mem, NULL);
01525
01526 }
01527
01528
01563 int
01564 edt_configure_block_buffers(EdtDev *edt_p, int bufsize, int numbufs, int write_flag,
01565 int header_size, int header_before)
01566
01567 {
01568
01569 return edt_configure_block_buffers_mem(edt_p,
01570 bufsize,
01571 numbufs,
01572 write_flag,
01573 header_size,
01574 header_before,
01575 NULL);
01576
01577 }
01578
01579
01593 int
01594 edt_disable_ring_buffer(EdtDev *edt_p,
01595 int whichone)
01596
01597 {
01598 if (edt_p->ring_buffers[whichone])
01599 {
01600
01601
01602 edt_ioctl(edt_p, EDTS_FREEBUF, &whichone);
01603 edt_msg(EDTDEBUG, "free buf %d\n", whichone);
01604
01605 #ifdef __sun
01606 {
01607 u_int using_lock ;
01608 using_lock = edt_get_umem_lock(edt_p) ;
01609 if (!using_lock)
01610 {
01611 edt_msg(EDTDEBUG, "joining user buf %d tid %x\n",
01612 whichone, edt_p->rb_control[whichone].ring_tid);
01613 thr_join(edt_p->rb_control[whichone].ring_tid, NULL, NULL);
01614
01615 edt_msg(EDTDEBUG, "join user buf %d done\n", whichone);
01616 }
01617 }
01618 #endif
01619
01620 if (edt_p->rb_control[whichone].owned)
01621 {
01622 edt_msg(EDTDEBUG, "free user buf %d\n", whichone);
01623 edt_free(edt_p->ring_buffers[whichone]);
01624 }
01625
01626 edt_p->ring_buffers[whichone] = NULL;
01627
01628 }
01629 #if defined(__hpux)
01630 {
01631 int pret ;
01632 pret = plock(UNLOCK) ;
01633 }
01634 #endif
01635
01636 return 0;
01637
01638 }
01639
01640
01652 int
01653 edt_disable_ring_buffers(EdtDev *edt_p)
01654
01655 {
01656 int i;
01657
01658
01659 for (i = edt_p->ring_buffer_numbufs - 1; i >= 0 ; i--)
01660 {
01661 edt_disable_ring_buffer(edt_p,i);
01662 }
01663
01664 edt_p->ring_buffers_configured = 0;
01665 edt_p->ring_buffers_allocated = 0;
01666 #if defined(__hpux)
01667 {
01668 int pret ;
01669 pret = plock(UNLOCK) ;
01670 }
01671 #elif defined(sgi)
01672 munlockall();
01673 #endif
01674
01675 if (edt_p->base_buffer )
01676 {
01677
01678 if (edt_p->mmap_buffers)
01679 edt_unmap_dmamem(edt_p);
01680 else
01681 edt_free(edt_p->base_buffer);
01682 edt_p->base_buffer = NULL;
01683 }
01684
01685
01686 {
01687 int one = 1;
01688 edt_p->ring_buffer_numbufs = 0;
01689 edt_ioctl(edt_p, EDTS_NUMBUFS, &one);
01690 edt_ioctl(edt_p, EDTS_CLEAR_DMAID, &one);
01691 }
01692
01693 return 0;
01694 }
01695
01710 int
01711 edt_start_buffers(EdtDev *edt_p, uint_t count)
01712 {
01713 if (edt_p->devid == DMY_ID && edt_p->dd_p)
01714 dmy_started += count ;
01715 edt_msg(EDTDEBUG, "edt_start_buffers %d\n", count);
01716 edt_ioctl(edt_p, EDTS_STARTBUF, &count);
01717 return 0;
01718 }
01719
01720
01721 int
01722 edt_lockoff(EdtDev * edt_p)
01723 {
01724 int count = 0;
01725
01726 edt_ioctl(edt_p, EDTS_STARTBUF, &count);
01727 return 0;
01728 }
01729
01739 unsigned int
01740 edt_allocated_size(EdtDev *edt_p, int buffer)
01741
01742 {
01743 if (buffer >= 0 && buffer < (int) edt_p->ring_buffer_numbufs)
01744 {
01745 return edt_p->rb_control[buffer].allocated_size;
01746 }
01747 return 0;
01748 }
01749
01771 int
01772 edt_set_buffer(EdtDev *edt_p, uint_t bufnum)
01773 {
01774 edt_ioctl(edt_p, EDTS_SETBUF, &bufnum);
01775 edt_p->donecount = bufnum;
01776 if (edt_p->ring_buffer_numbufs)
01777 edt_p->nextwbuf = bufnum % edt_p->ring_buffer_numbufs;
01778 return 0;
01779 }
01780
01801 int
01802 edt_read(EdtDev *edt_p,
01803 void *buf,
01804 uint_t size)
01805 {
01806 int retval;
01807
01808 #ifdef USB
01809 if (edt_p->devtype == USB_ID)
01810 {
01811 if (usb_claim_interface(edt_p->usb_p, 0) < 0)
01812 {
01813 edt_set_errno(EBUSY); ;
01814 return -1 ;
01815 }
01816
01817 retval = usb_bulk_read(edt_p->usb_p, edt_p->usb_bulk_read_endpoint,
01818 buf, size, edt_p->usb_rtimeout);
01819
01820 usb_release_interface(edt_p->usb_p, 0);
01821 }
01822 else
01823 #endif
01824 {
01825
01826 #ifdef _NT_
01827 uint_t Length;
01828 #endif
01829
01830 if (size & 0x01)
01831 -- size ;
01832
01833 if (edt_p->last_direction != 1)
01834 edt_set_direction(edt_p, EDT_READ);
01835 #ifdef _NT_
01836 if ((retval = ReadFile(edt_p->fd, buf, size, &Length, NULL)) == 0)
01837 edt_msg_perror(EDTFATAL, "edt_read:ReadFile");
01838 retval = Length;
01839