Salut,
en ayant marre de la libusb, dont la version BSD ne supporte pas les
appels reset ou clear_halt, je suis en train d'écrire un pilote pour les
appareils numériques travaillant avec le protocole Sierra (Olympus,
Nikon...).
J'ai juste une question : est-il possible d'utiliser un appel lockmgr
dans un pilote de périphérique, selon ce modèle (schématique) :
En particulier, quelle priorité mettre dans l'appel lockinit, vu que la
solution par défaut, getpriority (PRIO_PROCESS, 0) va retourner la
priorité du noyau au moment de l'appel de _attach.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Miod Vallat
J'ai juste une question : est-il possible d'utiliser un appel lockmgr dans un pilote de périphérique, selon ce modèle (schématique) :
L'utilisation de lockmgr() n'a de sens que si tu associes le verrou à un processus (ou en 2.0, un lwp) - par exemple parce que ton traitement lent est provoqué par une entrée/sortie ou un ioctl depuis un processus en userland.
En particulier, quelle priorité mettre dans l'appel lockinit, vu que la solution par défaut, getpriority (PRIO_PROCESS, 0) va retourner la priorité du noyau au moment de l'appel de _attach.
PWAIT, ou PRIBIO si c'est véritablement une entrée/sortie comparable à une activité disque, me semblent adéquats.
lockmgr (usblock, LK_EXCLUSIVE , 0)
Attention, ne jamais passer un pointeur NULL à lockmgr. Au pire, curproc() ou curlwp(), mais jamais NULL...
J'ai juste une question : est-il possible d'utiliser un appel lockmgr
dans un pilote de périphérique, selon ce modèle (schématique) :
L'utilisation de lockmgr() n'a de sens que si tu associes le verrou à un
processus (ou en 2.0, un lwp) - par exemple parce que ton traitement
lent est provoqué par une entrée/sortie ou un ioctl depuis un processus
en userland.
En particulier, quelle priorité mettre dans l'appel lockinit, vu que la
solution par défaut, getpriority (PRIO_PROCESS, 0) va retourner la
priorité du noyau au moment de l'appel de _attach.
PWAIT, ou PRIBIO si c'est véritablement une entrée/sortie comparable à
une activité disque, me semblent adéquats.
lockmgr (usblock, LK_EXCLUSIVE , 0)
Attention, ne jamais passer un pointeur NULL à lockmgr. Au pire,
curproc() ou curlwp(), mais jamais NULL...
J'ai juste une question : est-il possible d'utiliser un appel lockmgr dans un pilote de périphérique, selon ce modèle (schématique) :
L'utilisation de lockmgr() n'a de sens que si tu associes le verrou à un processus (ou en 2.0, un lwp) - par exemple parce que ton traitement lent est provoqué par une entrée/sortie ou un ioctl depuis un processus en userland.
En particulier, quelle priorité mettre dans l'appel lockinit, vu que la solution par défaut, getpriority (PRIO_PROCESS, 0) va retourner la priorité du noyau au moment de l'appel de _attach.
PWAIT, ou PRIBIO si c'est véritablement une entrée/sortie comparable à une activité disque, me semblent adéquats.
lockmgr (usblock, LK_EXCLUSIVE , 0)
Attention, ne jamais passer un pointeur NULL à lockmgr. Au pire, curproc() ou curlwp(), mais jamais NULL...
Vincent
Re-
L'utilisation de lockmgr() n'a de sens que si tu associes le verrou à un processus (ou en 2.0, un lwp) - par exemple parce que ton traitement lent est provoqué par une entrée/sortie ou un ioctl depuis un processus en userland.
Oui, c'est ça. En fait, je veux bloquer si un processus 2 tente de lire un registre de l'appareil photo alors qu'un processus 1 est déjà en train de le faire, puis débloquer lorsque le bus est de nouveau libre.
En fait, le pilote ne supporte pas read/write. Il ne fonctionne que par ioctls, puisque l'appareil photo lui-même ne sait faire que cela.
Une fois qu'on a crée une strcuture de type bdevsw, comment récupérer son numéro d'ordre (et donc le majeur du périph ?)
PWAIT, ou PRIBIO si c'est véritablement une entrée/sortie comparable à une activité disque, me semblent adéquats.
Ok merci.
lockmgr (usblock, LK_EXCLUSIVE , 0)
Attention, ne jamais passer un pointeur NULL à lockmgr. Au pire, curproc() ou curlwp(), mais jamais NULL...
Il me semblait, d'après la man page, que le troisième argument était non significatif, sauf dans le cas de l'emploi du flag LK_INTERLOCK...
Vincent
Re-
L'utilisation de lockmgr() n'a de sens que si tu associes le verrou à
un processus (ou en 2.0, un lwp) - par exemple parce que ton
traitement lent est provoqué par une entrée/sortie ou un ioctl depuis
un processus en userland.
Oui, c'est ça. En fait, je veux bloquer si un processus 2 tente de lire
un registre de l'appareil photo alors qu'un processus 1 est déjà en
train de le faire, puis débloquer lorsque le bus est de nouveau libre.
En fait, le pilote ne supporte pas read/write. Il ne fonctionne que par
ioctls, puisque l'appareil photo lui-même ne sait faire que cela.
Une fois qu'on a crée une strcuture de type bdevsw, comment récupérer
son numéro d'ordre (et donc le majeur du périph ?)
PWAIT, ou PRIBIO si c'est véritablement une entrée/sortie comparable à
une activité disque, me semblent adéquats.
Ok merci.
lockmgr (usblock, LK_EXCLUSIVE , 0)
Attention, ne jamais passer un pointeur NULL à lockmgr. Au pire,
curproc() ou curlwp(), mais jamais NULL...
Il me semblait, d'après la man page, que le troisième argument était non
significatif, sauf dans le cas de l'emploi du flag LK_INTERLOCK...
L'utilisation de lockmgr() n'a de sens que si tu associes le verrou à un processus (ou en 2.0, un lwp) - par exemple parce que ton traitement lent est provoqué par une entrée/sortie ou un ioctl depuis un processus en userland.
Oui, c'est ça. En fait, je veux bloquer si un processus 2 tente de lire un registre de l'appareil photo alors qu'un processus 1 est déjà en train de le faire, puis débloquer lorsque le bus est de nouveau libre.
En fait, le pilote ne supporte pas read/write. Il ne fonctionne que par ioctls, puisque l'appareil photo lui-même ne sait faire que cela.
Une fois qu'on a crée une strcuture de type bdevsw, comment récupérer son numéro d'ordre (et donc le majeur du périph ?)
PWAIT, ou PRIBIO si c'est véritablement une entrée/sortie comparable à une activité disque, me semblent adéquats.
Ok merci.
lockmgr (usblock, LK_EXCLUSIVE , 0)
Attention, ne jamais passer un pointeur NULL à lockmgr. Au pire, curproc() ou curlwp(), mais jamais NULL...
Il me semblait, d'après la man page, que le troisième argument était non significatif, sauf dans le cas de l'emploi du flag LK_INTERLOCK...
Vincent
Miod Vallat
Oui, c'est ça. En fait, je veux bloquer si un processus 2 tente de lire un registre de l'appareil photo alors qu'un processus 1 est déjà en train de le faire, puis débloquer lorsque le bus est de nouveau libre.
Alors lockmgr() peut convenir.
Une fois qu'on a crée une strcuture de type bdevsw, comment récupérer son numéro d'ordre (et donc le majeur du périph ?)
Pourquoi as-tu besoin de connaître ton majeur ? Tu ne verra passer les open/ioctl/close que pour tes propres devices, tout ce que tu as à faire est de vérifier le mineur afin de voir si tu as du matériel associé.
Quand bien même tu aurais besoin de connaître ton majeur, sous Open, on en est encore à parcourir bdevsw[] et cdevsw[] à la mimine ; NetBSD 2 a [bc]devsw_lookup(), mais je ne sais pas si ces fonctions étaient déjà en 1.6.
lockmgr (usblock, LK_EXCLUSIVE , 0)
Attention, ne jamais passer un pointeur NULL à lockmgr. Au pire, curproc() ou curlwp(), mais jamais NULL...
Il me semblait, d'après la man page, que le troisième argument était non significatif, sauf dans le cas de l'emploi du flag LK_INTERLOCK...
Au temps pour moi, je ne me souvenais plus que lockmgr() avait 4 paramètres.
Oui, c'est ça. En fait, je veux bloquer si un processus 2 tente de lire
un registre de l'appareil photo alors qu'un processus 1 est déjà en
train de le faire, puis débloquer lorsque le bus est de nouveau libre.
Alors lockmgr() peut convenir.
Une fois qu'on a crée une strcuture de type bdevsw, comment récupérer
son numéro d'ordre (et donc le majeur du périph ?)
Pourquoi as-tu besoin de connaître ton majeur ? Tu ne verra passer les
open/ioctl/close que pour tes propres devices, tout ce que tu as à faire
est de vérifier le mineur afin de voir si tu as du matériel associé.
Quand bien même tu aurais besoin de connaître ton majeur, sous Open, on
en est encore à parcourir bdevsw[] et cdevsw[] à la mimine ; NetBSD 2 a
[bc]devsw_lookup(), mais je ne sais pas si ces fonctions étaient déjà en
1.6.
lockmgr (usblock, LK_EXCLUSIVE , 0)
Attention, ne jamais passer un pointeur NULL à lockmgr. Au pire,
curproc() ou curlwp(), mais jamais NULL...
Il me semblait, d'après la man page, que le troisième argument était non
significatif, sauf dans le cas de l'emploi du flag LK_INTERLOCK...
Au temps pour moi, je ne me souvenais plus que lockmgr() avait 4
paramètres.
Oui, c'est ça. En fait, je veux bloquer si un processus 2 tente de lire un registre de l'appareil photo alors qu'un processus 1 est déjà en train de le faire, puis débloquer lorsque le bus est de nouveau libre.
Alors lockmgr() peut convenir.
Une fois qu'on a crée une strcuture de type bdevsw, comment récupérer son numéro d'ordre (et donc le majeur du périph ?)
Pourquoi as-tu besoin de connaître ton majeur ? Tu ne verra passer les open/ioctl/close que pour tes propres devices, tout ce que tu as à faire est de vérifier le mineur afin de voir si tu as du matériel associé.
Quand bien même tu aurais besoin de connaître ton majeur, sous Open, on en est encore à parcourir bdevsw[] et cdevsw[] à la mimine ; NetBSD 2 a [bc]devsw_lookup(), mais je ne sais pas si ces fonctions étaient déjà en 1.6.
lockmgr (usblock, LK_EXCLUSIVE , 0)
Attention, ne jamais passer un pointeur NULL à lockmgr. Au pire, curproc() ou curlwp(), mais jamais NULL...
Il me semblait, d'après la man page, que le troisième argument était non significatif, sauf dans le cas de l'emploi du flag LK_INTERLOCK...
Au temps pour moi, je ne me souvenais plus que lockmgr() avait 4 paramètres.
Vincent
Miod Vallat dixit :
Alors lockmgr() peut convenir.
Hoquet :)
Pourquoi as-tu besoin de connaître ton majeur ? Tu ne verra passer les open/ioctl/close que pour tes propres devices, tout ce que tu as à faire est de vérifier le mineur afin de voir si tu as du matériel associé.
À ce qu'il me semble, si je veux faire un ioctl depuis l'userland, il faut quand même que je crée un device (donc mknod), ce qui suppose un couple majeur, mineur.
Bon, je n'ai certes pas d'intérêt à le connaître dans le corps du pilote, mais il faut quand même que je connaisse son numéro d'ordre dans la table pour mknod !
Au temps pour moi, je ne me souvenais plus que lockmgr() avait 4 paramètres.
C'est agréable de lire « au temps pour moi » dans sa version correcte ! :)
Merci encore Vincent
Miod Vallat <miod@online.fr> dixit :
Alors lockmgr() peut convenir.
Hoquet :)
Pourquoi as-tu besoin de connaître ton majeur ? Tu ne verra passer les
open/ioctl/close que pour tes propres devices, tout ce que tu as à
faire est de vérifier le mineur afin de voir si tu as du matériel
associé.
À ce qu'il me semble, si je veux faire un ioctl depuis l'userland, il
faut quand même que je crée un device (donc mknod), ce qui suppose un
couple majeur, mineur.
Bon, je n'ai certes pas d'intérêt à le connaître dans le corps du
pilote, mais il faut quand même que je connaisse son numéro d'ordre dans
la table pour mknod !
Au temps pour moi, je ne me souvenais plus que lockmgr() avait 4
paramètres.
C'est agréable de lire « au temps pour moi » dans sa version correcte !
:)
Pourquoi as-tu besoin de connaître ton majeur ? Tu ne verra passer les open/ioctl/close que pour tes propres devices, tout ce que tu as à faire est de vérifier le mineur afin de voir si tu as du matériel associé.
À ce qu'il me semble, si je veux faire un ioctl depuis l'userland, il faut quand même que je crée un device (donc mknod), ce qui suppose un couple majeur, mineur.
Bon, je n'ai certes pas d'intérêt à le connaître dans le corps du pilote, mais il faut quand même que je connaisse son numéro d'ordre dans la table pour mknod !
Au temps pour moi, je ne me souvenais plus que lockmgr() avait 4 paramètres.
C'est agréable de lire « au temps pour moi » dans sa version correcte ! :)
Merci encore Vincent
Miod Vallat
À ce qu'il me semble, si je veux faire un ioctl depuis l'userland, il faut quand même que je crée un device (donc mknod), ce qui suppose un couple majeur, mineur.
Certes. Dans ce cas, en 1.6 il te suffit de choisir un emplacement dans sys/arch/<arch>/<arch>/conf.c, qui te détermine le numéro majeur. La gestion des mineurs est laissée à ta guise. Et puis tu gagnes le droit de te palucher le MAKEDEV à la mimine.
En 2.0, tout est plus simple, tu n'as qu'à ajouter une entrée dans sys/arch/<arch>/conf/majors.<arch>, ou sys/conf/majors, et tout en découle automagiquement.
À ce qu'il me semble, si je veux faire un ioctl depuis l'userland, il
faut quand même que je crée un device (donc mknod), ce qui suppose un
couple majeur, mineur.
Certes. Dans ce cas, en 1.6 il te suffit de choisir un emplacement dans
sys/arch/<arch>/<arch>/conf.c, qui te détermine le numéro majeur. La
gestion des mineurs est laissée à ta guise. Et puis tu gagnes le droit
de te palucher le MAKEDEV à la mimine.
En 2.0, tout est plus simple, tu n'as qu'à ajouter une entrée dans
sys/arch/<arch>/conf/majors.<arch>, ou sys/conf/majors, et tout en
découle automagiquement.
À ce qu'il me semble, si je veux faire un ioctl depuis l'userland, il faut quand même que je crée un device (donc mknod), ce qui suppose un couple majeur, mineur.
Certes. Dans ce cas, en 1.6 il te suffit de choisir un emplacement dans sys/arch/<arch>/<arch>/conf.c, qui te détermine le numéro majeur. La gestion des mineurs est laissée à ta guise. Et puis tu gagnes le droit de te palucher le MAKEDEV à la mimine.
En 2.0, tout est plus simple, tu n'as qu'à ajouter une entrée dans sys/arch/<arch>/conf/majors.<arch>, ou sys/conf/majors, et tout en découle automagiquement.
Vincent
En 2.0, tout est plus simple, tu n'as qu'à ajouter une entrée dans sys/arch/<arch>/conf/majors.<arch>, ou sys/conf/majors, et tout en découle automagiquement.
Bien bien. Juste une dernière question.
Pour récupérer la structure toto_softc appropriée dans un appel genre toto_open ou toto_close, il faut bien faire :
struct toto_softc * toto_sc ;
[...]
toto_sc = toto_cd. cd_devs [dev] ; ?
Merci derechef. Vincent
En 2.0, tout est plus simple, tu n'as qu'à ajouter une entrée dans
sys/arch/<arch>/conf/majors.<arch>, ou sys/conf/majors, et tout en
découle automagiquement.
Bien bien.
Juste une dernière question.
Pour récupérer la structure toto_softc appropriée dans un appel genre
toto_open ou toto_close, il faut bien faire :
En 2.0, tout est plus simple, tu n'as qu'à ajouter une entrée dans sys/arch/<arch>/conf/majors.<arch>, ou sys/conf/majors, et tout en découle automagiquement.
Bien bien. Juste une dernière question.
Pour récupérer la structure toto_softc appropriée dans un appel genre toto_open ou toto_close, il faut bien faire :
struct toto_softc * toto_sc ;
[...]
toto_sc = toto_cd. cd_devs [dev] ; ?
Merci derechef. Vincent
Miod Vallat
Pour récupérer la structure toto_softc appropriée dans un appel genre toto_open ou toto_close, il faut bien faire :
struct toto_softc * toto_sc ;
[...]
toto_sc = toto_cd. cd_devs [dev] ;
Grossièrement, oui.
En pratique, on va aussi vérifier que l'on a bien un softc au numéro que l'utilisateur a demandé :
int totoopen(dev_t dev, int flag, int mode, struct proc *p) { struct toto_softc *sc; unsigned int dnum;
dnum = TOTO_NUM(dev); if (dnum >= toto_cd.cd_ndevs) return ENODEV;
sc = (struct tot_softc *)tot_cd.cd_devs[dnum];
...
où TOTO_NUM est une macro sur le thème de getminor() & 0x42, à fournir soi-même.
Pour récupérer la structure toto_softc appropriée dans un appel genre
toto_open ou toto_close, il faut bien faire :
struct toto_softc * toto_sc ;
[...]
toto_sc = toto_cd. cd_devs [dev] ;
Grossièrement, oui.
En pratique, on va aussi vérifier que l'on a bien un softc au numéro que
l'utilisateur a demandé :
int
totoopen(dev_t dev, int flag, int mode, struct proc *p)
{
struct toto_softc *sc;
unsigned int dnum;
dnum = TOTO_NUM(dev);
if (dnum >= toto_cd.cd_ndevs)
return ENODEV;
sc = (struct tot_softc *)tot_cd.cd_devs[dnum];
...
où TOTO_NUM est une macro sur le thème de getminor() & 0x42, à fournir
soi-même.
Pour récupérer la structure toto_softc appropriée dans un appel genre toto_open ou toto_close, il faut bien faire :
struct toto_softc * toto_sc ;
[...]
toto_sc = toto_cd. cd_devs [dev] ;
Grossièrement, oui.
En pratique, on va aussi vérifier que l'on a bien un softc au numéro que l'utilisateur a demandé :
int totoopen(dev_t dev, int flag, int mode, struct proc *p) { struct toto_softc *sc; unsigned int dnum;
dnum = TOTO_NUM(dev); if (dnum >= toto_cd.cd_ndevs) return ENODEV;
sc = (struct tot_softc *)tot_cd.cd_devs[dnum];
...
où TOTO_NUM est une macro sur le thème de getminor() & 0x42, à fournir soi-même.
Vincent
Miod Vallat dixit :
où TOTO_NUM est une macro sur le thème de getminor() & 0x42, à fournir soi-même.
Ouais, j'arrive pas à trouver la façon dont le dev_t est composé. Y a un fichier à consulter ? Y a bien la macro minor( ) dans types.h, mais ça ne me dit pas grand chose sur la signification des masques...
Vincent
Miod Vallat <miod@online.fr> dixit :
où TOTO_NUM est une macro sur le thème de getminor() & 0x42, à fournir
soi-même.
Ouais, j'arrive pas à trouver la façon dont le dev_t est composé.
Y a un fichier à consulter ? Y a bien la macro minor( ) dans types.h,
mais ça ne me dit pas grand chose sur la signification des masques...
où TOTO_NUM est une macro sur le thème de getminor() & 0x42, à fournir soi-même.
Ouais, j'arrive pas à trouver la façon dont le dev_t est composé. Y a un fichier à consulter ? Y a bien la macro minor( ) dans types.h, mais ça ne me dit pas grand chose sur la signification des masques...
Vincent
Miod Vallat
Ouais, j'arrive pas à trouver la façon dont le dev_t est composé.
makedev() dans <sys/types.h>.
Y a un fichier à consulter ? Y a bien la macro minor( ) dans types.h, mais ça ne me dit pas grand chose sur la signification des masques...
Tu t'en fiches ! La numérotation est opaque de ton point de vue. Tu as un majeur figé, et la gestion des mineurs est à ta guise.
Par exemple, un pilote pour une carte de ports parallèles peut définir les affectations suivantes :
0-7 8 ports en polling 8-15 8 ports avec interruptions