⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scsi_target.h

📁 iscsi源代码 UNH的progect 有initiator端和target端的源码
💻 H
📖 第 1 页 / 共 2 页
字号:
     * The pointer to the /proc/scsi_target directory entry     */    struct proc_dir_entry *proc_dir;    /* proc-fs info function.     * Can be used to export driver statistics and other infos to the world     * outside the kernel ie. userspace and it also provides an interface     * to feed the driver with information. Check eata_dma_proc.c for reference     */    int (*proc_info)(char *, char **, off_t, int, int, int);	/*	 * name of the template. Must be unique so as to help identify	 * the template. I have restricted the name length to 16 chars	 * which should be sufficient for most purposes. MUST HAVE	 */	const char name[TWOBYTE];	/*	 * detect function: This function should detect the devices that	 * are present in the system. The function should return a value	 * >= 0 to signify the number of front end devices within the	 * system. A negative value should be returned whenever there is	 * an error. MUST HAVE	 */	int (* detect) (struct STT*);	/*	 * release function: This function should free up the resources	 * allocated to the device defined by the STD. The function should	 * return 0 to indicate successful release or a negative value if	 * there are some issues with the release. OPTIONAL	 */	int (* release)(struct STD*);	/*	 * xmit_response: This function is equivalent to the SCSI	 * queuecommand. The front-end should transmit the response	 * buffer and the status in the Scsi_Request struct.	 * The expectation is that this executing this command is	 * NON-BLOCKING.	 *	 * After the response is actually transmitted, the front-end	 * should call the front_end_done function in the mid-level	 * which will allow the mid-level to free up the command	 * Return 0 for success and < 0 for trouble	 * MUST HAVE	 */	int (* xmit_response)(struct SC*);	/*	 * rdy_to_xfer: This function informs the driver that data	 * buffer corresponding to the said command have now been	 * allocated and it is okay to receive data for this command.	 * This function is necessary because a SCSI target does not	 * have any control over the commands it receives. Most lower	 * level protocols have a corresponding function which informs	 * the initiator that buffers have been allocated e.g., XFER_	 * RDY in Fibre Channel. After the data is actually received	 * the low-level driver needs to call rx_data provided by the	 * mid-level in order to continue processing this command.	 * Return 0 for success and < 0 for trouble	 * This command is expected to be NON-BLOCKING.	 * MUST HAVE.	 */	int (* rdy_to_xfer)(struct SC*);	/*	 * task_mgmt_fn_done: This function informs the driver that a	 * received task management function has been completed. This	 * function is necessary because low-level protocols have some	 * means of informing the initiator about the completion of a	 * Task Management function. This function being called will	 * signify that a Task Management function is completed as far	 * as the mid-level is concerned. Any information that must be	 * stored about the command is the responsibility of the low-	 * level driver. The field SC is relevant only for ABORT tasks	 * No return value expected.	 * This function is expected to be NON-BLOCKING	 * MUST HAVE if the front-end supports ABORTs	 */	void (* task_mgmt_fn_done)(struct SM*);	/*	 * report_aen: This function is used for Asynchronous Event	 * Notification. Since the Mid-Level does not have a mechanism	 * to know about initiators logged in with low-level driver, it	 * is the responsibility of the driver to notify any/all	 * initiators about the Asynchronous Event reported.	 * 0 for success, and < 0 for trouble	 * This command is expected to be NON-BLOCKING	 * MUST HAVE if low-level protocol supports AEN	 */	void (* report_aen)(int /* MGMT FN */, __u64 /* LUN */);} Scsi_Target_Template;/* * Scsi_Target_Device: This is an internal struct that is created to define * a device list in the struct GTE. Thus one STT could potentially * correspond to multiple devices. The only thing that the front end should * actually care about is the device id. This is defined by SAM as a 64 bit * entity. I should change this one pretty soon. */typedef struct STD{	__u64		id;		/* device id */	struct STD	*next; 		/* next one in the list */	/* dev_specific: my idea behind keeping this field was that this	 * should help the front end target driver store a pointer to a	 * struct that is a super-set of the Scsi_Target_Device where it	 * stores system specific values. This should help the front-end	 * locate the front-end easily instead of doing a search every	 * time. (kind of like hostdata in Scsi_Host). Allocation and	 * deallocation of memory for it is the responsibility of the	 * front-end. THIS IS THE ONLY FIELD THAT SHOULD BE MODIFIED BY	 * THE FRONT-END DRIVER	 */	void		*dev_specific;	Scsi_Target_Template *template;	/* ptr to available functions */} Scsi_Target_Device;/* * Target_Emulator: This is the "global" target struct. All information * within the system flows from this target struct. It also serves as a * repository for all that is global to the target emulator system */typedef struct GTE{	/*	 * command_id: This is a counter to decide what command_id gets	 * assigned to a command that gets queued. 0 is not a valid command.	 * Also, command_ids can wrap around. I also assume that if command	 * _ids wrap-around, then all commands with that particular command	 * _id have already been dealt with. There is a miniscule (?) chance	 * that this may not be the case - but I do not deal with it	 */	int			command_id;	/*	 * thread_sem: semaphore to control the synchronization of	 * killing the thread	 */	struct semaphore	thread_sem;	/*	 * signal_sem: semaphore to control the killing of the signal	 * processing thread	 */	struct semaphore	signal_sem;	/*	 * sig_thr_sem: the signal thread sleeps on this semaphore	 */	struct semaphore	sig_thr_sem;	/*	 * signal_id: pointer to the signal_process_thread. Will be used	 * to kill the thread when necessary	 */	struct task_struct	*signal_id;	/*	 * target_sem: semaphore to control the mid-level thread synchronizn	 * i.e., when it sleeps and when it awakens	 */	struct semaphore	target_sem;	/*	 * thread_id: this task struct will store the pointer to the SCSI	 * Mid-level thread - useful to kill the thread when necessary	 */	struct task_struct	*thread_id;	/*	 * st_device_list: pointer to the list of devices. I have not added	 * any semaphores around this list simply because I do not expect	 * multiple devices to register simultaneously (Am I correct ?)	 */	Scsi_Target_Device	*st_device_list;	/*	 * st_target_template: pointer to the target template. Each template	 * in this list can have multiple devices	 */	Scsi_Target_Template	*st_target_template;	/* this may change */	/*	 * cmd_queue_lock: this spinlock must be acquired whenever the	 * cmd_queue is accessed.  The spinlock is essential because	 * received CDBs can get queued up in the context of an	 * interrupt handler so we have to a spinlock, not a semaphore.	 */	spinlock_t		cmd_queue_lock;	/*	 * cmd_queue: doubly linked circular queue of commands	 */	struct list_head	cmd_queue;	/*	 * msgq_start: pointer to the start of the message queue	 */	Target_Scsi_Message	*msgq_start;	/*	 * msgq_end: pointer to the end of the message queue	 */	Target_Scsi_Message	*msgq_end;	/*	 * msg_lock: spinlock for the message	 */	spinlock_t		msg_lock;} Target_Emulator;/* number of devices target currently has access to */extern int target_count;/* function prototypes *//* these are entry points provided to the low-level driver */int	register_target_template	(Scsi_Target_Template*);int	deregister_target_template	(Scsi_Target_Template*);int	scsi_target_done		(Target_Scsi_Cmnd*);int	deregister_target_front_end	(Scsi_Target_Device*);int	scsi_rx_data			(Target_Scsi_Cmnd*);int	scsi_release			(Target_Scsi_Cmnd*);Scsi_Target_Device* register_target_front_end 	(Scsi_Target_Template*);Target_Scsi_Cmnd*	rx_cmnd		(Scsi_Target_Device*, __u64,					__u64, unsigned char*, int, int, int,					Target_Scsi_Cmnd**);Target_Scsi_Message*	rx_task_mgmt_fn	(Scsi_Target_Device*,int,void*);/* * Returns 1 if any luns for this target are in use. * Returns 0 otherwise. */extern inttarget_in_use(__u32 target_id);#if !defined(list_for_each_entry)/* include/linux/list.h is out of date *//** * list_for_each_entry	-	iterate over list of given type * @pos:	the type * to use as a loop counter. * @head:	the head for your list. * @member:	the name of the list_struct within the struct. */#define list_for_each_entry(pos, head, member)				\	for (pos = list_entry((head)->next, typeof(*pos), member),	\		     prefetch(pos->member.next);			\	     &pos->member != (head); 					\	     pos = list_entry(pos->member.next, typeof(*pos), member),	\		     prefetch(pos->member.next))#endif#endif

⌨️ 快捷键说明

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