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 147723 2005-07-01 15:21:30Z 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 */
68MALLOC_DEFINE(M_CAMXPT, "CAM XPT", "CAM XPT buffers");
69
70/*
71 * Definition of an async handler callback block. These are used to add
72 * SIMs and peripherals to the async callback lists.
73 */
74struct async_node {
75 SLIST_ENTRY(async_node) links;
76 u_int32_t event_enable; /* Async Event enables */

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

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

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

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

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

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

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

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

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

4865
4866union ccb *
4867xpt_alloc_ccb()
4868{
4869 union ccb *new_ccb;
4870
4871 GIANT_REQUIRED;
4872
4873 new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_WAITOK);
4874 return (new_ccb);
4875}
4876
4877union ccb *
4878xpt_alloc_ccb_nowait()
4879{
4880 union ccb *new_ccb;
4881
4882 GIANT_REQUIRED;
4883
4884 new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_NOWAIT);
4885 return (new_ccb);
4886}
4887
4888void
4889xpt_free_ccb(union ccb *free_ccb)
4890{
4891 free(free_ccb, M_CAMXPT);
4892}
4893
4894
4895
4896/* Private XPT functions */
4897
4898/*
4899 * Get a CAM control block for the caller. Charge the structure to the device

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

4905static union ccb *
4906xpt_get_ccb(struct cam_ed *device)
4907{
4908 union ccb *new_ccb;
4909 int s;
4910
4911 s = splsoftcam();
4912 if ((new_ccb = (union ccb *)SLIST_FIRST(&ccb_freeq)) == NULL) {
4913 new_ccb = xpt_alloc_ccb_nowait();
4914 if (new_ccb == NULL) {
4915 splx(s);
4916 return (NULL);
4917 }
4918 callout_handle_init(&new_ccb->ccb_h.timeout_ch);
4919 SLIST_INSERT_HEAD(&ccb_freeq, &new_ccb->ccb_h,
4920 xpt_links.sle);
4921 xpt_ccb_count++;

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

4932 int s;
4933
4934 s = splcam();
4935 if ((--bus->refcount == 0)
4936 && (TAILQ_FIRST(&bus->et_entries) == NULL)) {
4937 TAILQ_REMOVE(&xpt_busses, bus, links);
4938 bus_generation++;
4939 splx(s);
4940 free(bus, M_CAMXPT);
4941 } else
4942 splx(s);
4943}
4944
4945static struct cam_et *
4946xpt_alloc_target(struct cam_eb *bus, target_id_t target_id)
4947{
4948 struct cam_et *target;
4949
4950 target = (struct cam_et *)malloc(sizeof(*target), M_CAMXPT, M_NOWAIT);
4951 if (target != NULL) {
4952 struct cam_et *cur_target;
4953
4954 TAILQ_INIT(&target->ed_entries);
4955 target->bus = bus;
4956 target->target_id = target_id;
4957 target->refcount = 1;
4958 target->generation = 0;

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

4984 int s;
4985
4986 s = splcam();
4987 if ((--target->refcount == 0)
4988 && (TAILQ_FIRST(&target->ed_entries) == NULL)) {
4989 TAILQ_REMOVE(&bus->et_entries, target, links);
4990 bus->generation++;
4991 splx(s);
4992 free(target, M_CAMXPT);
4993 xpt_release_bus(bus);
4994 } else
4995 splx(s);
4996}
4997
4998static struct cam_ed *
4999xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
5000{

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

5008 /* Make space for us in the device queue on our bus */
5009 devq = bus->sim->devq;
5010 status = cam_devq_resize(devq, devq->alloc_queue.array_size + 1);
5011
5012 if (status != CAM_REQ_CMP) {
5013 device = NULL;
5014 } else {
5015 device = (struct cam_ed *)malloc(sizeof(*device),
5016 M_CAMXPT, M_NOWAIT);
5017 }
5018
5019 if (device != NULL) {
5020 struct cam_ed *cur_device;
5021
5022 cam_init_pinfo(&device->alloc_ccb_entry.pinfo);
5023 device->alloc_ccb_entry.device = device;
5024 cam_init_pinfo(&device->send_ccb_entry.pinfo);
5025 device->send_ccb_entry.device = device;
5026 device->target = target;
5027 device->lun_id = lun_id;
5028 /* Initialize our queues */
5029 if (camq_init(&device->drvq, 0) != 0) {
5030 free(device, M_CAMXPT);
5031 return (NULL);
5032 }
5033 if (cam_ccbq_init(&device->ccbq,
5034 bus->sim->max_dev_openings) != 0) {
5035 camq_fini(&device->drvq);
5036 free(device, M_CAMXPT);
5037 return (NULL);
5038 }
5039 SLIST_INIT(&device->asyncs);
5040 SLIST_INIT(&device->periphs);
5041 device->generation = 0;
5042 device->owner = NULL;
5043 /*
5044 * Take the default quirk entry until we have inquiry

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

5116 target->generation++;
5117 xpt_max_ccbs -= device->ccbq.devq_openings;
5118 /* Release our slot in the devq */
5119 devq = bus->sim->devq;
5120 cam_devq_resize(devq, devq->alloc_queue.array_size - 1);
5121 splx(s);
5122 camq_fini(&device->drvq);
5123 camq_fini(&device->ccbq.queue);
5124 free(device, M_CAMXPT);
5125 xpt_release_target(bus, target);
5126 } else
5127 splx(s);
5128}
5129
5130static u_int32_t
5131xpt_dev_ccbq_resize(struct cam_path *path, int newopenings)
5132{

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

5964 have_serialnum = 0;
5965 csio = &done_ccb->csio;
5966 priority = done_ccb->ccb_h.pinfo.priority;
5967 serial_buf =
5968 (struct scsi_vpd_unit_serial_number *)csio->data_ptr;
5969
5970 /* Clean up from previous instance of this device */
5971 if (path->device->serial_num != NULL) {
5972 free(path->device->serial_num, M_CAMXPT);
5973 path->device->serial_num = NULL;
5974 path->device->serial_num_len = 0;
5975 }
5976
5977 if (serial_buf == NULL) {
5978 /*
5979 * Don't process the command as it was never sent
5980 */
5981 } else if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP
5982 && (serial_buf->length > 0)) {
5983
5984 have_serialnum = 1;
5985 path->device->serial_num =
5986 (u_int8_t *)malloc((serial_buf->length + 1),
5987 M_CAMXPT, M_NOWAIT);
5988 if (path->device->serial_num != NULL) {
5989 bcopy(serial_buf->serial_num,
5990 path->device->serial_num,
5991 serial_buf->length);
5992 path->device->serial_num_len =
5993 serial_buf->length;
5994 path->device->serial_num[serial_buf->length]
5995 = '\0';

--- 1119 unchanged lines hidden ---