152c9ce25SScott Long /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3bec9534dSPedro F. Giffuni * 452c9ce25SScott Long * Copyright 2009 Scott Long 552c9ce25SScott Long * All rights reserved. 652c9ce25SScott Long * 752c9ce25SScott Long * Redistribution and use in source and binary forms, with or without 852c9ce25SScott Long * modification, are permitted provided that the following conditions 952c9ce25SScott Long * are met: 1052c9ce25SScott Long * 1. Redistributions of source code must retain the above copyright 1152c9ce25SScott Long * notice, this list of conditions, and the following disclaimer, 1252c9ce25SScott Long * without modification, immediately at the beginning of the file. 1352c9ce25SScott Long * 2. The name of the author may not be used to endorse or promote products 1452c9ce25SScott Long * derived from this software without specific prior written permission. 1552c9ce25SScott Long * 1652c9ce25SScott Long * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1752c9ce25SScott Long * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1852c9ce25SScott Long * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1952c9ce25SScott Long * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 2052c9ce25SScott Long * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2152c9ce25SScott Long * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2252c9ce25SScott Long * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2352c9ce25SScott Long * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2452c9ce25SScott Long * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2552c9ce25SScott Long * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2652c9ce25SScott Long * SUCH DAMAGE. 2752c9ce25SScott Long */ 2852c9ce25SScott Long 2952c9ce25SScott Long #ifndef _CAM_CAM_XPT_INTERNAL_H 3052c9ce25SScott Long #define _CAM_CAM_XPT_INTERNAL_H 1 3152c9ce25SScott Long 32227d67aaSAlexander Motin #include <sys/taskqueue.h> 33227d67aaSAlexander Motin 3452c9ce25SScott Long /* Forward Declarations */ 3552c9ce25SScott Long struct cam_eb; 3652c9ce25SScott Long struct cam_et; 3752c9ce25SScott Long struct cam_ed; 3852c9ce25SScott Long 3952c9ce25SScott Long typedef struct cam_ed * (*xpt_alloc_device_func)(struct cam_eb *bus, 4052c9ce25SScott Long struct cam_et *target, 4152c9ce25SScott Long lun_id_t lun_id); 42f98d7a47SAlexander Motin typedef void (*xpt_release_device_func)(struct cam_ed *device); 4352c9ce25SScott Long typedef void (*xpt_action_func)(union ccb *start_ccb); 447af2f2c8SWarner Losh typedef void (*xpt_dev_async_func)(uint32_t async_code, 4552c9ce25SScott Long struct cam_eb *bus, 4652c9ce25SScott Long struct cam_et *target, 4752c9ce25SScott Long struct cam_ed *device, 4852c9ce25SScott Long void *async_arg); 4957079b17SAlexander Motin typedef void (*xpt_announce_periph_func)(struct cam_periph *periph); 505d01277fSScott Long typedef void (*xpt_announce_periph_sbuf_func)(struct cam_periph *periph, struct sbuf *sbuf); 5152c9ce25SScott Long 52ded2b706SWarner Losh struct xpt_xport_ops { 5352c9ce25SScott Long xpt_alloc_device_func alloc_device; 5452c9ce25SScott Long xpt_release_device_func reldev; 5552c9ce25SScott Long xpt_action_func action; 5652c9ce25SScott Long xpt_dev_async_func async; 575d01277fSScott Long xpt_announce_periph_sbuf_func announce_sbuf; 5852c9ce25SScott Long }; 5952c9ce25SScott Long 60ded2b706SWarner Losh struct xpt_xport { 61ded2b706SWarner Losh cam_xport xport; 62ded2b706SWarner Losh const char *name; 63ded2b706SWarner Losh struct xpt_xport_ops *ops; 64ded2b706SWarner Losh }; 65ded2b706SWarner Losh 66ded2b706SWarner Losh SET_DECLARE(cam_xpt_xport_set, struct xpt_xport); 67ded2b706SWarner Losh #define CAM_XPT_XPORT(data) \ 68ded2b706SWarner Losh DATA_SET(cam_xpt_xport_set, data) 69ded2b706SWarner Losh 7008f13879SWarner Losh typedef void (*xpt_proto_announce_func)(struct cam_ed *); 715d01277fSScott Long typedef void (*xpt_proto_announce_sbuf_func)(struct cam_ed *, struct sbuf *); 7208f13879SWarner Losh typedef void (*xpt_proto_debug_out_func)(union ccb *); 7308f13879SWarner Losh 7408f13879SWarner Losh struct xpt_proto_ops { 755d01277fSScott Long xpt_proto_announce_sbuf_func announce_sbuf; 765d01277fSScott Long xpt_proto_announce_sbuf_func denounce_sbuf; 7708f13879SWarner Losh xpt_proto_debug_out_func debug_out; 7808f13879SWarner Losh }; 7908f13879SWarner Losh 8008f13879SWarner Losh struct xpt_proto { 8108f13879SWarner Losh cam_proto proto; 8208f13879SWarner Losh const char *name; 8308f13879SWarner Losh struct xpt_proto_ops *ops; 8408f13879SWarner Losh }; 8508f13879SWarner Losh 8608f13879SWarner Losh SET_DECLARE(cam_xpt_proto_set, struct xpt_proto); 8708f13879SWarner Losh #define CAM_XPT_PROTO(data) \ 8808f13879SWarner Losh DATA_SET(cam_xpt_proto_set, data) 8908f13879SWarner Losh 9052c9ce25SScott Long /* 9152c9ce25SScott Long * The CAM EDT (Existing Device Table) contains the device information for 92db4fcadfSConrad Meyer * all devices for all buses in the system. The table contains a 9352c9ce25SScott Long * cam_ed structure for each device on the bus. 9452c9ce25SScott Long */ 9552c9ce25SScott Long struct cam_ed { 96227d67aaSAlexander Motin cam_pinfo devq_entry; 9752c9ce25SScott Long TAILQ_ENTRY(cam_ed) links; 9852c9ce25SScott Long struct cam_et *target; 9952c9ce25SScott Long struct cam_sim *sim; 10052c9ce25SScott Long lun_id_t lun_id; 10152c9ce25SScott Long struct cam_ccbq ccbq; /* Queue of pending ccbs */ 10252c9ce25SScott Long struct async_list asyncs; /* Async callback info for this B/T/L */ 10352c9ce25SScott Long struct periph_list periphs; /* All attached devices */ 10452c9ce25SScott Long u_int generation; /* Generation number */ 10552c9ce25SScott Long void *quirk; /* Oddities about this device */ 10652c9ce25SScott Long u_int maxtags; 10752c9ce25SScott Long u_int mintags; 10852c9ce25SScott Long cam_proto protocol; 10952c9ce25SScott Long u_int protocol_version; 11052c9ce25SScott Long cam_xport transport; 11152c9ce25SScott Long u_int transport_version; 11252c9ce25SScott Long struct scsi_inquiry_data inq_data; 11306e79492SKenneth D. Merry uint8_t *supported_vpds; 11406e79492SKenneth D. Merry uint8_t supported_vpds_len; 11506e79492SKenneth D. Merry uint32_t device_id_len; 11606e79492SKenneth D. Merry uint8_t *device_id; 1173bba3152SKenneth D. Merry uint32_t ext_inq_len; 1183bba3152SKenneth D. Merry uint8_t *ext_inq; 1193501942bSJustin T. Gibbs uint8_t physpath_len; 1203501942bSJustin T. Gibbs uint8_t *physpath; /* physical path string form */ 121e6bd5983SKenneth D. Merry uint32_t rcap_len; 122e6bd5983SKenneth D. Merry uint8_t *rcap_buf; 12352c9ce25SScott Long struct ata_params ident_data; 124a94a63f0SWarner Losh struct mmc_params mmc_ident_data; 1257af2f2c8SWarner Losh uint8_t inq_flags; /* 12652c9ce25SScott Long * Current settings for inquiry flags. 12752c9ce25SScott Long * This allows us to override settings 12852c9ce25SScott Long * like disconnection and tagged 12952c9ce25SScott Long * queuing for a device. 13052c9ce25SScott Long */ 1317af2f2c8SWarner Losh uint8_t queue_flags; /* Queue flags from the control page */ 1327af2f2c8SWarner Losh uint8_t serial_num_len; 1337af2f2c8SWarner Losh uint8_t *serial_num; 1347af2f2c8SWarner Losh uint32_t flags; 13552c9ce25SScott Long #define CAM_DEV_UNCONFIGURED 0x01 13652c9ce25SScott Long #define CAM_DEV_REL_TIMEOUT_PENDING 0x02 13752c9ce25SScott Long #define CAM_DEV_REL_ON_COMPLETE 0x04 13852c9ce25SScott Long #define CAM_DEV_REL_ON_QUEUE_EMPTY 0x08 13952c9ce25SScott Long #define CAM_DEV_TAG_AFTER_COUNT 0x20 14052c9ce25SScott Long #define CAM_DEV_INQUIRY_DATA_VALID 0x40 14152c9ce25SScott Long #define CAM_DEV_IN_DV 0x80 14252c9ce25SScott Long #define CAM_DEV_DV_HIT_BOTTOM 0x100 1434b997c49SAlexander Motin #define CAM_DEV_IDENTIFY_DATA_VALID 0x200 1447af2f2c8SWarner Losh uint32_t tag_delay_count; 14552c9ce25SScott Long #define CAM_TAG_DELAY_COUNT 5 1467af2f2c8SWarner Losh uint32_t tag_saved_openings; 1477af2f2c8SWarner Losh uint32_t refcount; 14852c9ce25SScott Long struct callout callout; 149ea541bfdSAlexander Motin STAILQ_ENTRY(cam_ed) highpowerq_entry; 150227d67aaSAlexander Motin struct mtx device_mtx; 151227d67aaSAlexander Motin struct task device_destroy_task; 152f439e3a4SAlexander Motin struct nvme_controller_data *nvme_cdata; 153f439e3a4SAlexander Motin struct nvme_namespace_data *nvme_data; 15452c9ce25SScott Long }; 15552c9ce25SScott Long 15652c9ce25SScott Long /* 15752c9ce25SScott Long * Each target is represented by an ET (Existing Target). These 15852c9ce25SScott Long * entries are created when a target is successfully probed with an 15952c9ce25SScott Long * identify, and removed when a device fails to respond after a number 16052c9ce25SScott Long * of retries, or a bus rescan finds the device missing. 16152c9ce25SScott Long */ 16252c9ce25SScott Long struct cam_et { 16352c9ce25SScott Long TAILQ_HEAD(, cam_ed) ed_entries; 16452c9ce25SScott Long TAILQ_ENTRY(cam_et) links; 16552c9ce25SScott Long struct cam_eb *bus; 16652c9ce25SScott Long target_id_t target_id; 1677af2f2c8SWarner Losh uint32_t refcount; 16852c9ce25SScott Long u_int generation; 16952c9ce25SScott Long struct timeval last_reset; 17082b361b1SMatt Jacob u_int rpl_size; 17182b361b1SMatt Jacob struct scsi_report_luns_data *luns; 172227d67aaSAlexander Motin struct mtx luns_mtx; /* Protection for luns field. */ 17352c9ce25SScott Long }; 17452c9ce25SScott Long 17552c9ce25SScott Long /* 17652c9ce25SScott Long * Each bus is represented by an EB (Existing Bus). These entries 17752c9ce25SScott Long * are created by calls to xpt_bus_register and deleted by calls to 17852c9ce25SScott Long * xpt_bus_deregister. 17952c9ce25SScott Long */ 18052c9ce25SScott Long struct cam_eb { 18152c9ce25SScott Long TAILQ_HEAD(, cam_et) et_entries; 18252c9ce25SScott Long TAILQ_ENTRY(cam_eb) links; 18352c9ce25SScott Long path_id_t path_id; 18452c9ce25SScott Long struct cam_sim *sim; 18552c9ce25SScott Long struct timeval last_reset; 1867af2f2c8SWarner Losh uint32_t flags; 18752c9ce25SScott Long #define CAM_EB_RUNQ_SCHEDULED 0x01 1887af2f2c8SWarner Losh uint32_t refcount; 18952c9ce25SScott Long u_int generation; 19052c9ce25SScott Long device_t parent_dev; 19152c9ce25SScott Long struct xpt_xport *xport; 192227d67aaSAlexander Motin struct mtx eb_mtx; /* Bus topology mutex. */ 19352c9ce25SScott Long }; 19452c9ce25SScott Long 19552c9ce25SScott Long struct cam_path { 19652c9ce25SScott Long struct cam_periph *periph; 19752c9ce25SScott Long struct cam_eb *bus; 19852c9ce25SScott Long struct cam_et *target; 19952c9ce25SScott Long struct cam_ed *device; 20052c9ce25SScott Long }; 20152c9ce25SScott Long 20252c9ce25SScott Long struct cam_ed * xpt_alloc_device(struct cam_eb *bus, 20352c9ce25SScott Long struct cam_et *target, 20452c9ce25SScott Long lun_id_t lun_id); 205f98d7a47SAlexander Motin void xpt_acquire_device(struct cam_ed *device); 206f98d7a47SAlexander Motin void xpt_release_device(struct cam_ed *device); 2077af2f2c8SWarner Losh uint32_t xpt_dev_ccbq_resize(struct cam_path *path, int newopenings); 20830a4094fSAlexander Motin void xpt_start_tags(struct cam_path *path); 20930a4094fSAlexander Motin void xpt_stop_tags(struct cam_path *path); 21052c9ce25SScott Long 21152c9ce25SScott Long MALLOC_DECLARE(M_CAMXPT); 21252c9ce25SScott Long 21352c9ce25SScott Long #endif 214