Deleted Added
full compact
cam_xpt.c (147571) cam_xpt.c (147723)
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>
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 $");
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 */
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");
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--;
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--;
3404 free(cur_entry, M_DEVBUF);
3405 free(cur_entry, M_CAMXPT);
3405 } else {
3406 cur_entry->event_enable = csa->event_enable;
3407 }
3408 } else {
3406 } else {
3407 cur_entry->event_enable = csa->event_enable;
3408 }
3409 } else {
3409 cur_entry = malloc(sizeof(*cur_entry), M_DEVBUF,
3410 cur_entry = malloc(sizeof(*cur_entry), M_CAMXPT,
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
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
4018 path = (struct cam_path *)malloc(sizeof(*path), M_DEVBUF, M_NOWAIT);
4019 path = (struct cam_path *)malloc(sizeof(*path), M_CAMXPT, 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) {
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) {
4026 free(path, M_DEVBUF);
4027 free(path, M_CAMXPT);
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);
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);
4132 free(path, M_DEVBUF);
4133 free(path, M_CAMXPT);
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),
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),
4358 M_DEVBUF, M_NOWAIT);
4359 M_CAMXPT, 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
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
4872 new_ccb = malloc(sizeof(*new_ccb), M_DEVBUF, M_WAITOK);
4873 new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_WAITOK);
4873 return (new_ccb);
4874}
4875
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
4876void
4877xpt_free_ccb(union ccb *free_ccb)
4878{
4888void
4889xpt_free_ccb(union ccb *free_ccb)
4890{
4879 free(free_ccb, M_DEVBUF);
4891 free(free_ccb, M_CAMXPT);
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) {
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) {
4901 new_ccb = malloc(sizeof(*new_ccb), M_DEVBUF, M_NOWAIT);
4913 new_ccb = xpt_alloc_ccb_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);
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);
4928 free(bus, M_DEVBUF);
4940 free(bus, M_CAMXPT);
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
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
4938 target = (struct cam_et *)malloc(sizeof(*target), M_DEVBUF, M_NOWAIT);
4950 target = (struct cam_et *)malloc(sizeof(*target), M_CAMXPT, 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);
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);
4980 free(target, M_DEVBUF);
4992 free(target, M_CAMXPT);
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),
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),
5004 M_DEVBUF, M_NOWAIT);
5016 M_CAMXPT, 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) {
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) {
5018 free(device, M_DEVBUF);
5030 free(device, M_CAMXPT);
5019 return (NULL);
5020 }
5021 if (cam_ccbq_init(&device->ccbq,
5022 bus->sim->max_dev_openings) != 0) {
5023 camq_fini(&device->drvq);
5031 return (NULL);
5032 }
5033 if (cam_ccbq_init(&device->ccbq,
5034 bus->sim->max_dev_openings) != 0) {
5035 camq_fini(&device->drvq);
5024 free(device, M_DEVBUF);
5036 free(device, M_CAMXPT);
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);
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);
5112 free(device, M_DEVBUF);
5124 free(device, M_CAMXPT);
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) {
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) {
5960 free(path->device->serial_num, M_DEVBUF);
5972 free(path->device->serial_num, M_CAMXPT);
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),
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),
5975 M_DEVBUF, M_NOWAIT);
5987 M_CAMXPT, 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 ---
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 ---