Deleted Added
sdiff udiff text old ( 147571 ) new ( 147723 )
full compact
1/*-
2 * Implementation of the Common Access Method Transport (XPT) layer.
3 *
4 * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998, 1999 Kenneth D. Merry.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/cam/cam_xpt.c 147571 2005-06-24 08:09:05Z avatar $");
32
33#include <sys/param.h>
34#include <sys/bus.h>
35#include <sys/systm.h>
36#include <sys/types.h>
37#include <sys/malloc.h>
38#include <sys/kernel.h>
39#include <sys/time.h>

--- 20 unchanged lines hidden (view full) ---

60#include <cam/cam_debug.h>
61
62#include <cam/scsi/scsi_all.h>
63#include <cam/scsi/scsi_message.h>
64#include <cam/scsi/scsi_pass.h>
65#include "opt_cam.h"
66
67/* Datastructures internal to the xpt layer */
68
69/*
70 * Definition of an async handler callback block. These are used to add
71 * SIMs and peripherals to the async callback lists.
72 */
73struct async_node {
74 SLIST_ENTRY(async_node) links;
75 u_int32_t event_enable; /* Async Event enables */

--- 3320 unchanged lines hidden (view full) ---

3396 * If the request has no flags set,
3397 * remove the entry.
3398 */
3399 added &= ~cur_entry->event_enable;
3400 if (csa->event_enable == 0) {
3401 SLIST_REMOVE(async_head, cur_entry,
3402 async_node, links);
3403 csa->ccb_h.path->device->refcount--;
3404 free(cur_entry, M_DEVBUF);
3405 } else {
3406 cur_entry->event_enable = csa->event_enable;
3407 }
3408 } else {
3409 cur_entry = malloc(sizeof(*cur_entry), M_DEVBUF,
3410 M_NOWAIT);
3411 if (cur_entry == NULL) {
3412 splx(s);
3413 csa->ccb_h.status = CAM_RESRC_UNAVAIL;
3414 break;
3415 }
3416 cur_entry->event_enable = csa->event_enable;
3417 cur_entry->callback_arg = csa->callback_arg;

--- 592 unchanged lines hidden (view full) ---

4010xpt_create_path(struct cam_path **new_path_ptr, struct cam_periph *perph,
4011 path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
4012{
4013 struct cam_path *path;
4014 cam_status status;
4015
4016 GIANT_REQUIRED;
4017
4018 path = (struct cam_path *)malloc(sizeof(*path), M_DEVBUF, M_NOWAIT);
4019
4020 if (path == NULL) {
4021 status = CAM_RESRC_UNAVAIL;
4022 return(status);
4023 }
4024 status = xpt_compile_path(path, perph, path_id, target_id, lun_id);
4025 if (status != CAM_REQ_CMP) {
4026 free(path, M_DEVBUF);
4027 path = NULL;
4028 }
4029 *new_path_ptr = path;
4030 return (status);
4031}
4032
4033static cam_status
4034xpt_compile_path(struct cam_path *new_path, struct cam_periph *perph,

--- 89 unchanged lines hidden (view full) ---

4124
4125void
4126xpt_free_path(struct cam_path *path)
4127{
4128 GIANT_REQUIRED;
4129
4130 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_free_path\n"));
4131 xpt_release_path(path);
4132 free(path, M_DEVBUF);
4133}
4134
4135
4136/*
4137 * Return -1 for failure, 0 for exact match, 1 for match with wildcards
4138 * in path1, 2 for match with wildcards in path2.
4139 */
4140int

--- 209 unchanged lines hidden (view full) ---

4350 struct cam_eb *old_bus;
4351 struct ccb_pathinq cpi;
4352 int s;
4353
4354 GIANT_REQUIRED;
4355
4356 sim->bus_id = bus;
4357 new_bus = (struct cam_eb *)malloc(sizeof(*new_bus),
4358 M_DEVBUF, M_NOWAIT);
4359 if (new_bus == NULL) {
4360 /* Couldn't satisfy request */
4361 return (CAM_RESRC_UNAVAIL);
4362 }
4363
4364 if (strcmp(sim->sim_name, "xpt") != 0) {
4365
4366 sim->path_id =

--- 497 unchanged lines hidden (view full) ---

4864
4865union ccb *
4866xpt_alloc_ccb()
4867{
4868 union ccb *new_ccb;
4869
4870 GIANT_REQUIRED;
4871
4872 new_ccb = malloc(sizeof(*new_ccb), M_DEVBUF, M_WAITOK);
4873 return (new_ccb);
4874}
4875
4876void
4877xpt_free_ccb(union ccb *free_ccb)
4878{
4879 free(free_ccb, M_DEVBUF);
4880}
4881
4882
4883
4884/* Private XPT functions */
4885
4886/*
4887 * Get a CAM control block for the caller. Charge the structure to the device

--- 5 unchanged lines hidden (view full) ---

4893static union ccb *
4894xpt_get_ccb(struct cam_ed *device)
4895{
4896 union ccb *new_ccb;
4897 int s;
4898
4899 s = splsoftcam();
4900 if ((new_ccb = (union ccb *)SLIST_FIRST(&ccb_freeq)) == NULL) {
4901 new_ccb = malloc(sizeof(*new_ccb), M_DEVBUF, M_NOWAIT);
4902 if (new_ccb == NULL) {
4903 splx(s);
4904 return (NULL);
4905 }
4906 callout_handle_init(&new_ccb->ccb_h.timeout_ch);
4907 SLIST_INSERT_HEAD(&ccb_freeq, &new_ccb->ccb_h,
4908 xpt_links.sle);
4909 xpt_ccb_count++;

--- 10 unchanged lines hidden (view full) ---

4920 int s;
4921
4922 s = splcam();
4923 if ((--bus->refcount == 0)
4924 && (TAILQ_FIRST(&bus->et_entries) == NULL)) {
4925 TAILQ_REMOVE(&xpt_busses, bus, links);
4926 bus_generation++;
4927 splx(s);
4928 free(bus, M_DEVBUF);
4929 } else
4930 splx(s);
4931}
4932
4933static struct cam_et *
4934xpt_alloc_target(struct cam_eb *bus, target_id_t target_id)
4935{
4936 struct cam_et *target;
4937
4938 target = (struct cam_et *)malloc(sizeof(*target), M_DEVBUF, M_NOWAIT);
4939 if (target != NULL) {
4940 struct cam_et *cur_target;
4941
4942 TAILQ_INIT(&target->ed_entries);
4943 target->bus = bus;
4944 target->target_id = target_id;
4945 target->refcount = 1;
4946 target->generation = 0;

--- 25 unchanged lines hidden (view full) ---

4972 int s;
4973
4974 s = splcam();
4975 if ((--target->refcount == 0)
4976 && (TAILQ_FIRST(&target->ed_entries) == NULL)) {
4977 TAILQ_REMOVE(&bus->et_entries, target, links);
4978 bus->generation++;
4979 splx(s);
4980 free(target, M_DEVBUF);
4981 xpt_release_bus(bus);
4982 } else
4983 splx(s);
4984}
4985
4986static struct cam_ed *
4987xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
4988{

--- 7 unchanged lines hidden (view full) ---

4996 /* Make space for us in the device queue on our bus */
4997 devq = bus->sim->devq;
4998 status = cam_devq_resize(devq, devq->alloc_queue.array_size + 1);
4999
5000 if (status != CAM_REQ_CMP) {
5001 device = NULL;
5002 } else {
5003 device = (struct cam_ed *)malloc(sizeof(*device),
5004 M_DEVBUF, M_NOWAIT);
5005 }
5006
5007 if (device != NULL) {
5008 struct cam_ed *cur_device;
5009
5010 cam_init_pinfo(&device->alloc_ccb_entry.pinfo);
5011 device->alloc_ccb_entry.device = device;
5012 cam_init_pinfo(&device->send_ccb_entry.pinfo);
5013 device->send_ccb_entry.device = device;
5014 device->target = target;
5015 device->lun_id = lun_id;
5016 /* Initialize our queues */
5017 if (camq_init(&device->drvq, 0) != 0) {
5018 free(device, M_DEVBUF);
5019 return (NULL);
5020 }
5021 if (cam_ccbq_init(&device->ccbq,
5022 bus->sim->max_dev_openings) != 0) {
5023 camq_fini(&device->drvq);
5024 free(device, M_DEVBUF);
5025 return (NULL);
5026 }
5027 SLIST_INIT(&device->asyncs);
5028 SLIST_INIT(&device->periphs);
5029 device->generation = 0;
5030 device->owner = NULL;
5031 /*
5032 * Take the default quirk entry until we have inquiry

--- 71 unchanged lines hidden (view full) ---

5104 target->generation++;
5105 xpt_max_ccbs -= device->ccbq.devq_openings;
5106 /* Release our slot in the devq */
5107 devq = bus->sim->devq;
5108 cam_devq_resize(devq, devq->alloc_queue.array_size - 1);
5109 splx(s);
5110 camq_fini(&device->drvq);
5111 camq_fini(&device->ccbq.queue);
5112 free(device, M_DEVBUF);
5113 xpt_release_target(bus, target);
5114 } else
5115 splx(s);
5116}
5117
5118static u_int32_t
5119xpt_dev_ccbq_resize(struct cam_path *path, int newopenings)
5120{

--- 831 unchanged lines hidden (view full) ---

5952 have_serialnum = 0;
5953 csio = &done_ccb->csio;
5954 priority = done_ccb->ccb_h.pinfo.priority;
5955 serial_buf =
5956 (struct scsi_vpd_unit_serial_number *)csio->data_ptr;
5957
5958 /* Clean up from previous instance of this device */
5959 if (path->device->serial_num != NULL) {
5960 free(path->device->serial_num, M_DEVBUF);
5961 path->device->serial_num = NULL;
5962 path->device->serial_num_len = 0;
5963 }
5964
5965 if (serial_buf == NULL) {
5966 /*
5967 * Don't process the command as it was never sent
5968 */
5969 } else if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP
5970 && (serial_buf->length > 0)) {
5971
5972 have_serialnum = 1;
5973 path->device->serial_num =
5974 (u_int8_t *)malloc((serial_buf->length + 1),
5975 M_DEVBUF, M_NOWAIT);
5976 if (path->device->serial_num != NULL) {
5977 bcopy(serial_buf->serial_num,
5978 path->device->serial_num,
5979 serial_buf->length);
5980 path->device->serial_num_len =
5981 serial_buf->length;
5982 path->device->serial_num[serial_buf->length]
5983 = '\0';

--- 1119 unchanged lines hidden ---