devattach 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. .TH DEVATTACH 9
  2. .SH NAME
  3. devattach, devclone, devdir, devgen, devwalk, devdirread, devstat, devopen, devbread, devbwrite, devcreate, devremove, devwstat, devreset, devinit, devshutdown, openmode \- common device driver support
  4. .SH SYNOPSIS
  5. .nf
  6. .ta \w'\fLBlock* 'u +10n
  7. .B
  8. typedef int
  9. .B
  10. Devgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
  11. .PP
  12. .B
  13. Chan* devattach(int tc, char *spec)
  14. .PP
  15. .B
  16. Chan* devclone(Chan *c)
  17. .PP
  18. .B
  19. void devdir(Chan *c, Qid qid, char *n, long length,
  20. .B
  21. char *user, long perm, Dir *dp)
  22. .PP
  23. .B
  24. int devgen(Chan *c, char *name, Dirtab *tab, int ntab,
  25. .B
  26. int i, Dir *dp)
  27. .PP
  28. .B
  29. Walkqid* devwalk(Chan *c, Chan *nc, char **name, int nname,
  30. .B
  31. Dirtab *tab, int ntab, Devgen *gen)
  32. .PP
  33. .B
  34. void devstat(Chan *c, uchar *db, int n, Dirtab *tab,
  35. .B
  36. int ntab, Devgen *gen)
  37. .PP
  38. .B
  39. long devdirread(Chan *c, char *d, long n, Dirtab *tab,
  40. .B
  41. int ntab, Devgen *gen)
  42. .PP
  43. .B
  44. Chan* devopen(Chan *c, int omode, Dirtab *tab,
  45. .B
  46. int ntab, Devgen *gen)
  47. .PP
  48. .B
  49. Block* devbread(Chan *c, long n, ulong offset)
  50. .PP
  51. .B
  52. long devbwrite(Chan *c, Block *bp, ulong offset)
  53. .PP
  54. .B
  55. void devcreate(Chan*, char*, int, ulong)
  56. .PP
  57. .B
  58. void devremove(Chan*)
  59. .PP
  60. .B
  61. void devwstat(Chan*, uchar*, int)
  62. .PP
  63. .B
  64. void devreset(void)
  65. .PP
  66. .B
  67. void devinit(void)
  68. .PP
  69. .B
  70. void devshutdown(void)
  71. .PP
  72. .B
  73. int openmode(ulong mode)
  74. .SH DESCRIPTION
  75. Device drivers call these functions to carry out essential tasks and default actions.
  76. They do most of the name space management
  77. for a driver that serves a simple name space
  78. (eg, data and control files),
  79. leaving the driver to concentrate on the device-specific details
  80. of the I/O requests.
  81. More complex drivers also make good use of them at the leaves
  82. of their name space, and to help manage the
  83. .B Chan
  84. structures correctly.
  85. .PP
  86. A device has an associated
  87. .IR type ,
  88. represented as a Unicode character (`rune') that identifies the device
  89. inside and outside the kernel.
  90. It appears as the value of the
  91. .B type
  92. field in the
  93. .B Dir
  94. resulting from a
  95. .IR sys-stat (2)
  96. of any file provided by the device.
  97. A device is named outside the kernel using
  98. a path name starting with
  99. .B #
  100. followed by the device character
  101. (eg,
  102. .B c
  103. in
  104. .B #c
  105. for the console).
  106. Any subsequent characters before
  107. the next '/' or end of string is the `device specifier',
  108. interpreted solely by the device itself.
  109. .PP
  110. .I Devattach
  111. returns a new channel representing
  112. the root of the file tree
  113. corresponding to device type
  114. .IR tc ,
  115. with device specifier
  116. .IR spec .
  117. It is normally called by a driver's
  118. .I attach
  119. function (see
  120. .IR dev (9)).
  121. The
  122. .B qid
  123. for the new channel is
  124. .BR "(Qid){0,0,QTDIR}" ,
  125. suitable for a root directory for many devices, but
  126. a device driver is free to change it (provided the
  127. .B QTDIR
  128. bit remains in the
  129. .BR Qid.type ).
  130. .PP
  131. .I Devclone
  132. returns a new channel that is a copy of
  133. .IR c .
  134. An attempt to clone an open channel causes a
  135. .IR panic (9).
  136. .PP
  137. The
  138. .L Dir
  139. structure is shown below:
  140. .IP
  141. .EX
  142. typedef
  143. struct Dir
  144. {
  145. /* system-modified data */
  146. ushort type; /* server type */
  147. uint dev; /* server subtype */
  148. /* file data */
  149. Qid qid; /* unique id from server */
  150. ulong mode; /* permissions */
  151. ulong atime; /* last read time */
  152. ulong mtime; /* last write time */
  153. vlong length; /* file length */
  154. char *name; /* last element of path */
  155. char *uid; /* owner name */
  156. char *gid; /* group name */
  157. char *muid; /* last modifier name */
  158. } Dir;
  159. .EE
  160. .PP
  161. This
  162. .B Dir
  163. structure corresponds directly to the Limbo
  164. .B Dir
  165. adt described in
  166. .IR sys-stat (2).
  167. .PP
  168. Given a channel and assorted other information,
  169. .I devdir
  170. initialises a Dir structure at
  171. .IR dp .
  172. .I Devdir
  173. supplies the following data itself:
  174. .RS
  175. .TF length
  176. .TP
  177. .B atime
  178. last access time (set to current time)
  179. .TP
  180. .B mtime
  181. last modification time (set to kernel creation date)
  182. .TP
  183. .B gid
  184. group name (set to
  185. .IR eve (9))
  186. .TP
  187. .B length
  188. length in bytes (set to zero, which
  189. is normal for most devices)
  190. .RE
  191. .PD
  192. .PP
  193. Note that
  194. .I devdir
  195. assigns the values of
  196. .I name
  197. and
  198. .I user
  199. directly to fields of
  200. .BI * dp,
  201. and consequently those values must remain valid until the last use of
  202. .BI * dp.
  203. (Sometimes that requires the use of an auxiliary buffer, such as
  204. .BR up->genbuf .)
  205. If channel
  206. .I c
  207. corresponds to a file descriptor on which Styx is served,
  208. .I devdir
  209. sets both the flag bit
  210. .B QTMOUNT
  211. in
  212. .IB dp ->qid.type
  213. and the flag bit
  214. .B DMMOUNT
  215. in
  216. .IB dp ->mode
  217. (see
  218. .I export
  219. in
  220. .IR sys-dial (2)
  221. and
  222. .I mount
  223. in
  224. .IR sys-bind (2)).
  225. .PP
  226. A simple name space can be represented in a driver by an array of
  227. .B Dirtab
  228. structures.
  229. The array is typically static when the names and permissions
  230. are static, but can be dynamically allocated and initialised if required.
  231. The structure of
  232. .B Dirtab
  233. is shown below:
  234. .IP
  235. .EX
  236. typedef
  237. struct Dirtab
  238. {
  239. char name[KNAMELEN];
  240. Qid qid;
  241. vlong length;
  242. long perm;
  243. } Dirtab;
  244. .EE
  245. .PP
  246. The name
  247. .RB ` . '
  248. .I must
  249. appear as the first entry in a
  250. .B Dirtab
  251. if the default
  252. .I devgen
  253. function is used.
  254. On the other hand, the name
  255. .RB ` .. '
  256. must never appear in a
  257. .B Dirtab
  258. table.
  259. Drivers that support a directory hierarchy must walk up the hierarchy towards
  260. the root when their
  261. .I walk
  262. function receives
  263. .RB ` .. '
  264. as a file name component.
  265. The name
  266. .RB ` . '
  267. is never seen by a driver.
  268. .PP
  269. The
  270. .IR devdirread ,
  271. .IR devopen ,
  272. .IR devstat ,
  273. and
  274. .IR devwalk
  275. functions all take a
  276. .I gen
  277. function argument,
  278. of type
  279. .BR Devgen ,
  280. which they invoke to retrieve the items in
  281. a
  282. .B Chan
  283. that represents a directory.
  284. .I Gen
  285. takes a channel
  286. .I c
  287. (a directory),
  288. a file
  289. .I name
  290. (which is nil except during
  291. .IR devwalk ),
  292. an array of
  293. .B Dirtab
  294. structures
  295. .I tab
  296. of length
  297. .IR ntab ,
  298. and a table index
  299. .IR i .
  300. The functions calling
  301. .I gen
  302. expect it to place the
  303. .IR i 'th
  304. entry in the directory into
  305. .IR \f5*\fPdp .
  306. It should return 1
  307. if the call was successful,
  308. -1 if
  309. .I i
  310. is beyond the index of the last directory entry,
  311. or 0 if there is no entry at
  312. .IR i ,
  313. but there are entries beyond it.
  314. When
  315. .I i
  316. has the special value
  317. .B DEVDOTDOT
  318. then
  319. .I gen
  320. should set
  321. .IR \f5*\fPdp
  322. to reflect the parent of
  323. .IR c ;
  324. if
  325. .I c
  326. is a one-level device directory, then `..' is equivalent to `.'.
  327. Custom implementations of
  328. .I gen
  329. often ignore
  330. .IR devtab ,
  331. and instead return their own dynamically generated
  332. set of directory entries from some other source.
  333. Exceptionally, during
  334. .I devwalk
  335. a non-nil
  336. .I name
  337. is provided: it is the name being looked up, and a device-specific
  338. .I gen
  339. can short-circuit the search by returning -1 if the name does not exist,
  340. or filling in
  341. .IR \f5*\fPdp
  342. and returning 1 if it does exist.
  343. .PP
  344. The function
  345. .I devgen
  346. is compatible with
  347. .BR Devgen ;
  348. it returns the
  349. .IR i 'th
  350. entry in
  351. .IR devtab ,
  352. and can be used to provide a simple, static
  353. set of directory entries.
  354. .PP
  355. .I Devwalk
  356. walks channel
  357. .I c
  358. to the file in the device named by the path encoded in
  359. .IR name ,
  360. which is an array of strings of length
  361. .IR nname .
  362. It provides the interface to
  363. .IR walk (5)
  364. within the kernel, and that specification must be well understood to appreciate
  365. all the nuances of its interface.
  366. Fortunately, in nearly all device drivers, a device's
  367. .I walk
  368. function typically passes its parameters on to
  369. .I devwalk
  370. (adding the device's own
  371. .B Dirtab
  372. array as the the value of
  373. .IR tab ),
  374. and simply returning the result of
  375. .IR devwalk .
  376. .PP
  377. .I Devwalk
  378. walks
  379. .I c
  380. using the given set of names, and if the walk is successful, the
  381. channel
  382. .I nc
  383. will refer to the result of the walk
  384. (specifically,
  385. .IB nc ->qid
  386. is set to the Qid for the file).
  387. If
  388. .I nc
  389. is nil,
  390. .I devwalk
  391. will allocate a new channel itself, that is initially a clone of
  392. .IR c .
  393. As in
  394. .IR walk (5),
  395. .I devwalk
  396. can return a partial result,
  397. represented by
  398. a dynamically allocated value of the following structure:
  399. .IP
  400. .EX
  401. struct Walkqid
  402. {
  403. Chan *clone;
  404. int nqid;
  405. Qid qid[1]; /* actually nname in length */
  406. };
  407. .EE
  408. .PP
  409. The value must be freed after use.
  410. For each element of
  411. .I name ,
  412. .I devwalk
  413. passes
  414. the
  415. .I tab
  416. parameter to
  417. .I gen
  418. together with the currently-sought element of
  419. .IR name .
  420. If the first element is not found,
  421. .I devwalk
  422. returns nil; otherwise, it returns a
  423. .B Walkqid
  424. value in which
  425. .B nqid
  426. elements of the array
  427. .B qid
  428. are set to the qids (see
  429. .IR intro (5))
  430. of each valid element of
  431. .IR name .
  432. If all
  433. .I nname
  434. elements were successfully traversed, then
  435. .B nqid
  436. will have the value
  437. .IR nname ,
  438. and
  439. .B clone
  440. will refer to the result of the walk,
  441. which is either
  442. .I nc
  443. if given, or
  444. the new channel allocated by
  445. .IR devwalk .
  446. Otherwise, at least one element succeeded and
  447. .B nqid
  448. is less than
  449. .I nname
  450. and
  451. .B clone
  452. is nil.
  453. On an error or incomplete walk,
  454. the error string is set to the error that stopped the walk (eg,
  455. .B Enonexist
  456. or
  457. .BR Enotdir ).
  458. .PP
  459. .I Devstat
  460. fills the array of bytes
  461. .I db
  462. with data in the format produced by
  463. .IR stat (5)
  464. that describes the file
  465. referenced by channel
  466. .IR c ,
  467. which must have a corresponding entry
  468. returned by
  469. .IR gen
  470. (ie, an entry with matching
  471. .BR Qid.path ).
  472. If
  473. .I c
  474. is a communications channel connecting a Styx server to a current mount point,
  475. the
  476. .B DMMOUNT
  477. bit is set in the resulting
  478. .BR Dir.mode ,
  479. and
  480. .B QTMOUNT
  481. is set in
  482. .BR Dir.qid.type .
  483. As in
  484. .IR stat (5),
  485. the length of the data written to
  486. .I db
  487. varies; if more than
  488. .I n
  489. bytes are needed,
  490. .I devstat
  491. raises the
  492. .IR error (9)
  493. .BR Ebadarg .
  494. Otherwise, it returns the number of bytes in
  495. .I db
  496. actually used.
  497. .PP
  498. If an entry with the desired qid is not found in the table, but
  499. .I c
  500. corresponds to a directory
  501. (ie,
  502. .B QTDIR
  503. is set in
  504. .IR c\f5->qid.type\fP ),
  505. it is taken to be a
  506. .I stat
  507. of a notional directory containing the files listed in
  508. .IR tab .
  509. .I Dirstat
  510. then builds the corresponding Dir structure:
  511. its
  512. .B Dir.name
  513. is taken from
  514. .IR c\f5->path->elem\fP ;
  515. the length is
  516. .BI DIRLEN*nelem(tab) ;
  517. and
  518. .B Dir.perm
  519. is 0555 (read-execute for all).
  520. .PP
  521. .I Devdirread
  522. calls
  523. .I gen
  524. to obtain successive
  525. .B Dir
  526. structures representing entries in the open directory
  527. .IR c .
  528. These are converted to standard format (see
  529. .I convD2M
  530. in
  531. .IR fcall (2))
  532. and placed in the buffer
  533. .IR b .
  534. It returns the number of bytes in the result.
  535. At most
  536. .I n
  537. bytes will be returned, in multiples of
  538. .BR DIRLEN .
  539. Because the kernel maintains the current offset in
  540. .IR c ,
  541. successive calls to
  542. .I devdirread
  543. return successive directory components.
  544. .PP
  545. .I Devopen
  546. is called to check and complete a request to open channel
  547. .I c
  548. for I/O according to
  549. .IR omode
  550. (the open mode of
  551. .IR sys-open (2)).
  552. It calls
  553. .I gen
  554. to obtain successive directory entries
  555. which it searches
  556. for a Qid matching that of
  557. .IR c ,
  558. and ensures that the current user has permission to open
  559. .I c
  560. with the given mode,
  561. .IR omode ,
  562. and that the mode itself is valid
  563. (see
  564. .I openmode
  565. below).
  566. Permission is checked against the permission in the
  567. matching entry.
  568. If no matching Qid is found, it is assumed
  569. that the notional parent directory of the files represented in
  570. .I tab
  571. is to be opened.
  572. Such a directory is deemed to have mode
  573. 0555, allowing access by any user.
  574. A directory can only be opened for reading
  575. .RB ( OREAD ).
  576. .I Devopen
  577. returns the channel
  578. .I c
  579. on success.
  580. Last, it sets the bit
  581. .B COPEN
  582. in
  583. .B Chan.flag
  584. to mark
  585. .I c
  586. as open.
  587. This convention can always be relied upon by the driver's
  588. .I close
  589. function to tell if an open succeeded.
  590. On the otherhand,
  591. if the open request was unsuccessful,
  592. .I devopen
  593. raises an appropriate
  594. .IR error (9)
  595. and does not return.
  596. .PP
  597. .I Devbread
  598. returns a
  599. .B Block
  600. (see
  601. .IR allocb (9))
  602. containing up to
  603. .I n
  604. bytes read,
  605. using
  606. .BI "devtab[" c "->type]->read" ,
  607. from
  608. .I c
  609. starting at the given
  610. .IR offset .
  611. The read pointer in the returned
  612. .B Block
  613. points to the start of the data;
  614. the write pointer points to the next available byte.
  615. .PP
  616. .I Devbwrite
  617. writes the data in
  618. .B Block
  619. .I bp
  620. to the file
  621. .I c
  622. at the given
  623. .IR offset ,
  624. using the write function
  625. .BI "devtab[" c "->type]->write" .
  626. It then frees the block list
  627. .I bp
  628. before
  629. returning the number of bytes written.
  630. .PP
  631. Most built-in devices do not allow
  632. .IR create ,
  633. .IR remove
  634. or
  635. .I wstat
  636. on their files.
  637. .IR Devcreate ,
  638. .I devremove
  639. and
  640. .I devwstat
  641. are stubs that raise an
  642. .IR error (9),
  643. .BR Eperm .
  644. They can be named directly in a device driver's device
  645. switch (the
  646. .B Dev
  647. structure in
  648. .BR /sys/src/9/port/portdat.h :
  649. see
  650. .IR dev (9)).
  651. .PP
  652. .IR Devreset ,
  653. .I devinit
  654. and
  655. .I devshutdown
  656. are also stubs;
  657. they do nothing.
  658. A device driver puts them in its
  659. .B Dev
  660. structure when it need take no action on device reset, initialisation, or shut down.
  661. .PP
  662. .I Openmode
  663. is used by a driver that does not use
  664. .IR devopen ,
  665. to check the open mode it receives in its open
  666. routine.
  667. .I Openmode
  668. returns mode
  669. .IR o ,
  670. the mode parameter to
  671. .IR sys-open (2)
  672. or
  673. .IR sys-create ,
  674. shorn of
  675. .BR OTRUNC
  676. and similar options,
  677. and reduced to one of
  678. .BR OREAD ,
  679. .BR OWRITE
  680. or
  681. .BR ORDWR .
  682. In particular,
  683. .B OEXEC
  684. becomes
  685. .B OREAD
  686. within the kernel.
  687. .I Openmode
  688. raises an
  689. .IR error (9)
  690. .B Ebadarg
  691. instead of returning, if
  692. .I o
  693. is an invalid mode (eg, reserved bits set).
  694. .SH SOURCE
  695. .B /sys/src/9/port/dev.c
  696. .SH SEE ALSO
  697. .IR allocb (9),
  698. .IR eve (9),
  699. .IR qio (9)