esp_scsi.h

来自「linux 内核源代码」· C头文件 代码 · 共 559 行 · 第 1/2 页

H
559
字号
	struct completion	*eh_done;};/* XXX make this configurable somehow XXX */#define ESP_DEFAULT_TAGS	16#define ESP_MAX_TARGET		16#define ESP_MAX_LUN		8#define ESP_MAX_TAG		256struct esp_lun_data {	struct esp_cmd_entry	*non_tagged_cmd;	int			num_tagged;	int			hold;	struct esp_cmd_entry	*tagged_cmds[ESP_MAX_TAG];};struct esp_target_data {	/* These are the ESP_STP, ESP_SOFF, and ESP_CFG3 register values which	 * match the currently negotiated settings for this target.  The SCSI	 * protocol values are maintained in spi_{offset,period,wide}(starget).	 */	u8			esp_period;	u8			esp_offset;	u8			esp_config3;	u8			flags;#define ESP_TGT_WIDE		0x01#define ESP_TGT_DISCONNECT	0x02#define ESP_TGT_NEGO_WIDE	0x04#define ESP_TGT_NEGO_SYNC	0x08#define ESP_TGT_CHECK_NEGO	0x40#define ESP_TGT_BROKEN		0x80	/* When ESP_TGT_CHECK_NEGO is set, on the next scsi command to this	 * device we will try to negotiate the following parameters.	 */	u8			nego_goal_period;	u8			nego_goal_offset;	u8			nego_goal_width;	u8			nego_goal_tags;	struct scsi_target	*starget;};struct esp_event_ent {	u8			type;#define ESP_EVENT_TYPE_EVENT	0x01#define ESP_EVENT_TYPE_CMD	0x02	u8			val;	u8			sreg;	u8			seqreg;	u8			sreg2;	u8			ireg;	u8			select_state;	u8			event;	u8			__pad;};struct esp;struct esp_driver_ops {	/* Read and write the ESP 8-bit registers.  On some	 * applications of the ESP chip the registers are at 4-byte	 * instead of 1-byte intervals.	 */	void (*esp_write8)(struct esp *esp, u8 val, unsigned long reg);	u8 (*esp_read8)(struct esp *esp, unsigned long reg);	/* Map and unmap DMA memory.  Eventually the driver will be	 * converted to the generic DMA API as soon as SBUS is able to	 * cope with that.  At such time we can remove this.	 */	dma_addr_t (*map_single)(struct esp *esp, void *buf,				 size_t sz, int dir);	int (*map_sg)(struct esp *esp, struct scatterlist *sg,		      int num_sg, int dir);	void (*unmap_single)(struct esp *esp, dma_addr_t addr,			     size_t sz, int dir);	void (*unmap_sg)(struct esp *esp, struct scatterlist *sg,			 int num_sg, int dir);	/* Return non-zero if there is an IRQ pending.  Usually this	 * status bit lives in the DMA controller sitting in front of	 * the ESP.  This has to be accurate or else the ESP interrupt	 * handler will not run.	 */	int (*irq_pending)(struct esp *esp);	/* Reset the DMA engine entirely.  On return, ESP interrupts	 * should be enabled.  Often the interrupt enabling is	 * controlled in the DMA engine.	 */	void (*reset_dma)(struct esp *esp);	/* Drain any pending DMA in the DMA engine after a transfer.	 * This is for writes to memory.	 */	void (*dma_drain)(struct esp *esp);	/* Invalidate the DMA engine after a DMA transfer.  */	void (*dma_invalidate)(struct esp *esp);	/* Setup an ESP command that will use a DMA transfer.	 * The 'esp_count' specifies what transfer length should be	 * programmed into the ESP transfer counter registers, whereas	 * the 'dma_count' is the length that should be programmed into	 * the DMA controller.  Usually they are the same.  If 'write'	 * is non-zero, this transfer is a write into memory.  'cmd'	 * holds the ESP command that should be issued by calling	 * scsi_esp_cmd() at the appropriate time while programming	 * the DMA hardware.	 */	void (*send_dma_cmd)(struct esp *esp, u32 dma_addr, u32 esp_count,			     u32 dma_count, int write, u8 cmd);	/* Return non-zero if the DMA engine is reporting an error	 * currently.	 */	int (*dma_error)(struct esp *esp);};#define ESP_MAX_MSG_SZ		8#define ESP_EVENT_LOG_SZ	32#define ESP_QUICKIRQ_LIMIT	100#define ESP_RESELECT_TAG_LIMIT	2500struct esp {	void __iomem		*regs;	void __iomem		*dma_regs;	const struct esp_driver_ops *ops;	struct Scsi_Host	*host;	void			*dev;	struct esp_cmd_entry	*active_cmd;	struct list_head	queued_cmds;	struct list_head	active_cmds;	u8			*command_block;	dma_addr_t		command_block_dma;	unsigned int		data_dma_len;	/* The following are used to determine the cause of an IRQ. Upon every	 * IRQ entry we synchronize these with the hardware registers.	 */	u8			sreg;	u8			seqreg;	u8			sreg2;	u8			ireg;	u32			prev_hme_dmacsr;	u8			prev_soff;	u8			prev_stp;	u8			prev_cfg3;	u8			__pad;	struct list_head	esp_cmd_pool;	struct esp_target_data	target[ESP_MAX_TARGET];	int			fifo_cnt;	u8			fifo[16];	struct esp_event_ent	esp_event_log[ESP_EVENT_LOG_SZ];	int			esp_event_cur;	u8			msg_out[ESP_MAX_MSG_SZ];	int			msg_out_len;	u8			msg_in[ESP_MAX_MSG_SZ];	int			msg_in_len;	u8			bursts;	u8			config1;	u8			config2;	u8			scsi_id;	u32			scsi_id_mask;	enum esp_rev		rev;	u32			flags;#define ESP_FLAG_DIFFERENTIAL	0x00000001#define ESP_FLAG_RESETTING	0x00000002#define ESP_FLAG_DOING_SLOWCMD	0x00000004#define ESP_FLAG_WIDE_CAPABLE	0x00000008#define ESP_FLAG_QUICKIRQ_CHECK	0x00000010	u8			select_state;#define ESP_SELECT_NONE		0x00 /* Not selecting */#define ESP_SELECT_BASIC	0x01 /* Select w/o MSGOUT phase */#define ESP_SELECT_MSGOUT	0x02 /* Select with MSGOUT */	/* When we are not selecting, we are expecting an event.  */	u8			event;#define ESP_EVENT_NONE		0x00#define ESP_EVENT_CMD_START	0x01#define ESP_EVENT_CMD_DONE	0x02#define ESP_EVENT_DATA_IN	0x03#define ESP_EVENT_DATA_OUT	0x04#define ESP_EVENT_DATA_DONE	0x05#define ESP_EVENT_MSGIN		0x06#define ESP_EVENT_MSGIN_MORE	0x07#define ESP_EVENT_MSGIN_DONE	0x08#define ESP_EVENT_MSGOUT	0x09#define ESP_EVENT_MSGOUT_DONE	0x0a#define ESP_EVENT_STATUS	0x0b#define ESP_EVENT_FREE_BUS	0x0c#define ESP_EVENT_CHECK_PHASE	0x0d#define ESP_EVENT_RESET		0x10	/* Probed in esp_get_clock_params() */	u32			cfact;	u32			cfreq;	u32			ccycle;	u32			ctick;	u32			neg_defp;	u32			sync_defp;	/* Computed in esp_reset_esp() */	u32			max_period;	u32			min_period;	u32			radelay;	/* Slow command state.  */	u8			*cmd_bytes_ptr;	int			cmd_bytes_left;	struct completion	*eh_reset;	struct sbus_dma		*dma;};/* A front-end driver for the ESP chip should do the following in * it's device probe routine: * 1) Allocate the host and private area using scsi_host_alloc() *    with size 'sizeof(struct esp)'.  The first argument to *    scsi_host_alloc() should be &scsi_esp_template. * 2) Set host->max_id as appropriate. * 3) Set esp->host to the scsi_host itself, and esp->dev *    to the device object pointer. * 4) Hook up esp->ops to the front-end implementation. * 5) If the ESP chip supports wide transfers, set ESP_FLAG_WIDE_CAPABLE *    in esp->flags. * 6) Map the DMA and ESP chip registers. * 7) DMA map the ESP command block, store the DMA address *    in esp->command_block_dma. * 8) Register the scsi_esp_intr() interrupt handler. * 9) Probe for and provide the following chip properties: *    esp->scsi_id (assign to esp->host->this_id too) *    esp->scsi_id_mask *    If ESP bus is differential, set ESP_FLAG_DIFFERENTIAL *    esp->cfreq *    DMA burst bit mask in esp->bursts, if necessary * 10) Perform any actions necessary before the ESP device can *     be programmed for the first time.  On some configs, for *     example, the DMA engine has to be reset before ESP can *     be programmed. * 11) If necessary, call dev_set_drvdata() as needed. * 12) Call scsi_esp_register() with prepared 'esp' structure *     and a device pointer if possible. * 13) Check scsi_esp_register() return value, release all resources *     if an error was returned. */extern struct scsi_host_template scsi_esp_template;extern int scsi_esp_register(struct esp *, struct device *);extern void scsi_esp_unregister(struct esp *);extern irqreturn_t scsi_esp_intr(int, void *);extern void scsi_esp_cmd(struct esp *, u8);#endif /* !(_ESP_SCSI_H) */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?