ctl_backend.h revision 254759
154359Sroberto/*- 254359Sroberto * Copyright (c) 2003 Silicon Graphics International Corp. 354359Sroberto * All rights reserved. 454359Sroberto * 554359Sroberto * Redistribution and use in source and binary forms, with or without 654359Sroberto * modification, are permitted provided that the following conditions 754359Sroberto * are met: 854359Sroberto * 1. Redistributions of source code must retain the above copyright 954359Sroberto * notice, this list of conditions, and the following disclaimer, 1054359Sroberto * without modification. 1154359Sroberto * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1254359Sroberto * substantially similar to the "NO WARRANTY" disclaimer below 1354359Sroberto * ("Disclaimer") and any redistribution must be conditioned upon 1454359Sroberto * including a substantially similar Disclaimer requirement for further 1554359Sroberto * binary redistribution. 1654359Sroberto * 1754359Sroberto * NO WARRANTY 1854359Sroberto * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1954359Sroberto * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2054359Sroberto * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 2154359Sroberto * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2254359Sroberto * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2354359Sroberto * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2454359Sroberto * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2554359Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2654359Sroberto * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 2754359Sroberto * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2854359Sroberto * POSSIBILITY OF SUCH DAMAGES. 2954359Sroberto * 3054359Sroberto * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend.h#2 $ 3154359Sroberto * $FreeBSD: head/sys/cam/ctl/ctl_backend.h 254759 2013-08-24 01:50:31Z trasz $ 3254359Sroberto */ 3354359Sroberto/* 3454359Sroberto * CTL backend driver definitions 3554359Sroberto * 3654359Sroberto * Author: Ken Merry <ken@FreeBSD.org> 3754359Sroberto */ 3854359Sroberto 3954359Sroberto#ifndef _CTL_BACKEND_H_ 4054359Sroberto#define _CTL_BACKEND_H_ 4154359Sroberto 4254359Sroberto/* 4354359Sroberto * XXX KDM move this to another header file? 4454359Sroberto */ 4554359Sroberto#define CTL_BE_NAME_LEN 32 4654359Sroberto 4754359Sroberto/* 4854359Sroberto * The ID_REQ flag is used to say that the caller has requested a 4954359Sroberto * particular LUN ID in the req_lun_id field. If we cannot allocate that 5054359Sroberto * LUN ID, the ctl_add_lun() call will fail. 5154359Sroberto * 5254359Sroberto * The POWERED_OFF flag tells us that the LUN should default to the powered 5354359Sroberto * off state. It will return 0x04,0x02 until it is powered up. ("Logical 5454359Sroberto * unit not ready, initializing command required.") 5554359Sroberto * 5654359Sroberto * The INOPERABLE flag tells us that this LUN is not operable for whatever 5754359Sroberto * reason. This means that user data may have been (or has been?) lost. 5854359Sroberto * We will return 0x31,0x00 ("Medium format corrupted") until the host 5954359Sroberto * issues a FORMAT UNIT command to clear the error. 6054359Sroberto * 6154359Sroberto * The PRIMARY flag tells us that this LUN is registered as a Primary LUN 6254359Sroberto * which is accessible via the Master shelf controller in an HA. This flag 6354359Sroberto * being set indicates a Primary LUN. This flag being reset represents a 6454359Sroberto * Secondary LUN controlled by the Secondary controller in an HA 6554359Sroberto * configuration. Flag is applicable at this time to T_DIRECT types. 6654359Sroberto * 6754359Sroberto * The SERIAL_NUM flag tells us that the serial_num field is filled in and 6854359Sroberto * valid for use in SCSI INQUIRY VPD page 0x80. 6954359Sroberto * 7054359Sroberto * The DEVID flag tells us that the device_id field is filled in and 7154359Sroberto * valid for use in SCSI INQUIRY VPD page 0x83. 7254359Sroberto * 7354359Sroberto * The DEV_TYPE flag tells us that the device_type field is filled in. 7454359Sroberto */ 7554359Srobertotypedef enum { 7654359Sroberto CTL_LUN_FLAG_ID_REQ = 0x01, 7754359Sroberto CTL_LUN_FLAG_POWERED_OFF = 0x02, 7854359Sroberto CTL_LUN_FLAG_INOPERABLE = 0x04, 7954359Sroberto CTL_LUN_FLAG_PRIMARY = 0x08, 8054359Sroberto CTL_LUN_FLAG_SERIAL_NUM = 0x10, 8154359Sroberto CTL_LUN_FLAG_DEVID = 0x20, 8254359Sroberto CTL_LUN_FLAG_DEV_TYPE = 0x40 8354359Sroberto} ctl_backend_lun_flags; 8454359Sroberto 8554359Sroberto#ifdef _KERNEL 8654359Sroberto 8754359Sroberto#define CTL_BACKEND_DECLARE(name, driver) \ 8854359Sroberto static int name ## _modevent(module_t mod, int type, void *data) \ 8954359Sroberto { \ 9054359Sroberto switch (type) { \ 9154359Sroberto case MOD_LOAD: \ 9254359Sroberto ctl_backend_register( \ 9354359Sroberto (struct ctl_backend_driver *)data); \ 9454359Sroberto break; \ 9554359Sroberto case MOD_UNLOAD: \ 9654359Sroberto printf(#name " module unload - not possible for this module type\n"); \ 9754359Sroberto return EINVAL; \ 9854359Sroberto default: \ 9954359Sroberto return EOPNOTSUPP; \ 10054359Sroberto } \ 10154359Sroberto return 0; \ 10254359Sroberto } \ 10354359Sroberto static moduledata_t name ## _mod = { \ 10454359Sroberto #name, \ 10554359Sroberto name ## _modevent, \ 10654359Sroberto (void *)&driver \ 10754359Sroberto }; \ 10854359Sroberto DECLARE_MODULE(name, name ## _mod, SI_SUB_CONFIGURE, SI_ORDER_FOURTH); \ 10954359Sroberto MODULE_DEPEND(name, ctl, 1, 1, 1); \ 11054359Sroberto MODULE_DEPEND(name, cam, 1, 1, 1) 11154359Sroberto 11254359Sroberto 11354359Srobertotypedef enum { 11454359Sroberto CTL_LUN_CONFIG_OK, 11554359Sroberto CTL_LUN_CONFIG_FAILURE 11654359Sroberto} ctl_lun_config_status; 11754359Sroberto 11854359Srobertotypedef void (*be_callback_t)(void *be_lun); 11954359Srobertotypedef void (*be_lun_config_t)(void *be_lun, 12054359Sroberto ctl_lun_config_status status); 12154359Sroberto 12254359Sroberto/* 12354359Sroberto * The lun_type field is the SCSI device type of this particular LUN. In 12454359Sroberto * general, this should be T_DIRECT, although backends will want to create 12554359Sroberto * a processor LUN, typically at LUN 0. See scsi_all.h for the defines for 12654359Sroberto * the various SCSI device types. 12754359Sroberto * 12854359Sroberto * The flags are described above. 12954359Sroberto * 13054359Sroberto * The be_lun field is the backend driver's own context that will get 13154359Sroberto * passsed back so that it can tell which LUN CTL is referencing. 13254359Sroberto * 13354359Sroberto * maxlba is the maximum accessible LBA on the LUN. Note that this is 13454359Sroberto * different from the capacity of the array. capacity = maxlba + 1 13554359Sroberto * 13654359Sroberto * blocksize is the size, in bytes, of each LBA on the LUN. In general 13754359Sroberto * this should be 512. In theory CTL should be able to handle other block 13854359Sroberto * sizes. Host application software may not deal with it very well, though. 13954359Sroberto * 14054359Sroberto * req_lun_id is the requested LUN ID. CTL only pays attention to this 14154359Sroberto * field if the CTL_LUN_FLAG_ID_REQ flag is set. If the requested LUN ID is 14254359Sroberto * not available, the LUN addition will fail. If a particular LUN ID isn't 14354359Sroberto * requested, the first available LUN ID will be allocated. 14454359Sroberto * 14554359Sroberto * serial_num is the device serial number returned in the SCSI INQUIRY VPD 14654359Sroberto * page 0x80. This should be a unique, per-shelf value. The data inside 14754359Sroberto * this field should be ASCII only, left aligned, and any unused space 14854359Sroberto * should be padded out with ASCII spaces. This field should NOT be NULL 14954359Sroberto * terminated. 15054359Sroberto * 15154359Sroberto * device_id is the T10 device identifier returned in the SCSI INQUIRY VPD 15254359Sroberto * page 0x83. This should be a unique, per-LUN value. The data inside 15354359Sroberto * this field should be ASCII only, left aligned, and any unused space 15454359Sroberto * should be padded with ASCII spaces. This field should NOT be NULL 15554359Sroberto * terminated. 15654359Sroberto * 15754359Sroberto * The lun_shutdown() method is the callback for the ctl_invalidate_lun() 15854359Sroberto * call. It is called when all outstanding I/O for that LUN has been 15954359Sroberto * completed and CTL has deleted the resources for that LUN. When the CTL 16054359Sroberto * backend gets this call, it can safely free its per-LUN resources. 16154359Sroberto * 16254359Sroberto * The lun_config_status() method is the callback for the ctl_add_lun() 16354359Sroberto * call. It is called when the LUN is successfully added, or when LUN 16454359Sroberto * addition fails. If the LUN is successfully added, the backend may call 16554359Sroberto * the ctl_enable_lun() method to enable the LUN. 16654359Sroberto * 16754359Sroberto * The be field is a pointer to the ctl_backend_driver structure, which 16854359Sroberto * contains the backend methods to be called by CTL. 16954359Sroberto * 17054359Sroberto * The ctl_lun field is for CTL internal use only, and should not be used 17154359Sroberto * by the backend. 17254359Sroberto * 17354359Sroberto * The links field is for CTL internal use only, and should not be used by 17454359Sroberto * the backend. 17554359Sroberto */ 17654359Srobertostruct ctl_be_lun_option { 17754359Sroberto STAILQ_ENTRY(ctl_be_lun_option) links; 17854359Sroberto char *name; 17954359Sroberto char *value; 18054359Sroberto}; 18154359Sroberto 18254359Srobertostruct ctl_be_lun { 18354359Sroberto uint8_t lun_type; /* passed to CTL */ 18454359Sroberto ctl_backend_lun_flags flags; /* passed to CTL */ 18554359Sroberto void *be_lun; /* passed to CTL */ 18654359Sroberto uint64_t maxlba; /* passed to CTL */ 18754359Sroberto uint32_t blocksize; /* passed to CTL */ 18854359Sroberto uint32_t req_lun_id; /* passed to CTL */ 18954359Sroberto uint32_t lun_id; /* returned from CTL */ 19054359Sroberto uint8_t serial_num[CTL_SN_LEN]; /* passed to CTL */ 19154359Sroberto uint8_t device_id[CTL_DEVID_LEN];/* passed to CTL */ 19254359Sroberto be_callback_t lun_shutdown; /* passed to CTL */ 19354359Sroberto be_lun_config_t lun_config_status; /* passed to CTL */ 19454359Sroberto struct ctl_backend_driver *be; /* passed to CTL */ 19554359Sroberto void *ctl_lun; /* used by CTL */ 19654359Sroberto STAILQ_HEAD(, ctl_be_lun_option) options; /* passed to CTL */ 19754359Sroberto STAILQ_ENTRY(ctl_be_lun) links; /* used by CTL */ 19854359Sroberto}; 19954359Sroberto 20054359Srobertotypedef enum { 20154359Sroberto CTL_BE_FLAG_NONE = 0x00, /* no flags */ 20254359Sroberto CTL_BE_FLAG_HAS_CONFIG = 0x01, /* can do config reads, writes */ 20354359Sroberto CTL_BE_FLAG_INTERNAL = 0x02 /* don't inc mod refcount */ 20454359Sroberto} ctl_backend_flags; 20554359Sroberto 20654359Srobertotypedef int (*be_init_t)(void); 20754359Srobertotypedef int (*be_func_t)(union ctl_io *io); 20854359Srobertotypedef void (*be_vfunc_t)(union ctl_io *io); 20954359Srobertotypedef int (*be_ioctl_t)(struct cdev *dev, u_long cmd, caddr_t addr, int flag, 21054359Sroberto struct thread *td); 21154359Srobertotypedef int (*be_luninfo_t)(void *be_lun, struct sbuf *sb); 21254359Sroberto 21354359Srobertostruct ctl_backend_driver { 21454359Sroberto char name[CTL_BE_NAME_LEN]; /* passed to CTL */ 21554359Sroberto ctl_backend_flags flags; /* passed to CTL */ 21654359Sroberto be_init_t init; /* passed to CTL */ 21754359Sroberto be_func_t data_submit; /* passed to CTL */ 21854359Sroberto be_func_t data_move_done; /* passed to CTL */ 21954359Sroberto be_func_t config_read; /* passed to CTL */ 22054359Sroberto be_func_t config_write; /* passed to CTL */ 22154359Sroberto be_ioctl_t ioctl; /* passed to CTL */ 22254359Sroberto be_luninfo_t lun_info; /* passed to CTL */ 22354359Sroberto#ifdef CS_BE_CONFIG_MOVE_DONE_IS_NOT_USED 22454359Sroberto be_func_t config_move_done; /* passed to backend */ 22554359Sroberto#endif 22654359Sroberto#if 0 22754359Sroberto be_vfunc_t config_write_done; /* passed to backend */ 22854359Sroberto#endif 22954359Sroberto u_int num_luns; /* used by CTL */ 23054359Sroberto STAILQ_ENTRY(ctl_backend_driver) links; /* used by CTL */ 23154359Sroberto}; 23254359Sroberto 23354359Srobertoint ctl_backend_register(struct ctl_backend_driver *be); 23454359Srobertoint ctl_backend_deregister(struct ctl_backend_driver *be); 23554359Srobertostruct ctl_backend_driver *ctl_backend_find(char *backend_name); 23654359Sroberto 23754359Sroberto/* 23854359Sroberto * To add a LUN, first call ctl_add_lun(). You will get the lun_config_status() 23954359Sroberto * callback when the LUN addition has either succeeded or failed. 24054359Sroberto * 24154359Sroberto * Once you get that callback, you can then call ctl_enable_lun() to enable 24254359Sroberto * the LUN. 24354359Sroberto */ 24454359Srobertoint ctl_add_lun(struct ctl_be_lun *be_lun); 24554359Srobertoint ctl_enable_lun(struct ctl_be_lun *be_lun); 24654359Sroberto 24754359Sroberto/* 24854359Sroberto * To delete a LUN, first call ctl_disable_lun(), then 24954359Sroberto * ctl_invalidate_lun(). You will get the lun_shutdown() callback when all 25054359Sroberto * I/O to the LUN has completed and the LUN has been deleted. 25154359Sroberto */ 25254359Srobertoint ctl_disable_lun(struct ctl_be_lun *be_lun); 25354359Srobertoint ctl_invalidate_lun(struct ctl_be_lun *be_lun); 25454359Sroberto 25554359Sroberto/* 25654359Sroberto * To start a LUN (transition from powered off to powered on state) call 25754359Sroberto * ctl_start_lun(). To stop a LUN (transition from powered on to powered 25854359Sroberto * off state) call ctl_stop_lun(). 25954359Sroberto */ 26054359Srobertoint ctl_start_lun(struct ctl_be_lun *be_lun); 26154359Srobertoint ctl_stop_lun(struct ctl_be_lun *be_lun); 26254359Sroberto 26354359Sroberto/* 26454359Sroberto * If a LUN is inoperable, call ctl_lun_inoperable(). Generally the LUN 26554359Sroberto * will become operable once again when the user issues the SCSI FORMAT UNIT 26654359Sroberto * command. (CTL will automatically clear the inoperable flag.) If we 26754359Sroberto * need to re-enable the LUN, we can call ctl_lun_operable() to enable it 26854359Sroberto * without a SCSI command. 26954359Sroberto */ 27054359Srobertoint ctl_lun_inoperable(struct ctl_be_lun *be_lun); 27154359Srobertoint ctl_lun_operable(struct ctl_be_lun *be_lun); 27254359Sroberto 27354359Sroberto/* 27454359Sroberto * If a LUN is locked on or unlocked from a power/APS standpoint, call 27554359Sroberto * ctl_lun_power_lock() to update the current status in CTL's APS subpage. 27654359Sroberto * Set the lock flag to 1 to lock the LUN, set it to 0 to unlock the LUN. 27754359Sroberto */ 27854359Srobertoint ctl_lun_power_lock(struct ctl_be_lun *be_lun, struct ctl_nexus *nexus, 27954359Sroberto int lock); 28054359Sroberto 28154359Sroberto/* 28254359Sroberto * To take a LUN offline, call ctl_lun_offline(). Generally the LUN will 28354359Sroberto * be online again once the user sends a SCSI START STOP UNIT command with 28454359Sroberto * the start and on/offline bits set. The backend can bring the LUN back 28554359Sroberto * online via the ctl_lun_online() function, if necessary. 28654359Sroberto */ 28754359Srobertoint ctl_lun_offline(struct ctl_be_lun *be_lun); 28854359Srobertoint ctl_lun_online(struct ctl_be_lun *be_lun); 28954359Sroberto 29054359Sroberto/* 29154359Sroberto * Let the backend notify the initiator about changed capacity. 29254359Sroberto */ 29354359Srobertovoid ctl_lun_capacity_changed(struct ctl_be_lun *be_lun); 29454359Sroberto 29554359Sroberto#endif /* _KERNEL */ 29654359Sroberto#endif /* _CTL_BACKEND_H_ */ 29754359Sroberto 29854359Sroberto/* 29954359Sroberto * vim: ts=8 30054359Sroberto */ 30154359Sroberto