/testbed/scsipi/scsipiconf.h

http://rtems-atapi.googlecode.com/ · C Header · 859 lines · 487 code · 126 blank · 246 comment · 0 complexity · dcae428af41e6b7de6672cb4d0a34cc2 MD5 · raw file

  1. /* $NetBSD: scsipiconf.h,v 1.113 2008/09/08 23:36:54 gmcgarry Exp $ */
  2. /*-
  3. * Copyright (c) 1998, 1999, 2000, 2004 The NetBSD Foundation, Inc.
  4. * All rights reserved.
  5. *
  6. * This code is derived from software contributed to The NetBSD Foundation
  7. * by Charles M. Hannum; by Jason R. Thorpe of the Numerical Aerospace
  8. * Simulation Facility, NASA Ames Research Center.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  21. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  23. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. /*
  32. * Originally written by Julian Elischer (julian@tfs.com)
  33. * for TRW Financial Systems for use under the MACH(2.5) operating system.
  34. *
  35. * TRW Financial Systems, in accordance with their agreement with Carnegie
  36. * Mellon University, makes this software available to CMU to distribute
  37. * or use in any manner that they see fit as long as this message is kept with
  38. * the software. For this reason TFS also grants any other persons or
  39. * organisations permission to use or modify this software.
  40. *
  41. * TFS supplies this software to be publicly redistributed
  42. * on the understanding that TFS is not responsible for the correct
  43. * functioning of this software in any circumstances.
  44. *
  45. * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
  46. */
  47. #ifndef _DEV_SCSIPI_SCSIPICONF_H_
  48. #define _DEV_SCSIPI_SCSIPICONF_H_
  49. typedef int boolean;
  50. #include "../sys/callout.h"
  51. #include <rtems/bsd/sys/queue.h>
  52. #include "../scsipi/scsi_spc.h"
  53. #include "../scsipi/scsipi_debug.h"
  54. struct buf;
  55. struct proc;
  56. struct device;
  57. struct scsipi_channel;
  58. struct scsipi_periph;
  59. struct scsipi_xfer;
  60. /*
  61. * The following defines the scsipi_xfer queue.
  62. */
  63. TAILQ_HEAD(scsipi_xfer_queue, scsipi_xfer);
  64. struct scsipi_generic {
  65. u_int8_t opcode;
  66. u_int8_t bytes[15];
  67. };
  68. /*
  69. * scsipi_async_event_t:
  70. *
  71. * Asynchronous events from the adapter to the mid-layer and
  72. * peripherial.
  73. *
  74. * Arguments:
  75. *
  76. * ASYNC_EVENT_MAX_OPENINGS scsipi_max_openings * -- max
  77. * openings, device specified in
  78. * parameters
  79. *
  80. * ASYNC_EVENT_XFER_MODE scsipi_xfer_mode * -- xfer mode
  81. * parameters changed for I_T Nexus
  82. * ASYNC_EVENT_RESET NULL - channel has been reset
  83. */
  84. typedef enum {
  85. ASYNC_EVENT_MAX_OPENINGS, /* set max openings on periph */
  86. ASYNC_EVENT_XFER_MODE, /* xfer mode update for I_T */
  87. ASYNC_EVENT_RESET /* channel reset */
  88. } scsipi_async_event_t;
  89. /*
  90. * scsipi_max_openings:
  91. *
  92. * Argument for an ASYNC_EVENT_MAX_OPENINGS event.
  93. */
  94. struct scsipi_max_openings {
  95. int mo_target; /* openings are for this target... */
  96. int mo_lun; /* ...and this lun */
  97. int mo_openings; /* openings value */
  98. };
  99. /*
  100. * scsipi_xfer_mode:
  101. *
  102. * Argument for an ASYNC_EVENT_XFER_MODE event.
  103. */
  104. struct scsipi_xfer_mode {
  105. int xm_target; /* target, for I_T Nexus */
  106. int xm_mode; /* PERIPH_CAP* bits */
  107. int xm_period; /* sync period */
  108. int xm_offset; /* sync offset */
  109. };
  110. /*
  111. * scsipi_adapter_req_t:
  112. *
  113. * Requests that can be made of an adapter.
  114. *
  115. * Arguments:
  116. *
  117. * ADAPTER_REQ_RUN_XFER scsipi_xfer * -- the xfer which
  118. * is to be run
  119. *
  120. * ADAPTER_REQ_GROW_RESOURCES no argument
  121. *
  122. * ADAPTER_REQ_SET_XFER_MODE scsipi_xfer_mode * -- set the xfer
  123. * mode for the I_T Nexus according to
  124. * this
  125. */
  126. typedef enum {
  127. ADAPTER_REQ_RUN_XFER, /* run a scsipi_xfer */
  128. ADAPTER_REQ_GROW_RESOURCES, /* grow xfer execution resources */
  129. ADAPTER_REQ_SET_XFER_MODE /* set xfer mode */
  130. } scsipi_adapter_req_t;
  131. /*
  132. * scsipi_periphsw:
  133. *
  134. * Callbacks into periph driver from midlayer.
  135. *
  136. * psw_error Called by the bustype's interpret-sense routine
  137. * to do periph-specific sense handling.
  138. *
  139. * psw_start Called by midlayer to restart a device once
  140. * more command openings become available.
  141. *
  142. * psw_async Called by midlayer when an asynchronous event
  143. * from the adapter occurs.
  144. *
  145. * psw_done Called by the midlayer when an xfer has completed.
  146. */
  147. struct scsipi_periphsw {
  148. int (*psw_error)(struct scsipi_xfer *);
  149. void (*psw_start)(struct scsipi_periph *);
  150. int (*psw_async)(struct scsipi_periph *,
  151. scsipi_async_event_t, void *);
  152. void (*psw_done)(struct scsipi_xfer *, int);
  153. };
  154. struct disk_parms;
  155. struct scsipi_inquiry_pattern;
  156. /*
  157. * scsipi_adapter:
  158. *
  159. * This structure describes an instance of a SCSIPI adapter.
  160. *
  161. * Note that `adapt_openings' is used by (the common case of) adapters
  162. * which have per-adapter resources. If an adapter's command resources
  163. * are associated with a channel, then the `chan_openings' below will
  164. * be used instead.
  165. *
  166. * Note that all adapter entry points take a pointer to a channel,
  167. * as an adapter may have more than one channel, and the channel
  168. * structure contains the channel number.
  169. */
  170. struct scsipi_adapter {
  171. struct device *adapt_dev; /* pointer to adapter's device */
  172. int adapt_nchannels; /* number of adapter channels */
  173. int adapt_refcnt; /* adapter's reference count */
  174. int adapt_openings; /* total # of command openings */
  175. int adapt_max_periph; /* max openings per periph */
  176. int adapt_flags;
  177. void (*adapt_request)(struct scsipi_channel *,
  178. scsipi_adapter_req_t, void *);
  179. void (*adapt_minphys)(struct buf *);
  180. int (*adapt_ioctl)(struct scsipi_channel *, u_long,
  181. void *, int, struct proc *);
  182. int (*adapt_enable)(struct device *, int);
  183. int (*adapt_getgeom)(struct scsipi_periph *,
  184. struct disk_parms *, u_long);
  185. int (*adapt_accesschk)(struct scsipi_periph *,
  186. struct scsipi_inquiry_pattern *);
  187. };
  188. /* adapt_flags */
  189. #define SCSIPI_ADAPT_POLL_ONLY 0x01 /* Adaptor can't do interrupts. */
  190. #define scsipi_adapter_minphys(chan, bp) \
  191. (*(chan)->chan_adapter->adapt_minphys)((bp))
  192. #define scsipi_adapter_request(chan, req, arg) \
  193. (*(chan)->chan_adapter->adapt_request)((chan), (req), (arg))
  194. #define scsipi_adapter_ioctl(chan, cmd, data, flag, p) \
  195. (*(chan)->chan_adapter->adapt_ioctl)((chan), (cmd), (data), (flag), (p))
  196. #define scsipi_adapter_enable(chan, enable) \
  197. (*(chan)->chan_adapt->adapt_enable)((chan), (enable))
  198. /*
  199. * scsipi_bustype:
  200. *
  201. * This structure describes a SCSIPI bus type.
  202. * The bustype_type member is shared with struct ata_bustype
  203. * (because we can ata, atapi or scsi busses to the same controller)
  204. */
  205. struct scsipi_bustype {
  206. int bustype_type; /* symbolic name of type */
  207. void (*bustype_cmd)(struct scsipi_xfer *);
  208. int (*bustype_interpret_sense)(struct scsipi_xfer *);
  209. void (*bustype_printaddr)(struct scsipi_periph *);
  210. void (*bustype_kill_pending)(struct scsipi_periph *);
  211. };
  212. /* bustype_type */
  213. #define SCSIPI_BUSTYPE_SCSI 0
  214. #define SCSIPI_BUSTYPE_ATAPI 1
  215. /* #define SCSIPI_BUSTYPE_ATA 2 */
  216. /*
  217. * scsipi_channel:
  218. *
  219. * This structure describes a single channel of a SCSIPI adapter.
  220. * An adapter may have one or more channels. See the comment above
  221. * regarding the resource counter.
  222. * Note: chan_bustype has to be first member, as its bustype_type member
  223. * is shared with the aa_bustype member of struct ata_atapi_attach.
  224. */
  225. #define SCSIPI_CHAN_PERIPH_BUCKETS 16
  226. #define SCSIPI_CHAN_PERIPH_HASHMASK (SCSIPI_CHAN_PERIPH_BUCKETS - 1)
  227. struct scsipi_channel {
  228. const struct scsipi_bustype *chan_bustype; /* channel's bus type */
  229. const char *chan_name; /* this channel's name */
  230. struct scsipi_adapter *chan_adapter; /* pointer to our adapter */
  231. /* Periphs for this channel. */
  232. LIST_HEAD(, scsipi_periph) chan_periphtab[SCSIPI_CHAN_PERIPH_BUCKETS];
  233. int chan_channel; /* channel number */
  234. int chan_flags; /* channel flags */
  235. int chan_openings; /* number of command openings */
  236. int chan_max_periph; /* max openings per periph */
  237. int chan_ntargets; /* number of targets */
  238. int chan_nluns; /* number of luns */
  239. int chan_id; /* adapter's ID for this channel */
  240. int chan_defquirks; /* default device's quirks */
  241. struct lwp *chan_thread; /* completion thread */
  242. int chan_tflags; /* flags for the completion thread */
  243. int chan_qfreeze; /* freeze count for queue */
  244. /* Job queue for this channel. */
  245. struct scsipi_xfer_queue chan_queue;
  246. /* Completed (async) jobs. */
  247. struct scsipi_xfer_queue chan_complete;
  248. /* callback we may have to call from completion thread */
  249. void (*chan_callback)(struct scsipi_channel *, void *);
  250. void *chan_callback_arg;
  251. /* callback we may have to call after forking the kthread */
  252. void (*chan_init_cb)(struct scsipi_channel *, void *);
  253. void *chan_init_cb_arg;
  254. };
  255. /* chan_flags */
  256. #define SCSIPI_CHAN_OPENINGS 0x01 /* use chan_openings */
  257. #define SCSIPI_CHAN_CANGROW 0x02 /* channel can grow resources */
  258. #define SCSIPI_CHAN_NOSETTLE 0x04 /* don't wait for devices to settle */
  259. #define SCSIPI_CHAN_TACTIVE 0x08 /* completion thread is active */
  260. /* chan thread flags (chan_tflags) */
  261. #define SCSIPI_CHANT_SHUTDOWN 0x01 /* channel is shutting down */
  262. #define SCSIPI_CHANT_CALLBACK 0x02 /* has to call chan_callback() */
  263. #define SCSIPI_CHANT_KICK 0x04 /* need to run queues */
  264. #define SCSIPI_CHANT_GROWRES 0x08 /* call ADAPTER_REQ_GROW_RESOURCES */
  265. #define SCSIPI_CHAN_MAX_PERIPH(chan) \
  266. (((chan)->chan_flags & SCSIPI_CHAN_OPENINGS) ? \
  267. (chan)->chan_max_periph : (chan)->chan_adapter->adapt_max_periph)
  268. #define scsipi_printaddr(periph) \
  269. (*(periph)->periph_channel->chan_bustype->bustype_printaddr)((periph))
  270. #define scsipi_periph_bustype(periph) \
  271. (periph)->periph_channel->chan_bustype->bustype_type
  272. /*
  273. * Number of tag words in a periph structure:
  274. *
  275. * n_tag_words = ((256 / NBBY) / sizeof(u_int32_t))
  276. */
  277. #define PERIPH_NTAGWORDS ((256 / 8) / sizeof(u_int32_t))
  278. /*
  279. * scsipi_periph:
  280. *
  281. * This structure describes the path between a peripherial device
  282. * and an adapter. It contains a pointer to the adapter channel
  283. * which in turn contains a pointer to the adapter.
  284. *
  285. * XXX Given the way NetBSD's autoconfiguration works, this is ...
  286. * XXX nasty.
  287. *
  288. * Well, it's a lot nicer than it used to be, but there could
  289. * still be an improvement.
  290. */
  291. struct scsipi_periph {
  292. struct device *periph_dev; /* pointer to peripherial's device */
  293. struct scsipi_channel *periph_channel; /* channel we're connected to */
  294. /* link in channel's table of periphs */
  295. LIST_ENTRY(scsipi_periph) periph_hash;
  296. const struct scsipi_periphsw *periph_switch; /* peripherial's entry
  297. points */
  298. int periph_openings; /* max # of outstanding commands */
  299. int periph_active; /* current # of outstanding commands */
  300. int periph_sent; /* current # of commands sent to adapt*/
  301. int periph_mode; /* operation modes, CAP bits */
  302. int periph_period; /* sync period (factor) */
  303. int periph_offset; /* sync offset */
  304. /*
  305. * Information gleaned from the inquiry data.
  306. */
  307. u_int8_t periph_type; /* basic device type */
  308. int periph_cap; /* capabilities */
  309. int periph_quirks; /* device's quirks */
  310. int periph_flags; /* misc. flags */
  311. int periph_dbflags; /* debugging flags */
  312. int periph_target; /* target ID (drive # on ATAPI) */
  313. int periph_lun; /* LUN (not used on ATAPI) */
  314. int periph_version; /* ANSI SCSI version */
  315. int periph_qfreeze; /* queue freeze count */
  316. /* Bitmap of free command tags. */
  317. u_int32_t periph_freetags[PERIPH_NTAGWORDS];
  318. /* Pending scsipi_xfers on this peripherial. */
  319. struct scsipi_xfer_queue periph_xferq;
  320. callout_t periph_callout;
  321. /* xfer which has a pending CHECK_CONDITION */
  322. struct scsipi_xfer *periph_xscheck;
  323. };
  324. /*
  325. * Macro to return the current xfer mode of a periph.
  326. */
  327. #define PERIPH_XFER_MODE(periph) \
  328. (((periph)->periph_flags & PERIPH_MODE_VALID) ? \
  329. (periph)->periph_mode : 0)
  330. /* periph_cap */
  331. #define PERIPH_CAP_ANEC 0x0001 /* async event notification */
  332. #define PERIPH_CAP_TERMIOP 0x0002 /* terminate i/o proc. messages */
  333. #define PERIPH_CAP_RELADR 0x0004 /* relative addressing */
  334. #define PERIPH_CAP_WIDE32 0x0008 /* wide-32 transfers */
  335. #define PERIPH_CAP_WIDE16 0x0010 /* wide-16 transfers */
  336. /* XXX 0x0020 reserved for ATAPI_CFG_DRQ_MASK */
  337. /* XXX 0x0040 reserved for ATAPI_CFG_DRQ_MASK */
  338. #define PERIPH_CAP_SYNC 0x0080 /* synchronous transfers */
  339. #define PERIPH_CAP_LINKCMDS 0x0100 /* linked commands */
  340. #define PERIPH_CAP_TQING 0x0200 /* tagged queueing */
  341. #define PERIPH_CAP_SFTRESET 0x0400 /* soft RESET condition response */
  342. #define PERIPH_CAP_CMD16 0x0800 /* 16 byte commands (ATAPI) */
  343. #define PERIPH_CAP_DT 0x1000 /* supports DT clock */
  344. #define PERIPH_CAP_QAS 0x2000 /* supports quick arbit. and select. */
  345. #define PERIPH_CAP_IUS 0x4000 /* supports information unit xfers */
  346. /* periph_flags */
  347. #define PERIPH_REMOVABLE 0x0001 /* media is removable */
  348. #define PERIPH_MEDIA_LOADED 0x0002 /* media is loaded */
  349. #define PERIPH_WAITING 0x0004 /* process waiting for opening */
  350. #define PERIPH_OPEN 0x0008 /* device is open */
  351. #define PERIPH_WAITDRAIN 0x0010 /* waiting for pending xfers to drain */
  352. #define PERIPH_GROW_OPENINGS 0x0020 /* allow openings to grow */
  353. #define PERIPH_MODE_VALID 0x0040 /* periph_mode is valid */
  354. #define PERIPH_RECOVERING 0x0080 /* periph is recovering */
  355. #define PERIPH_RECOVERY_ACTIVE 0x0100 /* a recovery command is active */
  356. #define PERIPH_KEEP_LABEL 0x0200 /* retain label after 'full' close */
  357. #define PERIPH_SENSE 0x0400 /* periph has sense pending */
  358. #define PERIPH_UNTAG 0x0800 /* untagged command running */
  359. /* periph_quirks */
  360. #define PQUIRK_AUTOSAVE 0x00000001 /* do implicit SAVE POINTERS */
  361. #define PQUIRK_NOSYNC 0x00000002 /* does not grok SDTR */
  362. #define PQUIRK_NOWIDE 0x00000004 /* does not grok WDTR */
  363. #define PQUIRK_NOTAG 0x00000008 /* does not grok tagged cmds */
  364. #define PQUIRK_NOLUNS 0x00000010 /* DTWT with LUNs */
  365. #define PQUIRK_FORCELUNS 0x00000020 /* prehistoric device groks
  366. LUNs */
  367. #define PQUIRK_NOMODESENSE 0x00000040 /* device doesn't do MODE SENSE
  368. properly */
  369. #define PQUIRK_NOSYNCCACHE 0x00000100 /* do not issue SYNC CACHE */
  370. #define PQUIRK_LITTLETOC 0x00000400 /* audio TOC is little-endian */
  371. #define PQUIRK_NOCAPACITY 0x00000800 /* no READ CD CAPACITY */
  372. #define PQUIRK_NOTUR 0x00001000 /* no TEST UNIT READY */
  373. #define PQUIRK_NODOORLOCK 0x00002000 /* can't lock door */
  374. #define PQUIRK_NOSENSE 0x00004000 /* can't REQUEST SENSE */
  375. #define PQUIRK_ONLYBIG 0x00008000 /* only use SCSI_{R,W}_BIG */
  376. #define PQUIRK_NOBIGMODESENSE 0x00040000 /* has no big mode-sense op */
  377. #define PQUIRK_CAP_SYNC 0x00080000 /* SCSI device with ST sync op*/
  378. #define PQUIRK_CAP_WIDE16 0x00100000 /* SCSI device with ST wide op*/
  379. #define PQUIRK_CAP_NODT 0x00200000 /* signals DT, but can't. */
  380. /*
  381. * Error values an adapter driver may return
  382. */
  383. typedef enum {
  384. XS_NOERROR, /* there is no error, (sense is invalid) */
  385. XS_SENSE, /* Check the returned sense for the error */
  386. XS_SHORTSENSE, /* Check the ATAPI sense for the error */
  387. XS_DRIVER_STUFFUP, /* Driver failed to perform operation */
  388. XS_RESOURCE_SHORTAGE, /* adapter resource shortage */
  389. XS_SELTIMEOUT, /* The device timed out.. turned off? */
  390. XS_TIMEOUT, /* The Timeout reported was caught by SW */
  391. XS_BUSY, /* The device busy, try again later? */
  392. XS_RESET, /* bus was reset; possible retry command */
  393. XS_REQUEUE /* requeue this command */
  394. } scsipi_xfer_result_t;
  395. /*
  396. * Each scsipi transaction is fully described by one of these structures
  397. * It includes information about the source of the command and also the
  398. * device and adapter for which the command is destined.
  399. *
  400. * Before the HBA is given this transaction, channel_q is the linkage on
  401. * the related channel's chan_queue.
  402. *
  403. * When the this transaction is taken off the channel's chan_queue and
  404. * the HBA's request entry point is called with this transaction, the
  405. * HBA can use the channel_q tag for whatever it likes until it calls
  406. * scsipi_done for this transaction, at which time it has to stop
  407. * using channel_q.
  408. *
  409. * After scsipi_done is called with this transaction and if there was an
  410. * error on it, channel_q then becomes the linkage on the related channel's
  411. * chan_complete cqueue.
  412. *
  413. * The device_q member is maintained by the scsipi middle layer. When
  414. * a device issues a command, the xfer is placed on that device's
  415. * pending commands queue. When an xfer is done and freed, it is taken
  416. * off the device's queue. This allows for a device to wait for all of
  417. * its pending commands to complete.
  418. */
  419. struct scsipi_xfer {
  420. TAILQ_ENTRY(scsipi_xfer) channel_q; /* entry on channel queue */
  421. TAILQ_ENTRY(scsipi_xfer) device_q; /* device's pending xfers */
  422. callout_t xs_callout; /* callout for adapter use */
  423. int xs_control; /* control flags */
  424. volatile int xs_status; /* status flags */
  425. struct scsipi_periph *xs_periph;/* peripherial doing the xfer */
  426. int xs_retries; /* the number of times to retry */
  427. int xs_requeuecnt; /* number of requeues */
  428. int timeout; /* in milliseconds */
  429. struct scsipi_generic *cmd; /* The scsipi command to execute */
  430. int cmdlen; /* how long it is */
  431. u_char *data; /* DMA address OR a uio address */
  432. int datalen; /* data len (blank if uio) */
  433. int resid; /* how much buffer was not touched */
  434. scsipi_xfer_result_t error; /* an error value */
  435. struct buf *bp; /* If we need to associate with */
  436. /* a buf */
  437. union {
  438. struct scsi_sense_data scsi_sense; /* 32 bytes */
  439. u_int32_t atapi_sense;
  440. } sense;
  441. struct scsipi_xfer *xs_sensefor;/* we are requesting sense for this */
  442. /* xfer */
  443. u_int8_t status; /* SCSI status */
  444. /*
  445. * Info for tagged command queueing. This may or may not
  446. * be used by a given adapter driver. These are the same
  447. * as the bytes in the tag message.
  448. */
  449. u_int8_t xs_tag_type; /* tag type */
  450. u_int8_t xs_tag_id; /* tag ID */
  451. struct scsipi_generic cmdstore /*__aligned(4)*/; /* stash the command in here */
  452. };
  453. /*
  454. * scsipi_xfer control flags
  455. *
  456. * To do:
  457. *
  458. * - figure out what to do with XS_CTL_ESCAPE
  459. *
  460. * - replace XS_CTL_URGENT with an `xs_priority' field?
  461. */
  462. #define XS_CTL_NOSLEEP 0x00000001 /* don't sleep */
  463. #define XS_CTL_POLL 0x00000002 /* poll for completion */
  464. #define XS_CTL_DISCOVERY 0x00000004 /* doing device discovery */
  465. #define XS_CTL_ASYNC 0x00000008 /* command completes
  466. asynchronously */
  467. #define XS_CTL_USERCMD 0x00000010 /* user issued command */
  468. #define XS_CTL_SILENT 0x00000020 /* don't print sense info */
  469. #define XS_CTL_IGNORE_NOT_READY 0x00000040 /* ignore NOT READY */
  470. #define XS_CTL_IGNORE_MEDIA_CHANGE \
  471. 0x00000080 /* ignore media change */
  472. #define XS_CTL_IGNORE_ILLEGAL_REQUEST \
  473. 0x00000100 /* ignore ILLEGAL REQUEST */
  474. #define XS_CTL_SILENT_NODEV 0x00000200 /* don't print sense info
  475. if sense info is nodev */
  476. #define XS_CTL_RESET 0x00000400 /* reset the device */
  477. #define XS_CTL_DATA_UIO 0x00000800 /* xs_data points to uio */
  478. #define XS_CTL_DATA_IN 0x00001000 /* data coming into memory */
  479. #define XS_CTL_DATA_OUT 0x00002000 /* data going out of memory */
  480. #define XS_CTL_TARGET 0x00004000 /* target mode operation */
  481. #define XS_CTL_ESCAPE 0x00008000 /* escape operation */
  482. #define XS_CTL_URGENT 0x00010000 /* urgent (recovery)
  483. operation */
  484. #define XS_CTL_SIMPLE_TAG 0x00020000 /* use a Simple Tag */
  485. #define XS_CTL_ORDERED_TAG 0x00040000 /* use an Ordered Tag */
  486. #define XS_CTL_HEAD_TAG 0x00080000 /* use a Head of Queue Tag */
  487. #define XS_CTL_THAW_PERIPH 0x00100000 /* thaw periph once enqueued */
  488. #define XS_CTL_FREEZE_PERIPH 0x00200000 /* freeze periph when done */
  489. #define XS_CTL_DATA_ONSTACK 0x00400000 /* data is alloc'ed on stack */
  490. #define XS_CTL_REQSENSE 0x00800000 /* xfer is a request sense */
  491. #define XS_CTL_TAGMASK (XS_CTL_SIMPLE_TAG|XS_CTL_ORDERED_TAG|XS_CTL_HEAD_TAG)
  492. #define XS_CTL_TAGTYPE(xs) ((xs)->xs_control & XS_CTL_TAGMASK)
  493. /*
  494. * scsipi_xfer status flags
  495. */
  496. #define XS_STS_DONE 0x00000001 /* scsipi_xfer is done */
  497. #define XS_STS_PRIVATE 0xf0000000 /* reserved for HBA's use */
  498. /*
  499. * This describes matching information for scsipi_inqmatch(). The more things
  500. * match, the higher the configuration priority.
  501. */
  502. struct scsipi_inquiry_pattern {
  503. u_int8_t type;
  504. boolean removable;
  505. const char *vendor;
  506. const char *product;
  507. const char *revision;
  508. };
  509. /*
  510. * This is used to pass information from the high-level configuration code
  511. * to the device-specific drivers.
  512. */
  513. struct scsipibus_attach_args {
  514. struct scsipi_periph *sa_periph;
  515. struct scsipi_inquiry_pattern sa_inqbuf;
  516. struct scsipi_inquiry_data *sa_inqptr;
  517. union { /* bus-type specific infos */
  518. u_int8_t scsi_version; /* SCSI version */
  519. } scsipi_info;
  520. };
  521. /*
  522. * this describes a quirk entry
  523. */
  524. struct scsi_quirk_inquiry_pattern {
  525. struct scsipi_inquiry_pattern pattern;
  526. int quirks;
  527. };
  528. /*
  529. * Default number of retries, used for generic routines.
  530. */
  531. #define SCSIPIRETRIES 4
  532. #ifdef _KERNEL
  533. void scsipi_init(void);
  534. int scsipi_command(struct scsipi_periph *, struct scsipi_generic *, int,
  535. u_char *, int, int, int, struct buf *, int);
  536. void scsipi_create_completion_thread(void *);
  537. const void *scsipi_inqmatch(struct scsipi_inquiry_pattern *, const void *,
  538. size_t, size_t, int *);
  539. const char *scsipi_dtype(int);
  540. void scsipi_strvis(u_char *, int, const u_char *, int);
  541. int scsipi_execute_xs(struct scsipi_xfer *);
  542. int scsipi_test_unit_ready(struct scsipi_periph *, int);
  543. int scsipi_prevent(struct scsipi_periph *, int, int);
  544. int scsipi_inquire(struct scsipi_periph *,
  545. struct scsipi_inquiry_data *, int);
  546. int scsipi_mode_select(struct scsipi_periph *, int,
  547. struct scsi_mode_parameter_header_6 *, int, int, int, int);
  548. int scsipi_mode_select_big(struct scsipi_periph *, int,
  549. struct scsi_mode_parameter_header_10 *, int, int, int, int);
  550. int scsipi_mode_sense(struct scsipi_periph *, int, int,
  551. struct scsi_mode_parameter_header_6 *, int, int, int, int);
  552. int scsipi_mode_sense_big(struct scsipi_periph *, int, int,
  553. struct scsi_mode_parameter_header_10 *, int, int, int, int);
  554. int scsipi_start(struct scsipi_periph *, int, int);
  555. void scsipi_done(struct scsipi_xfer *);
  556. void scsipi_user_done(struct scsipi_xfer *);
  557. int scsipi_interpret_sense(struct scsipi_xfer *);
  558. void scsipi_wait_drain(struct scsipi_periph *);
  559. void scsipi_kill_pending(struct scsipi_periph *);
  560. struct scsipi_periph *scsipi_alloc_periph(int);
  561. #ifdef SCSIVERBOSE
  562. void scsipi_print_sense(struct scsipi_xfer *, int);
  563. void scsipi_print_sense_data(struct scsi_sense_data *, int);
  564. char *scsipi_decode_sense(void *, int);
  565. #endif
  566. void scsipi_print_cdb(struct scsipi_generic *cmd);
  567. int scsipi_thread_call_callback(struct scsipi_channel *,
  568. void (*callback)(struct scsipi_channel *, void *),
  569. void *);
  570. void scsipi_async_event(struct scsipi_channel *,
  571. scsipi_async_event_t, void *);
  572. int scsipi_do_ioctl(struct scsipi_periph *, dev_t, u_long, void *,
  573. int, struct lwp *);
  574. void scsipi_print_xfer_mode(struct scsipi_periph *);
  575. void scsipi_set_xfer_mode(struct scsipi_channel *, int, int);
  576. int scsipi_channel_init(struct scsipi_channel *);
  577. void scsipi_channel_shutdown(struct scsipi_channel *);
  578. void scsipi_insert_periph(struct scsipi_channel *,
  579. struct scsipi_periph *);
  580. void scsipi_remove_periph(struct scsipi_channel *,
  581. struct scsipi_periph *);
  582. struct scsipi_periph *scsipi_lookup_periph(struct scsipi_channel *,
  583. int, int);
  584. int scsipi_target_detach(struct scsipi_channel *, int, int, int);
  585. int scsipi_adapter_addref(struct scsipi_adapter *);
  586. void scsipi_adapter_delref(struct scsipi_adapter *);
  587. void scsipi_channel_freeze(struct scsipi_channel *, int);
  588. void scsipi_channel_thaw(struct scsipi_channel *, int);
  589. void scsipi_channel_timed_thaw(void *);
  590. void scsipi_periph_freeze(struct scsipi_periph *, int);
  591. void scsipi_periph_thaw(struct scsipi_periph *, int);
  592. void scsipi_periph_timed_thaw(void *);
  593. int scsipi_sync_period_to_factor(int);
  594. int scsipi_sync_factor_to_period(int);
  595. int scsipi_sync_factor_to_freq(int);
  596. void show_scsipi_xs(struct scsipi_xfer *);
  597. void show_scsipi_cmd(struct scsipi_xfer *);
  598. void show_mem(u_char *, int);
  599. #endif /* _KERNEL */
  600. static __inline void
  601. _lto2b(u_int32_t val, u_int8_t *bytes)
  602. {
  603. bytes[0] = (val >> 8) & 0xff;
  604. bytes[1] = val & 0xff;
  605. }
  606. static __inline void
  607. _lto3b(u_int32_t val, u_int8_t *bytes)
  608. {
  609. bytes[0] = (val >> 16) & 0xff;
  610. bytes[1] = (val >> 8) & 0xff;
  611. bytes[2] = val & 0xff;
  612. }
  613. static __inline void
  614. _lto4b(u_int32_t val, u_int8_t *bytes)
  615. {
  616. bytes[0] = (val >> 24) & 0xff;
  617. bytes[1] = (val >> 16) & 0xff;
  618. bytes[2] = (val >> 8) & 0xff;
  619. bytes[3] = val & 0xff;
  620. }
  621. static __inline void
  622. _lto8b(u_int64_t val, u_int8_t *bytes)
  623. {
  624. bytes[0] = (val >> 56) & 0xff;
  625. bytes[1] = (val >> 48) & 0xff;
  626. bytes[2] = (val >> 40) & 0xff;
  627. bytes[3] = (val >> 32) & 0xff;
  628. bytes[4] = (val >> 24) & 0xff;
  629. bytes[5] = (val >> 16) & 0xff;
  630. bytes[6] = (val >> 8) & 0xff;
  631. bytes[7] = val & 0xff;
  632. }
  633. static __inline u_int32_t
  634. _2btol(const u_int8_t *bytes)
  635. {
  636. u_int32_t rv;
  637. rv = (bytes[0] << 8) |
  638. bytes[1];
  639. return (rv);
  640. }
  641. static __inline u_int32_t
  642. _3btol(const u_int8_t *bytes)
  643. {
  644. u_int32_t rv;
  645. rv = (bytes[0] << 16) |
  646. (bytes[1] << 8) |
  647. bytes[2];
  648. return (rv);
  649. }
  650. static __inline u_int32_t
  651. _4btol(const u_int8_t *bytes)
  652. {
  653. u_int32_t rv;
  654. rv = (bytes[0] << 24) |
  655. (bytes[1] << 16) |
  656. (bytes[2] << 8) |
  657. bytes[3];
  658. return (rv);
  659. }
  660. static __inline u_int64_t
  661. _5btol(const u_int8_t *bytes)
  662. {
  663. u_int64_t rv;
  664. rv = ((u_int64_t)bytes[0] << 32) |
  665. ((u_int64_t)bytes[1] << 24) |
  666. ((u_int64_t)bytes[2] << 16) |
  667. ((u_int64_t)bytes[3] << 8) |
  668. (u_int64_t)bytes[4];
  669. return (rv);
  670. }
  671. static __inline u_int64_t
  672. _8btol(const u_int8_t *bytes)
  673. {
  674. u_int64_t rv;
  675. rv = ((u_int64_t)bytes[0] << 56) |
  676. ((u_int64_t)bytes[1] << 48) |
  677. ((u_int64_t)bytes[2] << 40) |
  678. ((u_int64_t)bytes[3] << 32) |
  679. ((u_int64_t)bytes[4] << 24) |
  680. ((u_int64_t)bytes[5] << 16) |
  681. ((u_int64_t)bytes[6] << 8) |
  682. (u_int64_t)bytes[7];
  683. return (rv);
  684. }
  685. static __inline void
  686. _lto2l(u_int32_t val, u_int8_t *bytes)
  687. {
  688. bytes[0] = val & 0xff;
  689. bytes[1] = (val >> 8) & 0xff;
  690. }
  691. static __inline void
  692. _lto3l(u_int32_t val, u_int8_t *bytes)
  693. {
  694. bytes[0] = val & 0xff;
  695. bytes[1] = (val >> 8) & 0xff;
  696. bytes[2] = (val >> 16) & 0xff;
  697. }
  698. static __inline void
  699. _lto4l(u_int32_t val, u_int8_t *bytes)
  700. {
  701. bytes[0] = val & 0xff;
  702. bytes[1] = (val >> 8) & 0xff;
  703. bytes[2] = (val >> 16) & 0xff;
  704. bytes[3] = (val >> 24) & 0xff;
  705. }
  706. static __inline u_int32_t
  707. _2ltol(const u_int8_t *bytes)
  708. {
  709. u_int32_t rv;
  710. rv = bytes[0] |
  711. (bytes[1] << 8);
  712. return (rv);
  713. }
  714. static __inline u_int32_t
  715. _3ltol(const u_int8_t *bytes)
  716. {
  717. u_int32_t rv;
  718. rv = bytes[0] |
  719. (bytes[1] << 8) |
  720. (bytes[2] << 16);
  721. return (rv);
  722. }
  723. static __inline u_int32_t
  724. _4ltol(const u_int8_t *bytes)
  725. {
  726. u_int32_t rv;
  727. rv = bytes[0] |
  728. (bytes[1] << 8) |
  729. (bytes[2] << 16) |
  730. (bytes[3] << 24);
  731. return (rv);
  732. }
  733. #endif /* _DEV_SCSIPI_SCSIPICONF_H_ */