RE: (no subject)
>> #define DEVICE2SOFTC(device) ((struct dev_softc >> *)device_get_softc(device)) >> >> static void dev_intr(void *arg); >> >> struct dev_softc { >> ... >> int rid_irq; >> struct resource* res_irq; >> void *intr_cookie; >> ... >> }; >> >> static int >> dev_attach(device_t device) >> { >> ... >> >> dev_sc->rid_irq = 0; >> dev_sc->res_irq = bus_alloc_resource_any(device, SYS_RES_IRQ, >> &(dev_sc->rid_irq), >> RF_SHAREABLE|RF_ACTIVE); >> if (dev_sc->res_irq == NULL) >> { >> uprintf("!!! Could not map interrupt !!!\n"); >> goto fail; >> } >> >> if (bus_setup_intr(device, dev_sc->res_irq, INTR_TYPE_TTY, >> dev_intr, dev_sc, &dev_sc->intr_cookie)) >> { >> uprintf("!!! Could not setup irq !!!\n"); >> goto fail; >> } >> >> ... >> >> fail: >> return ENXIO; >> } >> >> static int >> dev_detach(device_t device) >> { >> struct dev_softc *dev_sc = DEVICE2SOFTC(device); >> >> destroy_dev(dev_sc->device); >> >> if (bus_teardown_intr(device, dev_sc->res_irq, >> dev_sc->intr_cookie) != 0); > > Do you see that semicolon? > > >Norbert > > Oops... I am ashamed for my inattention... Thank you very much... ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"
bus_teardown_intr()
Sorry, I forgot to indicate the theme. >Hello. >Help me please to understand how the function bus_teardown_intr() works. >I have a device driver containing following code: > >#define DEVICE2SOFTC(device) ((struct dev_softc *)device_get_softc(device)) > >static void dev_intr(void *arg); > >struct dev_softc { > ... > int rid_irq; > struct resource* res_irq; > void *intr_cookie; > ... >}; > >static int >dev_attach(device_t device) >{ > ... > > dev_sc->rid_irq = 0; > dev_sc->res_irq = bus_alloc_resource_any(device, SYS_RES_IRQ, > &(dev_sc->rid_irq), RF_SHAREABLE|RF_ACTIVE); > if (dev_sc->res_irq == NULL) > { >uprintf("!!! Could not map interrupt !!!\n"); >goto fail; > } > > if (bus_setup_intr(device, dev_sc->res_irq, INTR_TYPE_TTY, > dev_intr, dev_sc, &dev_sc->intr_cookie)) > { >uprintf("!!! Could not setup irq !!!\n"); >goto fail; > } > > ... > >fail: > return ENXIO; >} > >static int >dev_detach(device_t device) >{ > struct dev_softc *dev_sc = DEVICE2SOFTC(device); > > destroy_dev(dev_sc->device); > > if (bus_teardown_intr(device, dev_sc->res_irq, dev_sc->intr_cookie) != 0); >printf("bus_teardown_intr ERROR !!!\n"); > > bus_release_resource(device, SYS_RES_IRQ, dev_sc->rid_irq, >dev_sc->res_irq); > ... > > return 0; >} > >static void >dev_intr(void *arg) >{ > struct dev_softc *dev_sc = (struct dev_softc *)arg; > > ... >} > >When the driver is loaded the following message is shown: > >dev0 port 0x9800-0x980f,0x9400-0x947f irq 16 at device 10.0 on pci1 > >i.e., as I understand, resourses are allocated normally. > >But when the driver is being unloaded the following message appear: > >bus_teardown_intr ERROR !!! > >What have I done wrong? Hint me please how to use bus_teardown_intr() >function correctly? >___ >freebsd-hackers@freebsd.org mailing list >http://lists.freebsd.org/mailman/listinfo/freebsd-hackers >To unsubscribe, send any mail to "[EMAIL PROTECTED]" -- Яндекс.Лента - любимые блоги и новости на одном сайте http://lenta.yandex.ru/ ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"
(no subject)
Hello. Help me please to understand how the function bus_teardown_intr() works. I have a device driver containing following code: #define DEVICE2SOFTC(device) ((struct dev_softc *)device_get_softc(device)) static void dev_intr(void *arg); struct dev_softc { ... int rid_irq; struct resource* res_irq; void *intr_cookie; ... }; static int dev_attach(device_t device) { ... dev_sc->rid_irq = 0; dev_sc->res_irq = bus_alloc_resource_any(device, SYS_RES_IRQ, &(dev_sc->rid_irq), RF_SHAREABLE|RF_ACTIVE); if (dev_sc->res_irq == NULL) { uprintf("!!! Could not map interrupt !!!\n"); goto fail; } if (bus_setup_intr(device, dev_sc->res_irq, INTR_TYPE_TTY, dev_intr, dev_sc, &dev_sc->intr_cookie)) { uprintf("!!! Could not setup irq !!!\n"); goto fail; } ... fail: return ENXIO; } static int dev_detach(device_t device) { struct dev_softc *dev_sc = DEVICE2SOFTC(device); destroy_dev(dev_sc->device); if (bus_teardown_intr(device, dev_sc->res_irq, dev_sc->intr_cookie) != 0); printf("bus_teardown_intr ERROR !!!\n"); bus_release_resource(device, SYS_RES_IRQ, dev_sc->rid_irq, dev_sc->res_irq); ... return 0; } static void dev_intr(void *arg) { struct dev_softc *dev_sc = (struct dev_softc *)arg; ... } When the driver is loaded the following message is shown: dev0 port 0x9800-0x980f,0x9400-0x947f irq 16 at device 10.0 on pci1 i.e., as I understand, resourses are allocated normally. But when the driver is being unloaded the following message appear: bus_teardown_intr ERROR !!! What have I done wrong? Hint me please how to use bus_teardown_intr() function correctly? ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"
RE: how to use the function copyout()
> I think that could work (only an idea, not tested): > > > struct Region > { > void * p; > size_t s; > }; > > > #define IOBIG _IOWR ('b', 123, struct Region) > > > userland: > > char data[1000]; > struct Region r; > > r.p = data; > r.s = sizeof data; > int error = ioctl (fd, IOBIG, &r); > > > kernel: > int my_ioctl(..., caddr_t data, ...) > { > ... > char data[1000]; > ... > return copyout(data, ((struct Region *) data)->p, ((struct Region *) > data)->s); > } > > > Have a try and tell us if it works. > > > Norbert > Yes! Now the program works! I have changed the code in this way: struct Region { void * p; size_t s; }; #define IOBIG _IOWR ('b', 123, struct Region) driver struct my_softc { ... short unsigned int B; }; ... static int my_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) { struct my_softc *my_sc; int unit, error; unit = minor(dev); my_sc = (struct my_softc *)devclass_get_softc(my_devclass, unit); if (my_sc == NULL) return (ENXIO); switch(cmd) { ... case IOCTL_GET_B: error = copyout(&my_sc->B, (((struct Datas *)data)->d)+0x1850, sizeof(my_sc->B)); break; default: break; } return 0; } ---user program -- ... short unsigned int data[32768]; struct Region r; int main(int argc, char *argv[]) { ... r.p = data; r.s = sizeof data; if (ioctl(fd0, IOCTL_GET_B, &r) == -1) err(1, "IOCTL_GET_B"); ... } Now I have access to each element of the array (e.g. 0x1850). Thank you very much! ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"
RE: how to use the function copyout()
>> #define IOCTL_GET_B_IOWR("F", 127, 0x4) > >I think the third parameter to _IOWR should directly specify a type, >e.g. _IOWR("F", 127, int) or _IOWR("F", 127, struct MyStruct). > >> >> driver >> >> struct my_softc { >> ... >> short unsigned int B; >> }; >> >> ... >> >> static int >> my_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, >>struct thread *td) >> { >> struct my_softc *my_sc; >> int unit, error; >> unit = minor(dev); >> my_sc = (struct my_softc *)devclass_get_softc(my_devclass, unit); >> if (my_sc == NULL) >>return (ENXIO); >> switch(cmd) >> { >>... >>case IOCTL_GET_B: >> error = copyout(&my_sc->B, data, sizeof(my_sc->B)); >> switch (error) >> { >>case 0: >> printf(" IOCTL_GET_B: %d\n", my_sc->B); >> break; >>case EFAULT: >> printf("EFAULT\n"); >> break; >>case EIO: >> printf("EIO\n"); >> break; >>case ENOMEM: >> printf("ENOMEM\n"); >> break; >>case ENOSPC: >> printf("ENOSPC\n"); >> break; >> } >> break; >> default: >> break; >> } >> return 0; >> } >> >> ---user program -- >> >> ... >> >> short unsigned int Data[32768]; >> >> int >> main(int argc, char *argv[]) >> { ... >> >> if (ioctl(fd0, IOCTL_GET_B, Data) == -1) >>err(1, "IOCTL_GET_B"); >> >> ... >> } >> >> --- >> >> Here I get EFAULT. >> >> What have I done wrong? How can I do it correctly? > >The caddr_t data in your ioctl is already mapped into kernel >memory. Look into the source of other device drivers. You'll >find a lot of *(int *) data = ... >So your copyout() has to fail because it tries to address >memory which is not a part of your application's >memory. >>From errno(2): EFAULT: Bad address... > >I have no idea if it is possible for ioctls to have mapped more >than a few 100 bytes for data exchange. >You should use read and uiomove() instead. So if I get it right, it's impossible in FreeBSD to gain access to 64KB of user's program memory with ioctl? My situation is this - I have a device driver for Linux. My task is port it as it is (1:1) into FreeBSD. In the Linux driver Ioctl is realized with the macroses _put_user _get_user all over it. As I understand in FreeBSD their analogues are functions described in store(9), copy(9) and fetch(9). So the problem is that in my user program an array short unsigned int Data[32768] is defined. I need to gain access to the array(to each element of it) from device driver with Ioctl handler. Is it possible to do? If yes, then how it can be done? > >Norbert >___ >freebsd-hackers@freebsd.org mailing list >http://lists.freebsd.org/mailman/listinfo/freebsd-hackers >To unsubscribe, send any mail to "[EMAIL PROTECTED]" -- Где Яндекс.Деньги - там хорошие скидки http://money.yandex.ru/discount/ ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"
how to use the function copyout()
I can't understand how to use the function copyout(). It is necessary to write the data from a device driver to the array defined in user program. I do it this way: #define IOCTL_GET_B_IOWR("F", 127, 0x4) driver struct my_softc { ... short unsigned int B; }; ... static int my_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) { struct my_softc *my_sc; int unit, error; unit = minor(dev); my_sc = (struct my_softc *)devclass_get_softc(my_devclass, unit); if (my_sc == NULL) return (ENXIO); switch(cmd) { ... case IOCTL_GET_B: error = copyout(&my_sc->B, data, sizeof(my_sc->B)); switch (error) { case 0: printf(" IOCTL_GET_B: %d\n", my_sc->B); break; case EFAULT: printf("EFAULT\n"); break; case EIO: printf("EIO\n"); break; case ENOMEM: printf("ENOMEM\n"); break; case ENOSPC: printf("ENOSPC\n"); break; } break; default: break; } return 0; } ---user program -- ... short unsigned int Data[32768]; int main(int argc, char *argv[]) { ... if (ioctl(fd0, IOCTL_GET_B, Data) == -1) err(1, "IOCTL_GET_B"); ... } --- Here I get EFAULT. What have I done wrong? How can I do it correctly? ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"