cam_sim.c revision 139743
1139743Simp/*- 239212Sgibbs * Common functions for SCSI Interface Modules (SIMs). 339212Sgibbs * 439212Sgibbs * Copyright (c) 1997 Justin T. Gibbs. 539212Sgibbs * All rights reserved. 639212Sgibbs * 739212Sgibbs * Redistribution and use in source and binary forms, with or without 839212Sgibbs * modification, are permitted provided that the following conditions 939212Sgibbs * are met: 1039212Sgibbs * 1. Redistributions of source code must retain the above copyright 1139212Sgibbs * notice, this list of conditions, and the following disclaimer, 1239212Sgibbs * without modification, immediately at the beginning of the file. 1339212Sgibbs * 2. The name of the author may not be used to endorse or promote products 1439212Sgibbs * derived from this software without specific prior written permission. 1539212Sgibbs * 1639212Sgibbs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1739212Sgibbs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1839212Sgibbs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1939212Sgibbs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 2039212Sgibbs * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2139212Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2239212Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2339212Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2439212Sgibbs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2539212Sgibbs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2639212Sgibbs * SUCH DAMAGE. 2739212Sgibbs */ 2839212Sgibbs 29116161Sobrien#include <sys/cdefs.h> 30116161Sobrien__FBSDID("$FreeBSD: head/sys/cam/cam_sim.c 139743 2005-01-05 22:34:37Z imp $"); 31116161Sobrien 3239212Sgibbs#include <sys/param.h> 3339212Sgibbs#include <sys/systm.h> 3439212Sgibbs#include <sys/malloc.h> 3539212Sgibbs 3639212Sgibbs#include <cam/cam.h> 3739212Sgibbs#include <cam/cam_ccb.h> 3839212Sgibbs#include <cam/cam_sim.h> 3939212Sgibbs#include <cam/cam_queue.h> 4039212Sgibbs 4139212Sgibbs#define CAM_PATH_ANY (u_int32_t)-1 4239212Sgibbs 4339212Sgibbsstruct cam_devq * 4439212Sgibbscam_simq_alloc(u_int32_t max_sim_transactions) 4539212Sgibbs{ 4639212Sgibbs return (cam_devq_alloc(/*size*/0, max_sim_transactions)); 4739212Sgibbs} 4839212Sgibbs 4939212Sgibbsvoid 5039212Sgibbscam_simq_free(struct cam_devq *devq) 5139212Sgibbs{ 5239212Sgibbs cam_devq_free(devq); 5339212Sgibbs} 5439212Sgibbs 5539212Sgibbsstruct cam_sim * 5639212Sgibbscam_sim_alloc(sim_action_func sim_action, sim_poll_func sim_poll, 5771507Sjhb const char *sim_name, void *softc, u_int32_t unit, 5846581Sken int max_dev_transactions, 5946581Sken int max_tagged_dev_transactions, struct cam_devq *queue) 6039212Sgibbs{ 6139212Sgibbs struct cam_sim *sim; 6239212Sgibbs 6339212Sgibbs /* 6439212Sgibbs * If this is the xpt layer creating a sim, then it's OK 6539212Sgibbs * to wait for an allocation. 6639212Sgibbs * 6739212Sgibbs * XXX Should we pass in a flag to indicate that wait is OK? 6839212Sgibbs */ 6939212Sgibbs if (strcmp(sim_name, "xpt") == 0) 7039212Sgibbs sim = (struct cam_sim *)malloc(sizeof(struct cam_sim), 71111119Simp M_DEVBUF, M_WAITOK); 7239212Sgibbs else 7339212Sgibbs sim = (struct cam_sim *)malloc(sizeof(struct cam_sim), 7439212Sgibbs M_DEVBUF, M_NOWAIT); 7539212Sgibbs 7639212Sgibbs if (sim != NULL) { 7739212Sgibbs sim->sim_action = sim_action; 7839212Sgibbs sim->sim_poll = sim_poll; 7939212Sgibbs sim->sim_name = sim_name; 8039212Sgibbs sim->softc = softc; 8139212Sgibbs sim->path_id = CAM_PATH_ANY; 8239212Sgibbs sim->unit_number = unit; 8339212Sgibbs sim->bus_id = 0; /* set in xpt_bus_register */ 8439212Sgibbs sim->max_tagged_dev_openings = max_tagged_dev_transactions; 8539212Sgibbs sim->max_dev_openings = max_dev_transactions; 8639212Sgibbs sim->flags = 0; 8739212Sgibbs callout_handle_init(&sim->c_handle); 8839212Sgibbs sim->devq = queue; 8939212Sgibbs } 9039212Sgibbs 9139212Sgibbs return (sim); 9239212Sgibbs} 9339212Sgibbs 9439212Sgibbsvoid 9539212Sgibbscam_sim_free(struct cam_sim *sim, int free_devq) 9639212Sgibbs{ 9739212Sgibbs if (free_devq) 9839212Sgibbs cam_simq_free(sim->devq); 9939212Sgibbs free(sim, M_DEVBUF); 10039212Sgibbs} 10139212Sgibbs 10239212Sgibbsvoid 10339212Sgibbscam_sim_set_path(struct cam_sim *sim, u_int32_t path_id) 10439212Sgibbs{ 10539212Sgibbs sim->path_id = path_id; 10639212Sgibbs} 107