| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #ifndef _SCSI_SCSI_TCQ_H
 | 
					
						
							|  |  |  | #define _SCSI_SCSI_TCQ_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <linux/blkdev.h>
 | 
					
						
							|  |  |  | #include <scsi/scsi_cmnd.h>
 | 
					
						
							|  |  |  | #include <scsi/scsi_device.h>
 | 
					
						
							| 
									
										
										
										
											2006-08-30 09:45:51 -04:00
										 |  |  | #include <scsi/scsi_host.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define MSG_SIMPLE_TAG	0x20
 | 
					
						
							|  |  |  | #define MSG_HEAD_TAG	0x21
 | 
					
						
							|  |  |  | #define MSG_ORDERED_TAG	0x22
 | 
					
						
							| 
									
										
										
										
											2011-05-19 20:19:14 -07:00
										 |  |  | #define MSG_ACA_TAG	0x24	/* unsupported */
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define SCSI_NO_TAG	(-1)    /* identify no tag in use */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer.  Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
 (*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
     support.
 (*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
     an item that uses the block layer.  This includes:
     (*) Block I/O tracing.
     (*) Disk partition code.
     (*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
     (*) The SCSI layer.  As far as I can tell, even SCSI chardevs use the
     	 block layer to do scheduling.  Some drivers that use SCSI facilities -
     	 such as USB storage - end up disabled indirectly from this.
     (*) Various block-based device drivers, such as IDE and the old CDROM
     	 drivers.
     (*) MTD blockdev handling and FTL.
     (*) JFFS - which uses set_bdev_super(), something it could avoid doing by
     	 taking a leaf out of JFFS2's book.
 (*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
     linux/elevator.h contingent on CONFIG_BLOCK being set.  sector_div() is,
     however, still used in places, and so is still available.
 (*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
     parts of linux/fs.h.
 (*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
 (*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
 (*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
     is not enabled.
 (*) fs/no-block.c is created to hold out-of-line stubs and things that are
     required when CONFIG_BLOCK is not set:
     (*) Default blockdev file operations (to give error ENODEV on opening).
 (*) Makes some /proc changes:
     (*) /proc/devices does not list any blockdevs.
     (*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
 (*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
 (*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
     given command other than Q_SYNC or if a special device is specified.
 (*) In init/do_mounts.c, no reference is made to the blockdev routines if
     CONFIG_BLOCK is not defined.  This does not prohibit NFS roots or JFFS2.
 (*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
     error ENOSYS by way of cond_syscall if so).
 (*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
     CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
											
										 
											2006-09-30 20:45:40 +02:00
										 |  |  | #ifdef CONFIG_BLOCK
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * scsi_get_tag_type - get the type of tag the device supports | 
					
						
							|  |  |  |  * @sdev:	the scsi device | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Notes: | 
					
						
							|  |  |  |  *	If the drive only supports simple tags, returns MSG_SIMPLE_TAG | 
					
						
							|  |  |  |  *	if it supports all tag types, returns MSG_ORDERED_TAG. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline int scsi_get_tag_type(struct scsi_device *sdev) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!sdev->tagged_supported) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	if (sdev->ordered_tags) | 
					
						
							|  |  |  | 		return MSG_ORDERED_TAG; | 
					
						
							|  |  |  | 	if (sdev->simple_tags) | 
					
						
							|  |  |  | 		return MSG_SIMPLE_TAG; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void scsi_set_tag_type(struct scsi_device *sdev, int tag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (tag) { | 
					
						
							|  |  |  | 	case MSG_ORDERED_TAG: | 
					
						
							|  |  |  | 		sdev->ordered_tags = 1; | 
					
						
							|  |  |  | 		/* fall through */ | 
					
						
							|  |  |  | 	case MSG_SIMPLE_TAG: | 
					
						
							|  |  |  | 		sdev->simple_tags = 1; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 0: | 
					
						
							|  |  |  | 		/* fall through */ | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		sdev->ordered_tags = 0; | 
					
						
							|  |  |  | 		sdev->simple_tags = 0; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * scsi_activate_tcq - turn on tag command queueing | 
					
						
							|  |  |  |  * @SDpnt:	device to turn on TCQ for | 
					
						
							|  |  |  |  * @depth:	queue depth | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Notes: | 
					
						
							|  |  |  |  *	Eventually, I hope depth would be the maximum depth | 
					
						
							|  |  |  |  *	the device could cope with and the real queue depth | 
					
						
							|  |  |  |  *	would be adjustable from 0 to depth. | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!sdev->tagged_supported) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!blk_queue_tagged(sdev->request_queue)) | 
					
						
							| 
									
										
										
										
											2006-08-30 09:45:51 -04:00
										 |  |  | 		blk_queue_init_tags(sdev->request_queue, depth, | 
					
						
							|  |  |  | 				    sdev->host->bqt); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), depth); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * scsi_deactivate_tcq - turn off tag command queueing | 
					
						
							|  |  |  |  * @SDpnt:	device to turn off TCQ for | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (blk_queue_tagged(sdev->request_queue)) | 
					
						
							|  |  |  | 		blk_queue_free_tags(sdev->request_queue); | 
					
						
							|  |  |  | 	scsi_adjust_queue_depth(sdev, 0, depth); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * scsi_populate_tag_msg - place a tag message in a buffer | 
					
						
							|  |  |  |  * @SCpnt:	pointer to the Scsi_Cmnd for the tag | 
					
						
							|  |  |  |  * @msg:	pointer to the area to place the tag | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Notes: | 
					
						
							|  |  |  |  *	designed to create the correct type of tag message for the  | 
					
						
							|  |  |  |  *	particular request.  Returns the size of the tag message. | 
					
						
							|  |  |  |  *	May return 0 if TCQ is disabled for this device. | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |         struct request *req = cmd->request; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (blk_rq_tagged(req)) { | 
					
						
							| 
									
										
										
										
											2010-09-03 11:56:16 +02:00
										 |  |  | 		*msg++ = MSG_SIMPLE_TAG; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |         	*msg++ = req->tag; | 
					
						
							|  |  |  |         	return 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * scsi_find_tag - find a tagged command by device | 
					
						
							|  |  |  |  * @SDpnt:	pointer to the ScSI device | 
					
						
							|  |  |  |  * @tag:	the tag number | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Notes: | 
					
						
							|  |  |  |  *	Only works with tags allocated by the generic blk layer. | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         struct request *req; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (tag != SCSI_NO_TAG) { | 
					
						
							|  |  |  |         	req = blk_queue_find_tag(sdev->request_queue, tag); | 
					
						
							|  |  |  | 	        return req ? (struct scsi_cmnd *)req->special : NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* single command, look in space */ | 
					
						
							|  |  |  | 	return sdev->current_cmnd; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-30 09:45:51 -04:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * scsi_init_shared_tag_map - create a shared tag map | 
					
						
							|  |  |  |  * @shost:	the host to share the tag map among all devices | 
					
						
							|  |  |  |  * @depth:	the total depth of the map | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2006-09-01 09:28:48 -04:00
										 |  |  | static inline int scsi_init_shared_tag_map(struct Scsi_Host *shost, int depth) | 
					
						
							| 
									
										
										
										
											2006-08-30 09:45:51 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-10-27 19:20:59 +01:00
										 |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * If the shared tag map isn't already initialized, do it now. | 
					
						
							|  |  |  | 	 * This saves callers from having to check ->bqt when setting up | 
					
						
							|  |  |  | 	 * devices on the shared host (for libata) | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (!shost->bqt) { | 
					
						
							|  |  |  | 		shost->bqt = blk_init_tags(depth); | 
					
						
							|  |  |  | 		if (!shost->bqt) | 
					
						
							|  |  |  | 			return -ENOMEM; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2006-08-30 09:45:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-04 08:27:25 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * scsi_host_find_tag - find the tagged command by host | 
					
						
							|  |  |  |  * @shost:	pointer to scsi_host | 
					
						
							|  |  |  |  * @tag:	tag of the scsi_cmnd | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Notes: | 
					
						
							|  |  |  |  *	Only works with tags allocated by the generic blk layer. | 
					
						
							|  |  |  |  **/ | 
					
						
							|  |  |  | static inline struct scsi_cmnd *scsi_host_find_tag(struct Scsi_Host *shost, | 
					
						
							|  |  |  | 						int tag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct request *req; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (tag != SCSI_NO_TAG) { | 
					
						
							|  |  |  | 		req = blk_map_queue_find_tag(shost->bqt, tag); | 
					
						
							|  |  |  | 		return req ? (struct scsi_cmnd *)req->special : NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												[PATCH] BLOCK: Make it possible to disable the block layer [try #6]
Make it possible to disable the block layer.  Not all embedded devices require
it, some can make do with just JFFS2, NFS, ramfs, etc - none of which require
the block layer to be present.
This patch does the following:
 (*) Introduces CONFIG_BLOCK to disable the block layer, buffering and blockdev
     support.
 (*) Adds dependencies on CONFIG_BLOCK to any configuration item that controls
     an item that uses the block layer.  This includes:
     (*) Block I/O tracing.
     (*) Disk partition code.
     (*) All filesystems that are block based, eg: Ext3, ReiserFS, ISOFS.
     (*) The SCSI layer.  As far as I can tell, even SCSI chardevs use the
     	 block layer to do scheduling.  Some drivers that use SCSI facilities -
     	 such as USB storage - end up disabled indirectly from this.
     (*) Various block-based device drivers, such as IDE and the old CDROM
     	 drivers.
     (*) MTD blockdev handling and FTL.
     (*) JFFS - which uses set_bdev_super(), something it could avoid doing by
     	 taking a leaf out of JFFS2's book.
 (*) Makes most of the contents of linux/blkdev.h, linux/buffer_head.h and
     linux/elevator.h contingent on CONFIG_BLOCK being set.  sector_div() is,
     however, still used in places, and so is still available.
 (*) Also made contingent are the contents of linux/mpage.h, linux/genhd.h and
     parts of linux/fs.h.
 (*) Makes a number of files in fs/ contingent on CONFIG_BLOCK.
 (*) Makes mm/bounce.c (bounce buffering) contingent on CONFIG_BLOCK.
 (*) set_page_dirty() doesn't call __set_page_dirty_buffers() if CONFIG_BLOCK
     is not enabled.
 (*) fs/no-block.c is created to hold out-of-line stubs and things that are
     required when CONFIG_BLOCK is not set:
     (*) Default blockdev file operations (to give error ENODEV on opening).
 (*) Makes some /proc changes:
     (*) /proc/devices does not list any blockdevs.
     (*) /proc/diskstats and /proc/partitions are contingent on CONFIG_BLOCK.
 (*) Makes some compat ioctl handling contingent on CONFIG_BLOCK.
 (*) If CONFIG_BLOCK is not defined, makes sys_quotactl() return -ENODEV if
     given command other than Q_SYNC or if a special device is specified.
 (*) In init/do_mounts.c, no reference is made to the blockdev routines if
     CONFIG_BLOCK is not defined.  This does not prohibit NFS roots or JFFS2.
 (*) The bdflush, ioprio_set and ioprio_get syscalls can now be absent (return
     error ENOSYS by way of cond_syscall if so).
 (*) The seclvl_bd_claim() and seclvl_bd_release() security calls do nothing if
     CONFIG_BLOCK is not set, since they can't then happen.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
											
										 
											2006-09-30 20:45:40 +02:00
										 |  |  | #endif /* CONFIG_BLOCK */
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #endif /* _SCSI_SCSI_TCQ_H */
 |