| /* | 
 |  * This file is part of the UCB release of Plan 9. It is subject to the license | 
 |  * terms in the LICENSE file found in the top-level directory of this | 
 |  * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No | 
 |  * part of the UCB release of Plan 9, including this file, may be copied, | 
 |  * modified, propagated, or distributed except according to the terms contained | 
 |  * in the LICENSE file. | 
 |  */ | 
 |  | 
 | /* | 
 |  * Storage Device. | 
 |  */ | 
 | struct devconf; | 
 | struct sdev; | 
 | struct sdifc; | 
 | struct sdio; | 
 | struct sdpart; | 
 | struct sdperm; | 
 | struct sdreq; | 
 | struct sdunit; | 
 |  | 
 | struct sdperm { | 
 | 	char *name; | 
 | 	char *user; | 
 | 	uint32_t perm; | 
 | }; | 
 |  | 
 | struct sdpart { | 
 | 	uint64_t start; | 
 | 	uint64_t end; | 
 | 	struct sdperm sdperm; | 
 | 	int valid; | 
 | 	uint32_t vers; | 
 | }; | 
 |  | 
 | struct sdunit { | 
 | 	struct sdev *dev; | 
 | 	int subno; | 
 | 	unsigned char inquiry[255]; /* format follows SCSI spec */ | 
 | 	unsigned char sense[18];    /* format follows SCSI spec */ | 
 | 	struct sdperm sdperm; | 
 |  | 
 | 	qlock_t ctl; | 
 | 	uint64_t sectors; | 
 | 	uint32_t secsize; | 
 | 	struct sdpart *part; /* nil or array of size npart */ | 
 | 	int npart; | 
 | 	uint32_t vers; | 
 | 	struct sdperm ctlperm; | 
 |  | 
 | 	qlock_t raw;       /* raw read or write in progress */ | 
 | 	uint32_t rawinuse; /* really just a test-and-set */ | 
 | 	int state; | 
 | 	struct sdreq *req; | 
 | 	struct sdperm rawperm; | 
 | }; | 
 |  | 
 | /* | 
 |  * Each controller is represented by a struct sdev. | 
 |  */ | 
 | struct sdev { | 
 | 	struct kref r;     /* Number of callers using device */ | 
 | 	struct sdifc *ifc; /* pnp/legacy */ | 
 | 	void *ctlr; | 
 | 	int idno; | 
 | 	char name[8]; | 
 | 	struct sdev *next; | 
 |  | 
 | 	qlock_t ql; /* enable/disable */ | 
 | 	int enabled; | 
 | 	int nunit;        /* Number of units */ | 
 | 	qlock_t unitlock; /* `Loading' of units */ | 
 | 	int *unitflg;     /* Unit flags */ | 
 | 	struct sdunit **unit; | 
 | }; | 
 |  | 
 | struct sdifc { | 
 | 	char *name; | 
 |  | 
 | 	struct sdev *(*pnp)(void); | 
 | 	struct sdev *(*legacy)(int, int); | 
 | 	int (*enable)(struct sdev *); | 
 | 	int (*disable)(struct sdev *); | 
 |  | 
 | 	int (*verify)(struct sdunit *); | 
 | 	int (*online)(struct sdunit *); | 
 | 	int (*rio)(struct sdreq *); | 
 | 	int (*rctl)(struct sdunit *, char *, int); | 
 | 	int (*wctl)(struct sdunit *, struct cmdbuf *); | 
 |  | 
 | 	int32_t (*bio)(struct sdunit *, int, int, void *, int32_t, uint64_t); | 
 | 	struct sdev *(*probe)(struct devconf *); | 
 | 	void (*clear)(struct sdev *); | 
 | 	char *(*rtopctl)(struct sdev *, char *, char *); | 
 | 	int (*wtopctl)(struct sdev *, struct cmdbuf *); | 
 | }; | 
 |  | 
 | struct sdreq { | 
 | 	struct sdunit *unit; | 
 | 	int lun; | 
 | 	int write; | 
 | 	unsigned char cmd[16]; | 
 | 	int clen; | 
 | 	void *data; | 
 | 	int dlen; | 
 |  | 
 | 	int flags; | 
 |  | 
 | 	int status; | 
 | 	int32_t rlen; | 
 | 	unsigned char sense[256]; | 
 | }; | 
 |  | 
 | enum { | 
 | 	SDnosense = 0x00000001, | 
 | 	SDvalidsense = 0x00010000, | 
 |  | 
 | 	SDinq0periphqual = 0xe0, | 
 | 	SDinq0periphtype = 0x1f, | 
 | 	SDinq1removable = 0x80, | 
 |  | 
 | 	/* periphtype values */ | 
 | 	SDperdisk = 0, /* Direct access (disk) */ | 
 | 	SDpertape = 1, /* Sequential eg, tape */ | 
 | 	SDperpr = 2,   /* Printer */ | 
 | 	SDperworm = 4, /* Worm */ | 
 | 	SDpercd = 5,   /* CD-ROM */ | 
 | 	SDpermo = 7,   /* rewriteable MO */ | 
 | 	SDperjuke = 8, /* medium-changer */ | 
 | }; | 
 |  | 
 | enum { | 
 | 	SDretry = -5, /* internal to controllers */ | 
 | 	SDmalloc = -4, | 
 | 	SDeio = -3, | 
 | 	SDtimeout = -2, | 
 | 	SDnostatus = -1, | 
 |  | 
 | 	SDok = 0, | 
 |  | 
 | 	SDcheck = 0x02, /* check condition */ | 
 | 	SDbusy = 0x08,  /* busy */ | 
 |  | 
 | 	SDmaxio = 2048 * 1024, | 
 | 	SDnpart = 16, | 
 | }; | 
 |  | 
 | /* | 
 |  * mmc/sd/sdio host controller interface | 
 |  */ | 
 |  | 
 | struct sdio { | 
 | 	char *name; | 
 | 	int (*init)(void); | 
 | 	void (*enable)(void); | 
 | 	int (*inquiry)(char *, int); | 
 | 	int (*cmd)(uint32_t, uint32_t, uint32_t *); | 
 | 	void (*iosetup)(int, void *, int, int); | 
 | 	void (*io)(int, unsigned char *, int); | 
 | }; | 
 |  | 
 | extern struct sdio sdio; | 
 |  | 
 | /* devsd.c */ | 
 | extern void sdadddevs(struct sdev *); | 
 | extern void sdaddconf(struct sdunit *); | 
 | extern void sdaddallconfs(void (*f)(struct sdunit *)); | 
 | extern void sdaddpart(struct sdunit *, char *, uint64_t, uint64_t); | 
 | extern int sdsetsense(struct sdreq *, int, int, int, int); | 
 | extern int sdmodesense(struct sdreq *, unsigned char *, void *, int); | 
 | extern int sdfakescsi(struct sdreq *, void *, int); | 
 |  | 
 | /* sdscsi.c */ | 
 | extern int scsiverify(struct sdunit *); | 
 | extern int scsionline(struct sdunit *); | 
 | extern int32_t scsibio(struct sdunit *, int, int, void *, int32_t, uint64_t); | 
 | extern struct sdev *scsiid(struct sdev *, struct sdifc *); | 
 |  | 
 | /* | 
 |  *  hardware info about a device | 
 |  */ | 
 | struct devport { | 
 | 	uint32_t port; | 
 | 	int size; | 
 | }; | 
 |  | 
 | struct devconf { | 
 | 	uint32_t intnum;       /* interrupt number */ | 
 | 	char *type;            /* card type, malloced */ | 
 | 	int nports;            /* Number of ports */ | 
 | 	struct devport *ports; /* The ports themselves */ | 
 | }; |