|
View:
New views
2 Messages
—
Rating Filter:
Alert me
|
|
|
Trouble with copyout, memcpy.... Plain-Text version =)Hey list,
I currently code a driver under Current 8.0 for Current 8.0. But there are some problems with kernel/user-space interaction. I've the following structure: struct daq_kitinfo { uint32_t ki_maxdata; uint32_t ki_flags; uint32_t ki_rng_type; int ki_type; int ki_nchan; int ki_len_chanl; }; The above structure is used in my user-space app: int main(void) { struct daq_kitinfo *info; struct daq_kit kit; int fd, size; ... ... ... /* * At this point I'll try to alloc memory. Notice that * the size i dependet from another struct entry. */ size = sizeof(*info) * kit.k_nkits; info = malloc(size); if (info == NULL) exit(ENOMEM); /* * The next step is to call the drivers ioctl() interface * (the reason for that is described below). */ if (ioctl(fd, DAQ_KITINFO, info)) { printf("errno: %d\n", errno); exit(errno); } printf("[ki_nchan] %d\n", info.ki_nchan); ... ... return (0); } and inside the driver (put it simply): static int my_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flags, struct thread *td) { struct daq_kitinfo *info; struct daq_kit = dev->si_drv1; int size; ... /* Do something useful e.g mutex'ing... */ ... /* The same as in user-space... */ size = sizeof(*info) * kit.k_nkits; info = malloc(sz, M_DAQ, M_NOWAIT | M_ZERO); if (info == NULL) .... /* * Here I want to copy struct info from kernel to user-space. * If i use memcpy, the result is that the system hangs * and I need to reboot the machine. OK, I thought * copyout() should be able to do the job for me... */ if (copyout(info, arg, sz)) /* * Fuc[k-k] i still come inside this block. I always * get an EFAULT error. */ } I really don't know what I should do to let the driver working properly. The driver should grap some informations/attributes, and fill up the info structure, so we can copy the filled info struct to the user's app. I hope somebody can help me to resolve that problem. Ah, the corresponding ioctl is: #define GRP 'd' #define DAQ_KITINFO _IOR(GRP, 3, struct daq_kitinfo) Thanks for attention and greatz from germany MG _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
|
|
Re: Trouble with copyout, memcpy.... Plain-Text version =)Leunam Elebek <forensec@...> writes:
> /* The same as in user-space... */ > size = sizeof(*info) * kit.k_nkits; > info = malloc(sz, M_DAQ, M_NOWAIT | M_ZERO); You shouldn't use M_NOWAIT unless there is absolutely no way around it. > if (info == NULL) > .... Unnecessary if you use M_WAITOK instead of M_NOWAIT. > /* > * Here I want to copy struct info from kernel to user-space. > * If i use memcpy, the result is that the system hangs > * and I need to reboot the machine. OK, I thought > * copyout() should be able to do the job for me... > */ > if (copyout(info, arg, sz)) Nope, ioctl() takes care of the copyin() / copyout(). At this point, arg is a pointer to a malloc()ed buffer of the right size (as specified by the definition of DAQ_KITINFO). > /* > * Fuc[k-k] i still come inside this block. I always > * get an EFAULT error. > */ This means that either a) info doesn't point where you think it does, b) arg doesn't point where you think it does, or c) sz doesn't have the value you think it does. In this case, it's a combination of the latter two: arg points to a kernel buffer, so the use of copyout(9) is inappropriate, but in addition, the size of that buffer is sizeof(daq_kitinfo), and you're trying to copy far more. You need to rethink your interface: either return only one struct daq_kitinfo per ioctl() call, or pass in a struct that contains a pointer to a userland buffer and a length, or use something else than ioctl(2). option 2 would be something like: struct daq_ioctl { struct daq_kitinfo *info; int nkits; }; #define GRP 'd' #define DAQ_KITINFO _IOWR(GRP, 3, struct daq_ioctl) static int my_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flags, struct thread *td) { struct daq_ioctl *di = (struct daq_ioctl *)arg; struct daq_kitinfo *info; struct daq_kit kit; int nkits, ret; /* ... */ nkits = (kit.k_nkits > di->nkits) ? di->nkits : kit.k_nkits; info = malloc(nkits * sizeof(struct daq_kitinfo)) /* ... */ ret = copyout(info, di->info, nkits * sizeof(struct daq_kitinfo)); /* let userland know what it got */ if (ret == 0) di->nkits = nkits; return (ret); } DES -- Dag-Erling Smørgrav - des@... _______________________________________________ freebsd-hackers@... mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@..." |
| Free embeddable forum powered by Nabble | Forum Help |