source: lib/dagapi.c @ b36a3b7

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since b36a3b7 was b36a3b7, checked in by Daniel Lawson <dlawson@…>, 17 years ago

poink

  • Property mode set to 100644
File size: 17.5 KB
Line 
1/*
2 * Copyright (c) 2002 Endace Measurement Systems Ltd, Hamilton, New Zealand.
3 * All rights reserved.
4 *
5 * This source code is proprietary to Endace Measurement Systems and no part
6 * of it may be redistributed, published or disclosed except as outlined in
7 * the written contract supplied with this product.
8 *
9 * $Id$
10 */
11
12# include       <stdio.h>
13# include       <fcntl.h>
14# include       <stdlib.h>
15# include       <unistd.h>
16# include       <errno.h>
17# include       <regex.h>
18# include       <stdarg.h>
19# include       <string.h>
20
21# include       <sys/types.h>
22# include       <sys/wait.h>
23# include       <sys/mman.h>
24# include       <sys/param.h>
25# include       <sys/time.h>
26
27# if 0
28# include       <machine/cpufunc.h>
29# endif
30
31# include       <dagnew.h>
32# include       <dagapi.h>
33# include       <dagtoken.h>
34
35extern void     dagopt_scan_string(const char *);
36extern int      dagoptlex(void);
37extern char     *dagopttext;
38extern int      dagoptlval;
39
40# define        ToHM2           (*(volatile unsigned *)(herd[dagfd].iom+0x08))
41# define        ToHM4           (*(volatile unsigned *)(herd[dagfd].iom+0x10))
42# define        ToAM2           (*(volatile unsigned *)(herd[dagfd].iom+0x48))
43# define        ToAM3           (*(volatile unsigned *)(herd[dagfd].iom+0x4c))
44# define        IOM(OFF)        (*(volatile unsigned *)(herd[dagfd].iom+(OFF)))
45# define        ARMOFFSET(FD)   ({ int _off = ToHM4 - dag_info(FD)->phy_addr; \
46                                        (_off == dag_info(FD)->buf_size) ? 0 : _off; })
47
48# define        CUROFFSET(FD)   ({ int _off = pbm->curaddr - dag_info(FD)->phy_addr; \
49                                        (_off == dag_info(FD)->buf_size) ? 0 : _off; })
50# define        SEGOFFSET(FD)   ({ int _off = pbm->segaddr - dag_info(FD)->phy_addr; \
51                                        (_off == dag_info(FD)->buf_size) ? 0 : _off; })
52# define        PBMOFFSET(FD)   (herd[FD].brokencuraddr ? \
53                                        SEGOFFSET(FD) : CUROFFSET(FD))
54
55/*
56 * Long comment on why this is here and necessary:
57 * There are a number of ambiguities with the wrsafe and curaddr pointers being
58 * the same, in particular, understanding in any given situation whether the
59 * buffer is empty/full from the PBM point of view, or meant to be emptied from
60 * a users point of view. A number of fixes are possible, this one appears to be
61 * the reliable path to address the problem, for the moment.
62 */
63# define        WRSAFE(FD,X)    (((X)<8) ? ((X)+dag_info(FD)->buf_size-8) : ((X)-8))
64
65/*
66 * Need to explain the file descriptor associative array.
67 */
68typedef struct sheep {
69        char            dagname[32];    /* be generous */
70        int             dagiom;         /* XXX cannot be 0 */
71        u_char          *buf;           /* large buffer */
72        u_char          *iom;           /* IO memory pointer */
73        daginf_t        daginf;
74        unsigned        brokencuraddr;  /* fix for ECMs and Dag4.1s */
75        unsigned        byteswap;       /* endinness for 3.4/3.51ecm */
76} sheep_t;
77
78static sheep_t  *herd;                  /* I was going to call this flock, initially */
79
80static void     panic(char *fmt, ...) __attribute__((noreturn, format (printf, 1, 2)));
81
82char *dagpath(char *path, char *temp, int tempsize) {
83       
84        if (!getenv("DAG"))
85                return path;
86        snprintf(temp, tempsize-1, "%s/%s", getenv("DAG"), path);
87        return temp;
88}
89
90int
91dag_open(char *dagname)
92{
93        int     dagfd, i;
94
95        if((dagfd = open(dagname, O_RDWR)) < 0)
96                return dagfd;
97        if(herd == NULL) {
98                int herdsize = sysconf(_SC_OPEN_MAX) * sizeof(sheep_t);
99                herd = malloc(herdsize);
100                if(herd == NULL)
101                        return -1;      /* errno is ENOMEM */
102                memset(herd, 0, herdsize);
103                for( i = 0 ; i < sysconf(_SC_OPEN_MAX) ; i++)
104                        herd[i].dagiom = -1;
105        }
106        if(dagfd >= sysconf(_SC_OPEN_MAX))
107                panic("dagapi: internal error in %s line %u\n", __FILE__, __LINE__);
108        /*
109         * Now fill in the herd structure
110         */
111        strcpy(herd[dagfd].dagname, dagname);
112        if(ioctl(dagfd, DAGIOCINFO, &herd[dagfd].daginf) < 0)
113                return -1;              /* errno set appropriately */
114
115        if((herd[dagfd].dagiom = dag_clone(dagfd, DAGMINOR_IOM)) < 0)
116                panic("dag_open dag_clone dagfd for dagiom: %s\n", strerror(errno));
117
118        if((herd[dagfd].iom = mmap(NULL, 2*PAGE_SIZE, PROT_READ | PROT_WRITE,
119                                        MAP_SHARED, herd[dagfd].dagiom, 0)) == MAP_FAILED)
120                return -1;      /* errno set appropriately */
121
122        return dagfd;
123}
124
125int
126dag_close(int dagfd)
127{
128        (void)close(herd[dagfd].dagiom);
129        memset(&herd[dagfd], 0, sizeof(herd[dagfd]));
130        herd[dagfd].dagiom = -1;
131        return close(dagfd);
132}
133
134/*
135 * This is tentative, could be made an inline function.
136 * Problem is we don't want to make herd public.
137 */
138daginf_t *
139dag_info(int dagfd)
140{
141        return &herd[dagfd].daginf;
142}
143
144u_char *
145dag_iom(int dagfd)
146{
147        return herd[dagfd].iom;
148}
149
150u_char
151dag_linktype(int dagfd)
152{
153        daggpp_t        *gpp = (daggpp_t *)(herd[dagfd].iom +
154                                        dag_info(dagfd)->gpp_base);
155        unsigned char   type;
156
157        type = (gpp->control >> 16) & 0xff;
158        if (type == 0xff)
159                type = TYPE_ETH;
160
161        return type;
162}
163
164static int      spawn(char *cmd, ...);
165
166#define Int_Enables 0x8c
167#define IW_Enable   0x10000
168#define armcode(X) ( (*(int*)(herd[X].iom + Int_Enables) & IW_Enable) || dag_info(X)->soft_caps.code )
169
170int
171dag_configure(int dagfd, char *params)
172{
173        int     lock, tok, setatm;
174        char    temp1[80], temp2[80];
175        daggpp_t        *gpp = (daggpp_t *)(herd[dagfd].iom +
176                                        dag_info(dagfd)->gpp_base);
177
178        /*
179         * We better own this before changing configurations
180         * We might aquire the lock again when starting the
181         * card, which is no harm.
182         */
183        lock = 1;
184        if(ioctl(dagfd, DAGIOCLOCK, &lock) < 0)
185                return -1;      /* errno set */
186
187        /*
188         * Parse input options
189         *
190         * Options are parsed before loading arm code since
191         * arm code loading depends on the options provided.
192         * The ncells options may enable armcode loading, and if so sets
193         * ToAM3 afterwards, since it is volatile on mailbox use.
194         *
195         * It is also possible auto-fpga loading may depend on options
196         * parsed here. If so, needs rearranging since reprogramming the
197         * pp fpga will void the gpp configurations set now.
198         */
199        dagopt_scan_string(params);
200
201        setatm=1; /* default to ncells=1 */
202        while((tok = dagoptlex()) != 0)
203                switch(tok) {
204                  case T_ERROR:
205                        fprintf(stderr, "unknown option '%s'\n", dagopttext);
206                        break;
207                  case T_POS:
208                        break;
209                  case T_ATM:
210                        break;
211                  case T_ATM_NCELLS:
212                        if (dagoptlval)
213                                *(int*)(herd[dagfd].iom + Int_Enables) |= IW_Enable;
214                        else
215                                *(int*)(herd[dagfd].iom + Int_Enables) &= ~IW_Enable;
216                        if (dagoptlval > 15)
217                                panic("ncells set too high (%d), max is 15\n",
218                                      dagoptlval);
219                        setatm &= ~0xffff;
220                        setatm |= dagoptlval;
221                        break;
222                  case T_ATM_LCELL:
223                        if(dagoptlval)
224                                setatm |= 0x20000;
225                        break;
226                  case T_GPP_SLEN:
227                        gpp->snaplen = dagoptlval;
228                        break;
229                  case T_GPP_VARLEN:
230                        if(dagoptlval)
231                                gpp->control |= 1;
232                        else
233                                gpp->control &= ~1;
234                        break;
235                  default:
236                        /* silently ignore unhandled tokens */
237                        if (tok < T_MAX)
238                                break;
239                        /* panic on illegal tokens */
240                        panic("unknown token %u in %s line %u\n", tok, __FILE__, __LINE__);
241                }
242
243        switch(dag_info(dagfd)->device_code) {
244          case 0x3200:
245                if(armcode(dagfd)) {
246                        if(spawn(dagpath("tools/dagrun", temp1, 80), "-d",
247                                        herd[dagfd].dagname,
248                                        dagpath("arm/dag3atm-hash.b",
249                                        temp2, 80), NULL) < 0)
250                                return -1;                             
251                }
252                break;
253          case 0x3500:
254                /*
255                 * XXX might want to load recent images first
256                 * XXX check if DUCK PPS present ?
257                 */
258                /*
259                 * XXX we need to split params and implement an "ignore what
260                 * you don't know" option in dagthree
261                 */
262# if notyet
263                if(execlp(dagpath("tools/dagthree", temp1, 80), "-d", herd[dagfd].dagname, params, NULL) < 0)
264                        return -1;      /* errno set appropriately */
265# endif
266                if(armcode(dagfd)) {
267# ifdef __linux__
268                        if(spawn(dagpath("tools/dagrun", temp1, 80), "-d", herd[dagfd].dagname, dagpath("arm/dag3atm-erf.b", temp2, 80), NULL) < 0)
269                                return -1;                             
270                       
271# else /* FreeBSD */
272                        if(spawn(dagpath("dagld", temp1, 80), "-d", herd[dagfd].dagname, "-r", dagpath("arm/dag3atm-erf.b", temp2, 80), NULL) < 0)
273                                return -1;
274# endif
275                }
276                break;
277                /* normal */
278          case 0x350e:
279          case 0x360d:
280                break;
281                /* byteswapped */
282          case 0x351c:
283                herd[dagfd].byteswap = DAGPBM_BYTESWAP;
284                break;
285                /* byteswapped and ipp */
286          case 0x3400:
287          case 0x340e:
288          case 0x341e:
289                herd[dagfd].byteswap = DAGPBM_BYTESWAP;
290                /* ipp */
291          case 0x4100:
292          case 0x4110:
293                herd[dagfd].brokencuraddr++;
294                break;
295                /* normal */
296          case 0x3800:
297          case 0x4220:
298          case 0x422e:
299          case 0x423e:
300          case 0x4230:
301          case 0x6000:
302          case 0x6100:
303                /*
304                 * XXX might wish to load recent Xilinx image, then reload
305                 */
306                break;
307          default:
308                errno = ENODEV;         /* need to say something */
309                return -1;
310        }
311
312        /* Now we are finished with loading, it's safe to set ARM parameters */
313        if(armcode(dagfd))
314                ToAM3 = setatm;
315
316        return 0;
317}
318
319static int
320spawn(char *cmd, ...)
321{
322        va_list ap;
323        int     i, pid, status;
324        char    *args[16];      /* arbitrarily small */
325
326        switch(pid = fork()) {
327          case -1:      /* error */
328                return -1;      /* errno set appropriately */
329          case 0:       /* child */
330                va_start(ap, cmd);
331                args[0] = cmd;
332                for( i = 1 ; i < 15 ; i++)
333                        if((args[i] = va_arg(ap, char *)) == NULL)
334                                break;
335                args[i] = NULL;
336                for( i = 0 ; i < 15 ; i++ ) {
337                        if(args[i] == NULL) {
338                                break;
339                        }
340                }
341
342                va_end(ap);
343                execvp(cmd, args);
344                panic("execvp %s failed: %s\n", cmd, strerror(errno));
345          default:      /* parent */
346                if(wait(&status) != pid)
347                        return -1;
348                if(!WIFEXITED(status))
349                        return -1;
350                if(WEXITSTATUS(status) != 0)
351                        return -1;
352                break;
353        }
354        return 0;
355}
356
357extern int      dag32start(int dagfd);
358extern int      dag32stop(int dagfd);
359extern int      dag35start(int dagfd);
360extern int      dag35stop(int dagfd);
361extern int      dag42start(int dagfd);
362extern int      dag42stop(int dagfd);
363
364int
365dag_start(int dagfd)
366{
367        int     lock;
368
369        lock = 1;
370        if(ioctl(dagfd, DAGIOCLOCK, &lock) < 0)
371                return -1;      /* errno set */
372
373        memset(herd[dagfd].buf, 0, dag_info(dagfd)->buf_size);
374
375        switch(dag_info(dagfd)->device_code) {
376          case 0x3200:
377                return dag32start(dagfd);
378          case 0x3500:
379          case 0x360d:
380                return dag35start(dagfd);
381          case 0x3400:
382          case 0x340e:
383          case 0x341e:
384          case 0x351c:
385          case 0x350e:
386          case 0x3800:
387          case 0x4100:
388          case 0x4110:
389          case 0x4220:
390          case 0x422e:
391          case 0x423e:
392          case 0x4230:
393          case 0x6000:
394          case 0x6100:
395                return dag42start(dagfd);
396          default:
397                errno = ENODEV;         /* need to say something */
398                return -1;
399        }
400}
401
402int
403dag_stop(int dagfd)
404{
405        int     lock;
406        int     error = 0;
407
408        switch(dag_info(dagfd)->device_code) {
409          case 0x3200:
410                error = dag32stop(dagfd);
411                break;
412          case 0x3500:
413          case 0x360d:
414                error = dag35stop(dagfd);
415                break;
416          case 0x3400:
417          case 0x340e:
418          case 0x341e:
419          case 0x351c:
420          case 0x350e:
421          case 0x3800:
422          case 0x4100:
423          case 0x4110:
424          case 0x4220:
425          case 0x422e:
426          case 0x423e:
427          case 0x4230:
428          case 0x6000:
429          case 0x6100:
430                error = dag42stop(dagfd);
431                break;
432          default:
433                errno = ENODEV;         /* need to say something */
434                error = -1;
435        }
436
437        lock = 0; /* unlock */
438        if(ioctl(dagfd, DAGIOCLOCK, &lock) < 0) 
439                error = -1;             /* errno set accordingly */
440        return error;
441}
442
443void *
444dag_mmap(int dagfd)
445{
446        void            *sp, *p, *ep;
447        daginf_t        *dip;
448
449        dip = dag_info(dagfd);
450        /*
451         * Start off with a fake mapping to allocate contiguous virtual
452         * address space in one lot for twice the size of the memory buffer,
453         * then map in the two copies via the dag device driver.
454         * This saves us (for the momemt) the costs of rewriting parts of
455         * the device driver, which would be an alternative solution to the
456         * problem.
457         */
458        if((sp = mmap(NULL, 2*dip->buf_size, PROT_READ | PROT_WRITE,
459                        MAP_ANON|MAP_SHARED, -1, 0)) == MAP_FAILED)
460                return MAP_FAILED;
461        /*
462         * Now map the real buffer, 1st round.
463         */
464        if((p = mmap(sp, dip->buf_size, PROT_READ | PROT_WRITE,
465                        MAP_FIXED|MAP_SHARED, dagfd, 0)) == MAP_FAILED)
466                return MAP_FAILED;
467        /*
468         * Map the buffer for a second time, this will turn out to be a neat
469         * feature for handling data records crossing the wrap around the
470         * top of the memory buffer.
471         */
472        if((ep = mmap(sp+dip->buf_size, dip->buf_size, PROT_READ|PROT_WRITE,
473                        MAP_FIXED|MAP_SHARED, dagfd, 0)) == MAP_FAILED)
474                return MAP_FAILED;
475        herd[dagfd].buf = p;
476        return p;
477}
478
479/*
480 * XXX should probably made card or feature specific.
481 * XXX should the next two be merged ? Blocking/non-blocking ?
482 */
483int
484dag_offset(int dagfd, int *oldoffset, int flags)
485{
486        dagpbm_t        *pbm = (dagpbm_t *)(herd[dagfd].iom +
487                                        dag_info(dagfd)->pbm_base);
488        int             offset;
489
490        /*
491         * The implementation implies that offsets within
492         * the buffer are now starting zero to top of the
493         * hole, exclusive the top address, which is considered
494         * zero.
495         */
496        if(*oldoffset >= dag_info(dagfd)->buf_size)
497                *oldoffset -= dag_info(dagfd)->buf_size;
498
499        if(dag_info(dagfd)->soft_caps.pbm) {
500                /*
501                 * Advance acknowledgement pointer, this should be done in
502                 * all cases, blocking or non-blocking.
503                 * Reinit the burst manager, in case safety net was reached
504                 * XXX we might consider reporting safety net status ?
505                 */
506                pbm->wrsafe = dag_info(dagfd)->phy_addr + WRSAFE(dagfd, *oldoffset);
507                pbm->cs = (DAGPBM_AUTOWRAP|herd[dagfd].byteswap);
508                /*
509                 * With the WRSAFE() macro in place, if offset equals oldoffset,
510                 * the buffer is guaranteed to be empty.
511                 */
512                offset = PBMOFFSET(dagfd);
513                while(offset == *oldoffset) {
514                        if (flags & DAGF_NONBLOCK)
515                                return offset;
516                        usleep(1);
517                        offset = PBMOFFSET(dagfd);
518                }
519        } else {
520                offset = ARMOFFSET(dagfd);
521                while(offset == *oldoffset) {
522                        if (flags & DAGF_NONBLOCK)
523                                return offset;
524                        usleep(1);
525                        offset = ARMOFFSET(dagfd);
526                }
527        }
528
529        if(offset > dag_info(dagfd)->buf_size)
530                panic("dagapi: dag_offset internal error offset=0x%x\n", offset);
531
532        if(offset < *oldoffset)
533                offset += dag_info(dagfd)->buf_size;
534
535        return offset;
536}
537
538void *
539dag_nextpkt(void *curpkt, void *buf, int bufsize)
540{
541
542        return 0;
543}
544
545/*
546 * XXX this shall be moved to a different file later
547 */
548int
549dag32start(int dagfd)
550{
551        if(armcode(dagfd)) {
552                ToAM2 = 0;                      /* clear command register */
553
554                while(ToHM2 != 1) {
555                        usleep(1);
556                        if(ToHM2 == 2)
557                                break;          /* protocol bug */
558                }
559
560                ToAM2 = 1;                      /* command: run */
561
562                while(ToHM2 != 2)
563                        usleep(1);
564        }
565
566        return 0;
567}
568
569int
570dag32stop(int dagfd)
571{
572        int     loop = 100, retval=0;
573
574        if(armcode(dagfd)) {
575                ToAM2 = 2;                      /* stop command */
576
577                while(--loop > 0) {
578                        usleep(10*1000); /* give ARM a chance to settle */
579                        if(ToHM2 == 3)
580                                break;
581                }
582                retval = (ToHM2 == 3) ? 0 : -1; /* XXX need to set errno */
583        }
584        return retval;
585}
586
587int
588dag35start(int dagfd)
589{
590        dagpbm_t        *pbm = (dagpbm_t *)(herd[dagfd].iom +
591                                        dag_info(dagfd)->pbm_base);
592
593        /*
594         * XXX make sure the DUCK is in sync, if needed
595         */
596        if(dag_info(dagfd)->soft_caps.pbm) {
597                pbm->cs = (DAGPBM_PAUSED | DAGPBM_SAFETY);
598                while (pbm->cs & DAGPBM_REQPEND)
599                        usleep(1);
600
601                IOM(0x88)  |= (1<<31);          /* L2RESET, will auto deassert */
602
603                pbm->bursttmo = 0xffff;
604                pbm->memaddr = dag_info(dagfd)->phy_addr; /* XXX curaddr bugfix */
605                pbm->memsize = dag_info(dagfd)->buf_size;
606                pbm->segsize = (1024*1024);     /* paranoia, not that it matters */
607                pbm->wrsafe = dag_info(dagfd)->phy_addr + WRSAFE(dagfd, dag_info(dagfd)->buf_size);
608                pbm->cs = (DAGPBM_SYNCL2R|DAGPBM_AUTOWRAP|herd[dagfd].byteswap);
609
610                IOM(0x88)  |= (1<<31);          /* L2RESET, will auto deassert */
611
612        }
613
614        if(armcode(dagfd)) {
615                usleep(1); /* seems necessary to let pbm settle? */
616                IOM(0x404) |=  (1<<23);         /* framer now held in reset */
617                IOM(0x88)  |= (1<<31);          /* L2RESET, will auto deassert */
618
619                ToAM2 = 0;                      /* clear command register */
620
621                while(ToHM2 != 1) {
622                        usleep(1);
623                        if(ToHM2 == 2)
624                                break;          /* protocol bug */
625                }
626
627                ToAM2 = 1;                      /* command: run */
628
629                while(ToHM2 != 2)
630                        usleep(1);
631                IOM(0x404) &= ~(1<<23);         /* deassert framer reset */
632        }
633
634        return 0;
635}
636
637int
638dag35stop(int dagfd)
639{
640        dagpbm_t        *pbm = (dagpbm_t *)(herd[dagfd].iom +
641                                        dag_info(dagfd)->pbm_base);
642        int     loop = 100, retval=0;
643
644        if(armcode(dagfd)) {
645                ToAM2 = 2;                      /* stop command */
646
647                while(--loop > 0) {
648                        usleep(10*1000); /* give ARM a chance to settle */
649                        if(ToHM2 == 3)
650                                break;
651                }
652                retval = (ToHM2 == 3) ? 0 : -1; /* XXX need to set errno */
653        }
654        if(dag_info(dagfd)->soft_caps.pbm) {
655                pbm->cs = (DAGPBM_PAUSED);
656
657                while(--loop > 0) {
658                        if(!(pbm->cs & DAGPBM_REQPEND))
659                                break;
660                        usleep(10*1000);
661                }
662                retval += (pbm->cs & DAGPBM_REQPEND) ? -1 : 0;
663        }
664        return retval;
665}
666
667int
668dag42start(int dagfd)
669{
670        dagpbm_t        *pbm = (dagpbm_t *)(herd[dagfd].iom +
671                                        dag_info(dagfd)->pbm_base);
672
673        pbm->cs = (DAGPBM_PAUSED | DAGPBM_SAFETY);
674        while (pbm->cs & DAGPBM_REQPEND)
675                usleep(1);
676
677        IOM(0x88)  |= (1<<31);          /* L2RESET, will auto deassert */
678
679        pbm->bursttmo = 0xffff;
680        pbm->memaddr = dag_info(dagfd)->phy_addr; /* XXX curaddr bugfix */
681        pbm->memsize = dag_info(dagfd)->buf_size;
682        pbm->segsize = (1024*1024);     /* paranoia, not that it matters */
683        pbm->wrsafe = dag_info(dagfd)->phy_addr + WRSAFE(dagfd, dag_info(dagfd)->buf_size);
684        pbm->cs = (DAGPBM_SYNCL2R|DAGPBM_AUTOWRAP|herd[dagfd].byteswap);
685
686        IOM(0x88)  |= (1<<31);          /* L2RESET, will auto deassert */
687
688        return 0;
689}
690
691int
692dag42stop(int dagfd)
693{
694        dagpbm_t        *pbm = (dagpbm_t *)(herd[dagfd].iom +
695                                        dag_info(dagfd)->pbm_base);
696        int             loop = 100;
697
698        pbm->cs = (DAGPBM_PAUSED);
699
700        while(--loop > 0) {
701                if(!(pbm->cs & DAGPBM_REQPEND))
702                        break;
703                usleep(10*1000);
704        }
705
706        return 0;
707}
708
709/*
710 * I wish there was a better way, by means of a clone ioctl() in the
711 * kernel, but it appears to be more difficult and also OS specific,
712 * so here is the second best and also portable version.
713 */
714int
715dag_clone(int dagfd, int minor)
716{
717        regex_t         reg;
718        regmatch_t      match;
719        char            buf[16];
720        char            *fmt[DAGMINOR_MAX] = {
721                                "/dev/dag%c",           /* DAGMINOR_DAG */
722                                "/dev/dagmem%c",        /* DAGMINOR_MEM */
723                                "/dev/dagiom%c",        /* DAGMINOR_IOM */
724                                "/dev/dagarm%c",        /* DAGMINOR_ARM */
725                                "/dev/dagram%c",        /* DAGMINOR_RAM */
726                        };
727        int             r;
728
729        if(minor >= DAGMINOR_MAX) {
730                errno = EDOM;
731                return -1;
732        }
733        if(regcomp(&reg, "/dev/dag(iom|mem|arm|ram)*[0-9]", REG_EXTENDED) != 0) {
734                errno = EDOM;   /* grrrk */
735                return -1;
736        }
737        if((r = regexec(&reg, herd[dagfd].dagname, 1, &match, 0)) !=0) {
738                errno = EDOM;  /* grrrk */
739                return -1;
740        }
741        (void)sprintf(buf, fmt[minor], herd[dagfd].dagname[match.rm_eo-1]);
742        regfree(&reg);
743
744        return open(buf, O_RDWR);
745}
746
747static void
748panic(char *fmt, ...)
749{
750        va_list ap;
751
752        (void)fprintf(stderr, "daglib: panic: ");
753        va_start(ap, fmt);
754        (void)vfprintf(stderr, fmt, ap);
755        va_end(ap);
756        exit(1);
757}
758
Note: See TracBrowser for help on using the repository browser.