diff options
Diffstat (limited to 'include/scsi/scsi_transport.h')
-rw-r--r-- | include/scsi/scsi_transport.h | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h new file mode 100644 index 0000000000..a0458bda31 --- /dev/null +++ b/include/scsi/scsi_transport.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Transport specific attributes. + * + * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. + */ +#ifndef SCSI_TRANSPORT_H +#define SCSI_TRANSPORT_H + +#include <linux/transport_class.h> +#include <linux/blkdev.h> +#include <linux/bug.h> +#include <scsi/scsi_host.h> +#include <scsi/scsi_device.h> + +struct scsi_transport_template { + /* the attribute containers */ + struct transport_container host_attrs; + struct transport_container target_attrs; + struct transport_container device_attrs; + + /* + * If set, called from sysfs and legacy procfs rescanning code. + */ + int (*user_scan)(struct Scsi_Host *, uint, uint, u64); + + /* The size of the specific transport attribute structure (a + * space of this size will be left at the end of the + * scsi_* structure */ + int device_size; + int device_private_offset; + int target_size; + int target_private_offset; + int host_size; + /* no private offset for the host; there's an alternative mechanism */ + + /* + * True if the transport wants to use a host-based work-queue + */ + unsigned int create_work_queue : 1; + + /* + * Allows a transport to override the default error handler. + */ + void (* eh_strategy_handler)(struct Scsi_Host *); +}; + +#define transport_class_to_shost(tc) \ + dev_to_shost((tc)->parent) + + +/* Private area maintenance. The driver requested allocations come + * directly after the transport class allocations (if any). The idea + * is that you *must* call these only once. The code assumes that the + * initial values are the ones the transport specific code requires */ +static inline void +scsi_transport_reserve_target(struct scsi_transport_template * t, int space) +{ + BUG_ON(t->target_private_offset != 0); + t->target_private_offset = ALIGN(t->target_size, sizeof(void *)); + t->target_size = t->target_private_offset + space; +} +static inline void +scsi_transport_reserve_device(struct scsi_transport_template * t, int space) +{ + BUG_ON(t->device_private_offset != 0); + t->device_private_offset = ALIGN(t->device_size, sizeof(void *)); + t->device_size = t->device_private_offset + space; +} +static inline void * +scsi_transport_target_data(struct scsi_target *starget) +{ + struct Scsi_Host *shost = dev_to_shost(&starget->dev); + return (u8 *)starget->starget_data + + shost->transportt->target_private_offset; + +} +static inline void * +scsi_transport_device_data(struct scsi_device *sdev) +{ + struct Scsi_Host *shost = sdev->host; + return (u8 *)sdev->sdev_data + + shost->transportt->device_private_offset; +} + +void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q); + +#endif /* SCSI_TRANSPORT_H */ |