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 --- |