1230557Sjimharris/*- 2230557Sjimharris * BSD LICENSE 3230557Sjimharris * 4230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 5230557Sjimharris * All rights reserved. 6230557Sjimharris * 7230557Sjimharris * Redistribution and use in source and binary forms, with or without 8230557Sjimharris * modification, are permitted provided that the following conditions 9230557Sjimharris * are met: 10230557Sjimharris * 11230557Sjimharris * * Redistributions of source code must retain the above copyright 12230557Sjimharris * notice, this list of conditions and the following disclaimer. 13230557Sjimharris * * Redistributions in binary form must reproduce the above copyright 14230557Sjimharris * notice, this list of conditions and the following disclaimer in 15230557Sjimharris * the documentation and/or other materials provided with the 16230557Sjimharris * distribution. 17230557Sjimharris * 18230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29230557Sjimharris * 30230557Sjimharris * $FreeBSD$ 31230557Sjimharris */ 32230557Sjimharris 33235751Sjimharris#ifndef _ISCI_H 34235751Sjimharris#define _ISCI_H 35235751Sjimharris 36230557Sjimharris#include <sys/param.h> 37230557Sjimharris#include <sys/systm.h> 38230557Sjimharris#include <sys/kernel.h> 39230557Sjimharris#include <sys/bus.h> 40230557Sjimharris#include <sys/lock.h> 41230557Sjimharris#include <sys/mutex.h> 42230557Sjimharris#include <sys/types.h> 43230557Sjimharris#include <sys/malloc.h> 44230557Sjimharris#include <sys/rman.h> 45230557Sjimharris 46230557Sjimharris#include <machine/bus.h> 47230557Sjimharris#include <machine/resource.h> 48230557Sjimharris 49230557Sjimharris#include <cam/cam.h> 50230557Sjimharris#include <cam/cam_ccb.h> 51230557Sjimharris#include <cam/cam_sim.h> 52230557Sjimharris#include <cam/cam_xpt_sim.h> 53230557Sjimharris 54230557Sjimharris#include <dev/isci/environment.h> 55230557Sjimharris#include <dev/isci/scil/intel_pci.h> 56230557Sjimharris 57230557Sjimharris#include <dev/isci/scil/sci_types.h> 58230557Sjimharris#include <dev/isci/scil/sci_object.h> 59230557Sjimharris#include <dev/isci/scil/sci_status.h> 60230557Sjimharris#include <dev/isci/scil/sci_pool.h> 61230557Sjimharris#include <dev/isci/scil/sci_fast_list.h> 62230557Sjimharris 63230557Sjimharris#include <dev/isci/scil/sci_controller_constants.h> 64230557Sjimharris 65230557Sjimharris#include <dev/isci/scil/scic_controller.h> 66230557Sjimharris#include <dev/isci/scil/scic_config_parameters.h> 67230557Sjimharris 68230557Sjimharris#define DEVICE2SOFTC(dev) ((struct isci_softc *) device_get_softc(dev)) 69230557Sjimharris 70230557Sjimharris#define DEVICE_TIMEOUT 1000 71230557Sjimharris#define SCI_MAX_TIMERS 32 72230557Sjimharris 73230557Sjimharris#define ISCI_NUM_PCI_BARS 2 74230557Sjimharris#define ISCI_MAX_LUN 8 75230557Sjimharris 76230557SjimharrisMALLOC_DECLARE(M_ISCI); 77230557Sjimharris 78230557Sjimharrisstruct ISCI_TIMER { 79230557Sjimharris struct callout callout; 80230557Sjimharris SCI_TIMER_CALLBACK_T callback; 81230557Sjimharris void *cookie; 82230557Sjimharris BOOL is_started; 83230557Sjimharris}; 84230557Sjimharris 85230557Sjimharrisstruct ISCI_REMOTE_DEVICE { 86230557Sjimharris uint32_t index; 87230557Sjimharris struct ISCI_DOMAIN *domain; 88230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T sci_object; 89230557Sjimharris BOOL is_resetting; 90230557Sjimharris uint32_t frozen_lun_mask; 91230557Sjimharris SCI_FAST_LIST_ELEMENT_T pending_device_reset_element; 92235751Sjimharris 93235751Sjimharris /* 94235751Sjimharris * This queue maintains CCBs that have been returned with 95235751Sjimharris * SCI_IO_FAILURE_INVALID_STATE from the SCI layer. These CCBs 96235751Sjimharris * need to be retried, but we cannot return CAM_REQUEUE_REQ because 97235751Sjimharris * this status gets passed all the way back up to users of the pass(4) 98235751Sjimharris * interface and breaks things like smartctl. So instead, we queue 99235751Sjimharris * these CCBs internally. 100235751Sjimharris */ 101234106Sjimharris TAILQ_HEAD(,ccb_hdr) queued_ccbs; 102235751Sjimharris 103235751Sjimharris /* 104235751Sjimharris * Marker denoting this remote device needs its first queued ccb to 105235751Sjimharris * be retried. 106235751Sjimharris */ 107235751Sjimharris BOOL release_queued_ccb; 108235751Sjimharris 109235751Sjimharris /* 110235751Sjimharris * Points to a CCB in the queue that is currently being processed by 111235751Sjimharris * SCIL. This allows us to keep in flight CCBs in the queue so as to 112235751Sjimharris * maintain ordering (i.e. in case we retry an I/O and then find out 113235751Sjimharris * it needs to be retried again - it just keeps its same place in the 114235751Sjimharris * queue. 115235751Sjimharris */ 116235751Sjimharris union ccb * queued_ccb_in_progress; 117230557Sjimharris}; 118230557Sjimharris 119230557Sjimharrisstruct ISCI_DOMAIN { 120233622Sjimharris struct ISCI_CONTROLLER *controller; 121233622Sjimharris SCI_DOMAIN_HANDLE_T sci_object; 122233622Sjimharris uint8_t index; 123233622Sjimharris struct ISCI_REMOTE_DEVICE *da_remote_device; 124230557Sjimharris}; 125230557Sjimharris 126230557Sjimharrisstruct ISCI_MEMORY 127230557Sjimharris{ 128230557Sjimharris bus_addr_t physical_address; 129230557Sjimharris bus_dma_tag_t dma_tag; 130230557Sjimharris bus_dmamap_t dma_map; 131230557Sjimharris POINTER_UINT virtual_address; 132230557Sjimharris uint32_t size; 133230557Sjimharris int error; 134230557Sjimharris}; 135230557Sjimharris 136230557Sjimharrisstruct ISCI_INTERRUPT_INFO 137230557Sjimharris{ 138230557Sjimharris SCIC_CONTROLLER_HANDLER_METHODS_T *handlers; 139230557Sjimharris void *interrupt_target_handle; 140230557Sjimharris struct resource *res; 141230557Sjimharris int rid; 142230557Sjimharris void *tag; 143230557Sjimharris 144230557Sjimharris}; 145230557Sjimharris 146241403Sjimharrisstruct ISCI_PHY 147240965Sjimharris{ 148241403Sjimharris struct cdev *cdev_fault; 149241403Sjimharris struct cdev *cdev_locate; 150240965Sjimharris SCI_CONTROLLER_HANDLE_T handle; 151240965Sjimharris int index; 152241403Sjimharris int led_fault; 153241403Sjimharris int led_locate; 154240965Sjimharris}; 155240965Sjimharris 156230557Sjimharrisstruct ISCI_CONTROLLER 157230557Sjimharris{ 158230557Sjimharris struct isci_softc *isci; 159230557Sjimharris uint8_t index; 160230557Sjimharris SCI_CONTROLLER_HANDLE_T scif_controller_handle; 161230557Sjimharris struct ISCI_DOMAIN domain[SCI_MAX_DOMAINS]; 162230557Sjimharris BOOL is_started; 163233371Sjimharris BOOL has_been_scanned; 164230557Sjimharris uint32_t initial_discovery_mask; 165230557Sjimharris BOOL is_frozen; 166235751Sjimharris BOOL release_queued_ccbs; 167268073Sscottl BOOL fail_on_task_timeout; 168230557Sjimharris uint8_t *remote_device_memory; 169230557Sjimharris struct ISCI_MEMORY cached_controller_memory; 170230557Sjimharris struct ISCI_MEMORY uncached_controller_memory; 171230557Sjimharris struct ISCI_MEMORY request_memory; 172230557Sjimharris bus_dma_tag_t buffer_dma_tag; 173230557Sjimharris struct mtx lock; 174230557Sjimharris struct cam_sim *sim; 175230557Sjimharris struct cam_path *path; 176230557Sjimharris struct ISCI_REMOTE_DEVICE *remote_device[SCI_MAX_REMOTE_DEVICES]; 177230557Sjimharris void *timer_memory; 178230557Sjimharris SCIC_OEM_PARAMETERS_T oem_parameters; 179230557Sjimharris uint32_t oem_parameters_version; 180230557Sjimharris uint32_t queue_depth; 181230557Sjimharris uint32_t sim_queue_depth; 182230557Sjimharris SCI_FAST_LIST_T pending_device_reset_list; 183241403Sjimharris struct ISCI_PHY phys[SCI_MAX_PHYS]; 184230557Sjimharris 185230557Sjimharris SCI_MEMORY_DESCRIPTOR_LIST_HANDLE_T mdl; 186230557Sjimharris 187230557Sjimharris SCI_POOL_CREATE(remote_device_pool, struct ISCI_REMOTE_DEVICE *, SCI_MAX_REMOTE_DEVICES); 188230557Sjimharris SCI_POOL_CREATE(request_pool, struct ISCI_REQUEST *, SCI_MAX_IO_REQUESTS); 189230557Sjimharris SCI_POOL_CREATE(timer_pool, struct ISCI_TIMER *, SCI_MAX_TIMERS); 190239545Sjimharris SCI_POOL_CREATE(unmap_buffer_pool, void *, SCI_MAX_REMOTE_DEVICES); 191230557Sjimharris}; 192230557Sjimharris 193230557Sjimharrisstruct ISCI_REQUEST 194230557Sjimharris{ 195230557Sjimharris SCI_CONTROLLER_HANDLE_T controller_handle; 196230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device_handle; 197230557Sjimharris bus_dma_tag_t dma_tag; 198230557Sjimharris bus_dmamap_t dma_map; 199230557Sjimharris SCI_PHYSICAL_ADDRESS physical_address; 200230557Sjimharris struct callout timer; 201230557Sjimharris}; 202230557Sjimharris 203230557Sjimharrisstruct ISCI_IO_REQUEST 204230557Sjimharris{ 205230557Sjimharris struct ISCI_REQUEST parent; 206230557Sjimharris SCI_IO_REQUEST_HANDLE_T sci_object; 207230557Sjimharris union ccb *ccb; 208230557Sjimharris uint32_t num_segments; 209230557Sjimharris uint32_t current_sge_index; 210230557Sjimharris bus_dma_segment_t *sge; 211230557Sjimharris}; 212230557Sjimharris 213230557Sjimharrisstruct ISCI_TASK_REQUEST 214230557Sjimharris{ 215230557Sjimharris struct ISCI_REQUEST parent; 216230557Sjimharris struct scsi_sense_data sense_data; 217230557Sjimharris SCI_TASK_REQUEST_HANDLE_T sci_object; 218230557Sjimharris union ccb *ccb; 219230557Sjimharris 220230557Sjimharris}; 221230557Sjimharris 222230557Sjimharrisstruct ISCI_PCI_BAR { 223230557Sjimharris 224230557Sjimharris bus_space_tag_t bus_tag; 225230557Sjimharris bus_space_handle_t bus_handle; 226230557Sjimharris int resource_id; 227230557Sjimharris struct resource *resource; 228230557Sjimharris 229230557Sjimharris}; 230230557Sjimharris 231230557Sjimharris/* 232230557Sjimharris * One of these per allocated PCI device. 233230557Sjimharris */ 234230557Sjimharrisstruct isci_softc { 235230557Sjimharris 236230557Sjimharris struct ISCI_PCI_BAR pci_bar[ISCI_NUM_PCI_BARS]; 237230557Sjimharris struct ISCI_CONTROLLER controllers[SCI_MAX_CONTROLLERS]; 238230557Sjimharris SCI_LIBRARY_HANDLE_T sci_library_handle; 239230557Sjimharris void * sci_library_memory; 240230557Sjimharris SCIC_CONTROLLER_HANDLER_METHODS_T handlers[4]; 241230557Sjimharris struct ISCI_INTERRUPT_INFO interrupt_info[4]; 242230557Sjimharris uint32_t controller_count; 243230557Sjimharris uint32_t num_interrupts; 244230557Sjimharris uint32_t coalesce_number; 245230557Sjimharris uint32_t coalesce_timeout; 246230557Sjimharris device_t device; 247230557Sjimharris SCI_PCI_COMMON_HEADER_T pci_common_header; 248230557Sjimharris BOOL oem_parameters_found; 249230557Sjimharris struct intr_config_hook config_hook; 250230557Sjimharris}; 251230557Sjimharris 252230557Sjimharrisint isci_allocate_resources(device_t device); 253230557Sjimharris 254230557Sjimharrisint isci_allocate_dma_buffer(device_t device, struct ISCI_MEMORY *memory); 255230557Sjimharris 256230557Sjimharrisvoid isci_remote_device_reset(struct ISCI_REMOTE_DEVICE *remote_device, 257230557Sjimharris union ccb *ccb); 258230557Sjimharris 259230557Sjimharris/** 260230557Sjimharris * Returns the negotiated link rate (in KB/s) for the associated 261230557Sjimharris * remote device. Used to fill out bitrate field for GET_TRANS_SETTINGS. 262230557Sjimharris * Will match the negotiated link rate for the lowest numbered local phy 263230557Sjimharris * in the port/domain containing this remote device. 264230557Sjimharris */ 265230557Sjimharrisuint32_t isci_remote_device_get_bitrate( 266230557Sjimharris struct ISCI_REMOTE_DEVICE *remote_device); 267230557Sjimharris 268230557Sjimharrisvoid isci_remote_device_freeze_lun_queue( 269230557Sjimharris struct ISCI_REMOTE_DEVICE *remote_device, lun_id_t lun); 270230557Sjimharris 271230557Sjimharrisvoid isci_remote_device_release_lun_queue( 272230557Sjimharris struct ISCI_REMOTE_DEVICE *remote_device, lun_id_t lun); 273230557Sjimharris 274230557Sjimharrisvoid isci_remote_device_release_device_queue( 275230557Sjimharris struct ISCI_REMOTE_DEVICE * remote_device); 276230557Sjimharris 277230557Sjimharrisvoid isci_request_construct(struct ISCI_REQUEST *request, 278230557Sjimharris SCI_CONTROLLER_HANDLE_T scif_controller_handle, 279230557Sjimharris bus_dma_tag_t io_buffer_dma_tag, bus_addr_t physical_address); 280230557Sjimharris 281230557Sjimharris#define isci_io_request_get_max_io_size() \ 282230557Sjimharris ((SCI_MAX_SCATTER_GATHER_ELEMENTS - 1) * PAGE_SIZE) 283230557Sjimharris 284230557Sjimharris#define isci_task_request_get_object_size() \ 285230557Sjimharris (sizeof(struct ISCI_TASK_REQUEST) + scif_task_request_get_object_size()) 286230557Sjimharris 287230557Sjimharris#define isci_io_request_get_object_size() \ 288230557Sjimharris (sizeof(struct ISCI_IO_REQUEST) + scif_io_request_get_object_size()) 289230557Sjimharris 290230557Sjimharris#define isci_request_get_object_size() \ 291230557Sjimharris max( \ 292230557Sjimharris isci_task_request_get_object_size(), \ 293230557Sjimharris isci_io_request_get_object_size() \ 294230557Sjimharris ) 295230557Sjimharris 296230557Sjimharris 297230557Sjimharrisvoid isci_io_request_execute_scsi_io(union ccb *ccb, 298230557Sjimharris struct ISCI_CONTROLLER *controller); 299230557Sjimharris 300230557Sjimharris#if __FreeBSD_version >= 900026 301230557Sjimharrisvoid isci_io_request_execute_smp_io( 302230557Sjimharris union ccb *ccb, struct ISCI_CONTROLLER *controller); 303230557Sjimharris#endif 304230557Sjimharris 305230557Sjimharrisvoid isci_io_request_timeout(void *); 306230557Sjimharris 307230557Sjimharrisvoid isci_get_oem_parameters(struct isci_softc *isci); 308230557Sjimharris 309230557Sjimharrisvoid isci_io_request_complete( 310230557Sjimharris SCI_CONTROLLER_HANDLE_T scif_controller, 311230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 312230557Sjimharris struct ISCI_IO_REQUEST * isci_request, SCI_IO_STATUS completion_status); 313230557Sjimharris 314230557Sjimharrisvoid isci_task_request_complete( 315230557Sjimharris SCI_CONTROLLER_HANDLE_T scif_controller, 316230557Sjimharris SCI_REMOTE_DEVICE_HANDLE_T remote_device, 317230557Sjimharris SCI_TASK_REQUEST_HANDLE_T io_request, SCI_TASK_STATUS completion_status); 318230557Sjimharris 319230557Sjimharrisvoid isci_sysctl_initialize(struct isci_softc *isci); 320230557Sjimharris 321230557Sjimharrisvoid isci_controller_construct(struct ISCI_CONTROLLER *controller, 322230557Sjimharris struct isci_softc *isci); 323230557Sjimharris 324230557SjimharrisSCI_STATUS isci_controller_initialize(struct ISCI_CONTROLLER *controller); 325230557Sjimharris 326230557Sjimharrisint isci_controller_allocate_memory(struct ISCI_CONTROLLER *controller); 327230557Sjimharris 328230557Sjimharrisvoid isci_controller_domain_discovery_complete( 329230557Sjimharris struct ISCI_CONTROLLER *isci_controller, struct ISCI_DOMAIN *isci_domain); 330230557Sjimharris 331230557Sjimharrisint isci_controller_attach_to_cam(struct ISCI_CONTROLLER *controller); 332230557Sjimharris 333230557Sjimharrisvoid isci_controller_start(void *controller); 334230557Sjimharris 335235751Sjimharrisvoid isci_controller_release_queued_ccbs(struct ISCI_CONTROLLER *controller); 336235751Sjimharris 337230557Sjimharrisvoid isci_domain_construct(struct ISCI_DOMAIN *domain, uint32_t domain_index, 338230557Sjimharris struct ISCI_CONTROLLER *controller); 339230557Sjimharris 340230557Sjimharrisvoid isci_interrupt_setup(struct isci_softc *isci); 341230557Sjimharrisvoid isci_interrupt_poll_handler(struct ISCI_CONTROLLER *controller); 342230557Sjimharris 343230557Sjimharrisvoid isci_log_message(uint32_t verbosity, char *log_message_prefix, 344230557Sjimharris char *log_message, ...); 345230557Sjimharris 346230557Sjimharrisextern uint32_t g_isci_debug_level; 347235751Sjimharris 348235751Sjimharris#endif /* #ifndef _ISCI_H */ 349