ctl_frontend.h revision 275493
189857Sobrien/*- 2218822Sdim * Copyright (c) 2003 Silicon Graphics International Corp. 3218822Sdim * All rights reserved. 489857Sobrien * 589857Sobrien * Redistribution and use in source and binary forms, with or without 6130561Sobrien * modification, are permitted provided that the following conditions 789857Sobrien * are met: 8130561Sobrien * 1. Redistributions of source code must retain the above copyright 9130561Sobrien * notice, this list of conditions, and the following disclaimer, 10130561Sobrien * without modification. 11130561Sobrien * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1289857Sobrien * substantially similar to the "NO WARRANTY" disclaimer below 13130561Sobrien * ("Disclaimer") and any redistribution must be conditioned upon 14130561Sobrien * including a substantially similar Disclaimer requirement for further 15130561Sobrien * binary redistribution. 16130561Sobrien * 1789857Sobrien * NO WARRANTY 18130561Sobrien * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19130561Sobrien * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20218822Sdim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 2189857Sobrien * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22218822Sdim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2389857Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2489857Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2589857Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2689857Sobrien * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 2789857Sobrien * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2889857Sobrien * POSSIBILITY OF SUCH DAMAGES. 2989857Sobrien * 30218822Sdim * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_frontend.h#2 $ 31218822Sdim * $FreeBSD: stable/10/sys/cam/ctl/ctl_frontend.h 275493 2014-12-05 07:23:25Z mav $ 32218822Sdim */ 33218822Sdim/* 34218822Sdim * CAM Target Layer front end registration hooks 35218822Sdim * 36218822Sdim * Author: Ken Merry <ken@FreeBSD.org> 37218822Sdim */ 38218822Sdim 39218822Sdim#ifndef _CTL_FRONTEND_H_ 40218822Sdim#define _CTL_FRONTEND_H_ 41218822Sdim 42218822Sdimtypedef enum { 43218822Sdim CTL_PORT_STATUS_NONE = 0x00, 44218822Sdim CTL_PORT_STATUS_ONLINE = 0x01, 45218822Sdim CTL_PORT_STATUS_TARG_ONLINE = 0x02, 46218822Sdim CTL_PORT_STATUS_LUN_ONLINE = 0x04 47218822Sdim} ctl_port_status; 48218822Sdim 49218822Sdimtypedef int (*fe_init_t)(void); 50218822Sdimtypedef void (*fe_shutdown_t)(void); 51218822Sdimtypedef void (*port_func_t)(void *onoff_arg); 52218822Sdimtypedef int (*port_info_func_t)(void *onoff_arg, struct sbuf *sb); 53218822Sdimtypedef int (*lun_func_t)(void *arg, struct ctl_id targ_id, int lun_id); 54218822Sdimtypedef uint32_t (*lun_map_func_t)(void *arg, uint32_t lun_id); 5589857Sobrientypedef int (*fe_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag, 56218822Sdim struct thread *td); 57218822Sdim 58218822Sdim#define CTL_FRONTEND_DECLARE(name, driver) \ 59218822Sdim static int name ## _modevent(module_t mod, int type, void *data) \ 60218822Sdim { \ 61218822Sdim switch (type) { \ 62218822Sdim case MOD_LOAD: \ 6389857Sobrien ctl_frontend_register( \ 64218822Sdim (struct ctl_frontend *)data); \ 65218822Sdim break; \ 66218822Sdim case MOD_UNLOAD: \ 67218822Sdim printf(#name " module unload - not possible for this module type\n"); \ 68218822Sdim return EINVAL; \ 6989857Sobrien default: \ 70218822Sdim return EOPNOTSUPP; \ 71218822Sdim } \ 72218822Sdim return 0; \ 73218822Sdim } \ 74218822Sdim static moduledata_t name ## _mod = { \ 75218822Sdim #name, \ 76218822Sdim name ## _modevent, \ 7789857Sobrien (void *)&driver \ 78218822Sdim }; \ 79218822Sdim DECLARE_MODULE(name, name ## _mod, SI_SUB_CONFIGURE, SI_ORDER_FOURTH); \ 8089857Sobrien MODULE_DEPEND(name, ctl, 1, 1, 1); \ 81218822Sdim MODULE_DEPEND(name, cam, 1, 1, 1) 82218822Sdim 8389857Sobrienstruct ctl_wwpn_iid { 8489857Sobrien int in_use; 85218822Sdim time_t last_use; 86218822Sdim uint64_t wwpn; 8789857Sobrien char *name; 88218822Sdim}; 89218822Sdim 9089857Sobrien/* 9189857Sobrien * The ctl_frontend structure is the registration mechanism between a FETD 9289857Sobrien * (Front End Target Driver) and the CTL layer. Here is a description of 93218822Sdim * the fields: 94218822Sdim * 9589857Sobrien * port_type: This field tells CTL what kind of front end it is 96218822Sdim * dealing with. This field serves two purposes. 9789857Sobrien * The first is to let CTL know whether the frontend 9889857Sobrien * in question is inside the main CTL module (i.e. 99218822Sdim * the ioctl front end), and therefore its module 100218822Sdim * reference count shouldn't be incremented. The 10189857Sobrien * CTL ioctl front end should continue to use the 102218822Sdim * CTL_PORT_IOCTL argument as long as it is part of 103218822Sdim * the main CTL module. The second is to let CTL 104218822Sdim * know what kind of front end it is dealing with, so 105218822Sdim * it can return the proper inquiry data for that 10689857Sobrien * particular port. 107218822Sdim * 108218822Sdim * num_requested_ctl_io: This is the number of ctl_io structures that the 109218822Sdim * front end needs for its pool. This should 110218822Sdim * generally be the maximum number of outstanding 111218822Sdim * transactions that the FETD can handle. The CTL 112218822Sdim * layer will add a few to this to account for 113218822Sdim * ctl_io buffers queued for pending sense data. 114218822Sdim * (Pending sense only gets queued if the FETD 115218822Sdim * doesn't support autosense. e.g. non-packetized 116218822Sdim * parallel SCSI doesn't support autosense.) 117218822Sdim * 118218822Sdim * port_name: A string describing the FETD. e.g. "LSI 1030T U320" 119218822Sdim * or whatever you want to use to describe the driver. 120218822Sdim * 121218822Sdim * 122218822Sdim * physical_port: This is the physical port number of this 123218822Sdim * particular port within the driver/hardware. This 124218822Sdim * number is hardware/driver specific. 125218822Sdim * virtual_port: This is the virtual port number of this 126218822Sdim * particular port. This is for things like NP-IV. 127218822Sdim * 128218822Sdim * port_online(): This function is called, with onoff_arg as its 129218822Sdim * argument, by the CTL layer when it wants the FETD 130218822Sdim * to start responding to selections on the specified 131218822Sdim * target ID. (targ_target) 132218822Sdim * 133218822Sdim * port_offline(): This function is called, with onoff_arg as its 134218822Sdim * argument, by the CTL layer when it wants the FETD 135218822Sdim * to stop responding to selection on the specified 136218822Sdim * target ID. (targ_target) 137218822Sdim * 13889857Sobrien * onoff_arg: This is supplied as an argument to port_online() 13989857Sobrien * and port_offline(). This is specified by the 14089857Sobrien * FETD. 141130561Sobrien * 14289857Sobrien * lun_enable(): This function is called, with targ_lun_arg, a target 14389857Sobrien * ID and a LUN ID as its arguments, by CTL when it 14489857Sobrien * wants the FETD to enable a particular LUN. If the 14589857Sobrien * FETD doesn't really know about LUNs, it should 14689857Sobrien * just ignore this call and return 0. If the FETD 14789857Sobrien * cannot enable the requested LUN for some reason, the 14889857Sobrien * FETD should return non-zero status. 14989857Sobrien * 15089857Sobrien * lun_disable(): This function is called, with targ_lun_arg, a target 15189857Sobrien * ID and LUN ID as its arguments, by CTL when it 15289857Sobrien * wants the FETD to disable a particular LUN. If the 15389857Sobrien * FETD doesn't really know about LUNs, it should just 15489857Sobrien * ignore this call and return 0. If the FETD cannot 15589857Sobrien * disable the requested LUN for some reason, the 15689857Sobrien * FETD should return non-zero status. 15789857Sobrien * 15889857Sobrien * targ_lun_arg: This is supplied as an argument to the targ/lun 15989857Sobrien * enable/disable() functions. This is specified by 16089857Sobrien * the FETD. 161130561Sobrien * 162130561Sobrien * fe_datamove(): This function is called one or more times per I/O 16389857Sobrien * by the CTL layer to tell the FETD to initiate a 16489857Sobrien * DMA to or from the data buffer(s) specified by 16589857Sobrien * the passed-in ctl_io structure. 166130561Sobrien * 16789857Sobrien * fe_done(): This function is called by the CTL layer when a 16889857Sobrien * particular SCSI I/O or task management command has 16989857Sobrien * completed. For SCSI I/O requests (CTL_IO_SCSI), 17089857Sobrien * sense data is always supplied if the status is 17189857Sobrien * CTL_SCSI_ERROR and the SCSI status byte is 172130561Sobrien * SCSI_STATUS_CHECK_COND. If the FETD doesn't 173130561Sobrien * support autosense, the sense should be queued 174130561Sobrien * back to the CTL layer via ctl_queue_sense(). 175130561Sobrien * 176130561Sobrien * fe_dump(): This function, if it exists, is called by CTL 177130561Sobrien * to request a dump of any debugging information or 178130561Sobrien * state to the console. 179130561Sobrien * 180130561Sobrien * max_targets: The maximum number of targets that we can create 181130561Sobrien * per-port. 182130561Sobrien * 183130561Sobrien * max_target_id: The highest target ID that we can use. 184130561Sobrien * 185130561Sobrien * targ_port: The CTL layer assigns a "port number" to every 186130561Sobrien * FETD. This port number should be passed back in 187130561Sobrien * in the header of every ctl_io that is queued to 188130561Sobrien * the CTL layer. This enables us to determine 189130561Sobrien * which bus the command came in on. 190130561Sobrien * 191130561Sobrien * ctl_pool_ref: Memory pool reference used by the FETD in calls to 192130561Sobrien * ctl_alloc_io(). 19389857Sobrien * 19489857Sobrien * max_initiators: Maximum number of initiators that the FETD is 19589857Sobrien * allowed to have. Initiators should be numbered 19689857Sobrien * from 0 to max_initiators - 1. This value will 197130561Sobrien * typically be 16, and thus not a problem for 19889857Sobrien * parallel SCSI. This may present issues for Fibre 19989857Sobrien * Channel. 20089857Sobrien * 201130561Sobrien * wwnn World Wide Node Name to be used by the FETD. 20289857Sobrien * Note that this is set *after* registration. It 20389857Sobrien * will be set prior to the online function getting 20489857Sobrien * called. 20589857Sobrien * 20689857Sobrien * wwpn World Wide Port Name to be used by the FETD. 20789857Sobrien * Note that this is set *after* registration. It 20889857Sobrien * will be set prior to the online function getting 20989857Sobrien * called. 21089857Sobrien * 21189857Sobrien * status: Used by CTL to keep track of per-FETD state. 212218822Sdim * 21389857Sobrien * links: Linked list pointers, used by CTL. The FETD 214218822Sdim * shouldn't touch this field. 215218822Sdim */ 21689857Sobrienstruct ctl_port { 217218822Sdim struct ctl_frontend *frontend; 218218822Sdim ctl_port_type port_type; /* passed to CTL */ 219218822Sdim int num_requested_ctl_io; /* passed to CTL */ 220218822Sdim char *port_name; /* passed to CTL */ 221218822Sdim int physical_port; /* passed to CTL */ 22289857Sobrien int virtual_port; /* passed to CTL */ 223218822Sdim port_func_t port_online; /* passed to CTL */ 22489857Sobrien port_func_t port_offline; /* passed to CTL */ 22589857Sobrien port_info_func_t port_info; /* passed to CTL */ 22689857Sobrien void *onoff_arg; /* passed to CTL */ 22789857Sobrien lun_func_t lun_enable; /* passed to CTL */ 22889857Sobrien lun_func_t lun_disable; /* passed to CTL */ 22989857Sobrien lun_map_func_t lun_map; /* passed to CTL */ 230218822Sdim void *targ_lun_arg; /* passed to CTL */ 231218822Sdim void (*fe_datamove)(union ctl_io *io); /* passed to CTL */ 232218822Sdim void (*fe_done)(union ctl_io *io); /* passed to CTL */ 23389857Sobrien int max_targets; /* passed to CTL */ 23489857Sobrien int max_target_id; /* passed to CTL */ 23589857Sobrien int32_t targ_port; /* passed back to FETD */ 236130561Sobrien void *ctl_pool_ref; /* passed back to FETD */ 23789857Sobrien uint32_t max_initiators; /* passed back to FETD */ 23889857Sobrien struct ctl_wwpn_iid *wwpn_iid; /* used by CTL */ 23989857Sobrien uint64_t wwnn; /* set by CTL before online */ 240218822Sdim uint64_t wwpn; /* set by CTL before online */ 241218822Sdim ctl_port_status status; /* used by CTL */ 242218822Sdim ctl_options_t options; /* passed to CTL */ 243218822Sdim struct ctl_devid *port_devid; /* passed to CTL */ 244218822Sdim struct ctl_devid *target_devid; /* passed to CTL */ 245218822Sdim struct ctl_devid *init_devid; /* passed to CTL */ 246218822Sdim STAILQ_ENTRY(ctl_port) fe_links; /* used by CTL */ 247218822Sdim STAILQ_ENTRY(ctl_port) links; /* used by CTL */ 248218822Sdim}; 249218822Sdim 250218822Sdimstruct ctl_frontend { 251218822Sdim char name[CTL_DRIVER_NAME_LEN]; /* passed to CTL */ 252218822Sdim fe_init_t init; /* passed to CTL */ 253218822Sdim fe_ioctl_t ioctl; /* passed to CTL */ 254218822Sdim void (*fe_dump)(void); /* passed to CTL */ 255218822Sdim fe_shutdown_t shutdown; /* passed to CTL */ 256218822Sdim STAILQ_HEAD(, ctl_port) port_list; /* used by CTL */ 257218822Sdim STAILQ_ENTRY(ctl_frontend) links; /* used by CTL */ 258218822Sdim}; 259218822Sdim 260218822Sdim/* 261218822Sdim * This may block until resources are allocated. Called at FETD module load 262218822Sdim * time. Returns 0 for success, non-zero for failure. 263218822Sdim */ 264218822Sdimint ctl_frontend_register(struct ctl_frontend *fe); 265218822Sdim 266218822Sdim/* 267218822Sdim * Called at FETD module unload time. 268218822Sdim * Returns 0 for success, non-zero for failure. 269218822Sdim */ 270218822Sdimint ctl_frontend_deregister(struct ctl_frontend *fe); 271218822Sdim 272218822Sdim/* 273218822Sdim * Find the frontend by its name. Returns NULL if not found. 274218822Sdim */ 275218822Sdimstruct ctl_frontend * ctl_frontend_find(char *frontend_name); 276218822Sdim 277218822Sdim/* 278218822Sdim * This may block until resources are allocated. Called at FETD module load 279218822Sdim * time. Returns 0 for success, non-zero for failure. 280218822Sdim */ 281218822Sdimint ctl_port_register(struct ctl_port *port); 282218822Sdim 283218822Sdim/* 284218822Sdim * Called at FETD module unload time. 285218822Sdim * Returns 0 for success, non-zero for failure. 286218822Sdim */ 287218822Sdimint ctl_port_deregister(struct ctl_port *port); 288218822Sdim 289218822Sdim/* 290218822Sdim * Called to set the WWNN and WWPN for a particular frontend. 291218822Sdim */ 292218822Sdimvoid ctl_port_set_wwns(struct ctl_port *port, int wwnn_valid, 293218822Sdim uint64_t wwnn, int wwpn_valid, uint64_t wwpn); 294218822Sdim 295218822Sdim/* 296218822Sdim * Called to bring a particular frontend online. 297218822Sdim */ 298218822Sdimvoid ctl_port_online(struct ctl_port *fe); 299218822Sdim 300218822Sdim/* 301218822Sdim * Called to take a particular frontend offline. 302218822Sdim */ 303218822Sdimvoid ctl_port_offline(struct ctl_port *fe); 304218822Sdim 305218822Sdim/* 306218822Sdim * This routine queues I/O and task management requests from the FETD to the 307218822Sdim * CTL layer. Returns immediately. Returns 0 for success, non-zero for 308218822Sdim * failure. 309218822Sdim */ 310218822Sdimint ctl_queue(union ctl_io *io); 311218822Sdim 312218822Sdim/* 313218822Sdim * This routine is used if the front end interface doesn't support 314218822Sdim * autosense (e.g. non-packetized parallel SCSI). This will queue the 315218822Sdim * scsiio structure back to a per-lun pending sense queue. This MUST be 316218822Sdim * called BEFORE any request sense can get queued to the CTL layer -- I 317218822Sdim * need it in the queue in order to service the request. The scsiio 318218822Sdim * structure passed in here will be freed by the CTL layer when sense is 31989857Sobrien * retrieved by the initiator. Returns 0 for success, non-zero for failure. 320218822Sdim */ 321218822Sdimint ctl_queue_sense(union ctl_io *io); 322218822Sdim 323218822Sdim/* 324218822Sdim * This routine adds an initiator to CTL's port database. 325218822Sdim * The iid field should be the same as the iid passed in the nexus of each 326218822Sdim * ctl_io from this initiator. 32789857Sobrien * The WWPN should be the FC WWPN, if available. 328218822Sdim */ 329218822Sdimint ctl_add_initiator(struct ctl_port *port, int iid, uint64_t wwpn, char *name); 330218822Sdim 331218822Sdim/* 332218822Sdim * This routine will remove an initiator from CTL's port database. 333218822Sdim * The iid field should be the same as the iid passed in the nexus of each 334218822Sdim * ctl_io from this initiator. 335218822Sdim */ 336218822Sdimint ctl_remove_initiator(struct ctl_port *port, int iid); 337218822Sdim 338218822Sdim#endif /* _CTL_FRONTEND_H_ */ 339218822Sdim