xref: /OK3568_Linux_fs/kernel/include/scsi/scsi_transport.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *  Transport specific attributes.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *  Copyright (c) 2003 Silicon Graphics, Inc.  All rights reserved.
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun #ifndef SCSI_TRANSPORT_H
8*4882a593Smuzhiyun #define SCSI_TRANSPORT_H
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/transport_class.h>
11*4882a593Smuzhiyun #include <linux/blkdev.h>
12*4882a593Smuzhiyun #include <linux/bug.h>
13*4882a593Smuzhiyun #include <scsi/scsi_host.h>
14*4882a593Smuzhiyun #include <scsi/scsi_device.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun struct scsi_transport_template {
17*4882a593Smuzhiyun 	/* the attribute containers */
18*4882a593Smuzhiyun 	struct transport_container host_attrs;
19*4882a593Smuzhiyun 	struct transport_container target_attrs;
20*4882a593Smuzhiyun 	struct transport_container device_attrs;
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun 	/*
23*4882a593Smuzhiyun 	 * If set, called from sysfs and legacy procfs rescanning code.
24*4882a593Smuzhiyun 	 */
25*4882a593Smuzhiyun 	int (*user_scan)(struct Scsi_Host *, uint, uint, u64);
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun 	/* The size of the specific transport attribute structure (a
28*4882a593Smuzhiyun 	 * space of this size will be left at the end of the
29*4882a593Smuzhiyun 	 * scsi_* structure */
30*4882a593Smuzhiyun 	int	device_size;
31*4882a593Smuzhiyun 	int	device_private_offset;
32*4882a593Smuzhiyun 	int	target_size;
33*4882a593Smuzhiyun 	int	target_private_offset;
34*4882a593Smuzhiyun 	int	host_size;
35*4882a593Smuzhiyun 	/* no private offset for the host; there's an alternative mechanism */
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	/*
38*4882a593Smuzhiyun 	 * True if the transport wants to use a host-based work-queue
39*4882a593Smuzhiyun 	 */
40*4882a593Smuzhiyun 	unsigned int create_work_queue : 1;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun 	/*
43*4882a593Smuzhiyun 	 * Allows a transport to override the default error handler.
44*4882a593Smuzhiyun 	 */
45*4882a593Smuzhiyun 	void (* eh_strategy_handler)(struct Scsi_Host *);
46*4882a593Smuzhiyun };
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun #define transport_class_to_shost(tc) \
49*4882a593Smuzhiyun 	dev_to_shost((tc)->parent)
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun /* Private area maintenance. The driver requested allocations come
53*4882a593Smuzhiyun  * directly after the transport class allocations (if any).  The idea
54*4882a593Smuzhiyun  * is that you *must* call these only once.  The code assumes that the
55*4882a593Smuzhiyun  * initial values are the ones the transport specific code requires */
56*4882a593Smuzhiyun static inline void
scsi_transport_reserve_target(struct scsi_transport_template * t,int space)57*4882a593Smuzhiyun scsi_transport_reserve_target(struct scsi_transport_template * t, int space)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun 	BUG_ON(t->target_private_offset != 0);
60*4882a593Smuzhiyun 	t->target_private_offset = ALIGN(t->target_size, sizeof(void *));
61*4882a593Smuzhiyun 	t->target_size = t->target_private_offset + space;
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun static inline void
scsi_transport_reserve_device(struct scsi_transport_template * t,int space)64*4882a593Smuzhiyun scsi_transport_reserve_device(struct scsi_transport_template * t, int space)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun 	BUG_ON(t->device_private_offset != 0);
67*4882a593Smuzhiyun 	t->device_private_offset = ALIGN(t->device_size, sizeof(void *));
68*4882a593Smuzhiyun 	t->device_size = t->device_private_offset + space;
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun static inline void *
scsi_transport_target_data(struct scsi_target * starget)71*4882a593Smuzhiyun scsi_transport_target_data(struct scsi_target *starget)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
74*4882a593Smuzhiyun 	return (u8 *)starget->starget_data
75*4882a593Smuzhiyun 		+ shost->transportt->target_private_offset;
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun static inline void *
scsi_transport_device_data(struct scsi_device * sdev)79*4882a593Smuzhiyun scsi_transport_device_data(struct scsi_device *sdev)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	struct Scsi_Host *shost = sdev->host;
82*4882a593Smuzhiyun 	return (u8 *)sdev->sdev_data
83*4882a593Smuzhiyun 		+ shost->transportt->device_private_offset;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun #endif /* SCSI_TRANSPORT_H */
89