1/*- 2 * Implementation of the Target Mode 'Black Hole device' for CAM. 3 * 4 * Copyright (c) 1999 Justin T. Gibbs. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 13 unchanged lines hidden (view full) --- 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_targ_bh.c 147723 2005-07-01 15:21:30Z avatar $"); |
31 32#include <sys/param.h> 33#include <sys/queue.h> 34#include <sys/systm.h> 35#include <sys/kernel.h> 36#include <sys/types.h> 37#include <sys/bio.h> 38#include <sys/conf.h> --- 6 unchanged lines hidden (view full) --- 45#include <cam/cam_periph.h> 46#include <cam/cam_queue.h> 47#include <cam/cam_xpt_periph.h> 48#include <cam/cam_debug.h> 49 50#include <cam/scsi/scsi_all.h> 51#include <cam/scsi/scsi_message.h> 52 |
53MALLOC_DEFINE(M_SCSIBH, "SCSI bh", "SCSI blackhole buffers"); 54 |
55typedef enum { 56 TARGBH_STATE_NORMAL, 57 TARGBH_STATE_EXCEPTION, 58 TARGBH_STATE_TEARDOWN 59} targbh_state; 60 61typedef enum { 62 TARGBH_FLAG_NONE = 0x00, --- 210 unchanged lines hidden (view full) --- 273 274 /* 275 * Build up a buffer of accept target I/O 276 * operations for incoming selections. 277 */ 278 for (i = 0; i < MAX_ACCEPT; i++) { 279 struct ccb_accept_tio *atio; 280 |
281 atio = (struct ccb_accept_tio*)malloc(sizeof(*atio), M_SCSIBH, |
282 M_NOWAIT); 283 if (atio == NULL) { 284 status = CAM_RESRC_UNAVAIL; 285 break; 286 } 287 288 atio->ccb_h.ccb_descr = targbhallocdescr(); 289 290 if (atio->ccb_h.ccb_descr == NULL) { |
291 free(atio, M_SCSIBH); |
292 status = CAM_RESRC_UNAVAIL; 293 break; 294 } 295 296 xpt_setup_ccb(&atio->ccb_h, periph->path, /*priority*/1); 297 atio->ccb_h.func_code = XPT_ACCEPT_TARGET_IO; 298 atio->ccb_h.cbfcnp = targbhdone; 299 xpt_action((union ccb *)atio); 300 status = atio->ccb_h.status; 301 if (status != CAM_REQ_INPROG) { 302 targbhfreedescr(atio->ccb_h.ccb_descr); |
303 free(atio, M_SCSIBH); |
304 break; 305 } 306 ((struct targbh_cmd_desc*)atio->ccb_h.ccb_descr)->atio_link = 307 softc->accept_tio_list; 308 softc->accept_tio_list = atio; 309 } 310 311 if (i == 0) { --- 6 unchanged lines hidden (view full) --- 318 319 /* 320 * Build up a buffer of immediate notify CCBs 321 * so the SIM can tell us of asynchronous target mode events. 322 */ 323 for (i = 0; i < MAX_ACCEPT; i++) { 324 struct ccb_immed_notify *inot; 325 |
326 inot = (struct ccb_immed_notify*)malloc(sizeof(*inot), M_SCSIBH, |
327 M_NOWAIT); 328 329 if (inot == NULL) { 330 status = CAM_RESRC_UNAVAIL; 331 break; 332 } 333 334 xpt_setup_ccb(&inot->ccb_h, periph->path, /*priority*/1); 335 inot->ccb_h.func_code = XPT_IMMED_NOTIFY; 336 inot->ccb_h.cbfcnp = targbhdone; 337 xpt_action((union ccb *)inot); 338 status = inot->ccb_h.status; 339 if (status != CAM_REQ_INPROG) { |
340 free(inot, M_SCSIBH); |
341 break; 342 } 343 SLIST_INSERT_HEAD(&softc->immed_notify_slist, &inot->ccb_h, 344 periph_links.sle); 345 } 346 347 if (i == 0) { 348 xpt_print_path(periph->path); --- 57 unchanged lines hidden (view full) --- 406 407static cam_status 408targbhctor(struct cam_periph *periph, void *arg) 409{ 410 struct targbh_softc *softc; 411 412 /* Allocate our per-instance private storage */ 413 softc = (struct targbh_softc *)malloc(sizeof(*softc), |
414 M_SCSIBH, M_NOWAIT); |
415 if (softc == NULL) { 416 printf("targctor: unable to malloc softc\n"); 417 return (CAM_REQ_CMP_ERR); 418 } 419 420 bzero(softc, sizeof(*softc)); 421 TAILQ_INIT(&softc->pending_queue); 422 TAILQ_INIT(&softc->work_queue); --- 20 unchanged lines hidden (view full) --- 443 switch (softc->init_level) { 444 case 0: 445 panic("targdtor - impossible init level");; 446 case 1: 447 /* FALLTHROUGH */ 448 default: 449 /* XXX Wait for callback of targbhdislun() */ 450 tsleep(softc, PRIBIO, "targbh", hz/2); |
451 free(softc, M_SCSIBH); |
452 break; 453 } 454} 455 456static void 457targbhstart(struct cam_periph *periph, union ccb *start_ccb) 458{ 459 struct targbh_softc *softc; --- 113 unchanged lines hidden (view full) --- 573 int priority; 574 575 atio = &done_ccb->atio; 576 descr = (struct targbh_cmd_desc*)atio->ccb_h.ccb_descr; 577 cdb = atio->cdb_io.cdb_bytes; 578 if (softc->state == TARGBH_STATE_TEARDOWN 579 || atio->ccb_h.status == CAM_REQ_ABORTED) { 580 targbhfreedescr(descr); |
581 xpt_free_ccb(done_ccb); |
582 return; 583 } 584 585 /* 586 * Determine the type of incoming command and 587 * setup our buffer for a response. 588 */ 589 switch (cdb[0]) { --- 132 unchanged lines hidden (view full) --- 722 ("Returning ATIO to target\n")); 723 /* Restore wildcards */ 724 atio->ccb_h.target_id = CAM_TARGET_WILDCARD; 725 atio->ccb_h.target_lun = CAM_LUN_WILDCARD; 726 xpt_action((union ccb *)atio); 727 break; 728 } else { 729 targbhfreedescr(desc); |
730 free(atio, M_SCSIBH); |
731 } 732 break; 733 } 734 case XPT_IMMED_NOTIFY: 735 { 736 int frozen; 737 738 frozen = (done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0; 739 if (softc->state == TARGBH_STATE_TEARDOWN 740 || done_ccb->ccb_h.status == CAM_REQ_ABORTED) { 741 printf("Freed an immediate notify\n"); |
742 xpt_free_ccb(done_ccb); |
743 } else { 744 /* Requeue for another immediate event */ 745 xpt_action(done_ccb); 746 } 747 if (frozen != 0) 748 cam_release_devq(periph->path, 749 /*relsim_flags*/0, 750 /*opening reduction*/0, --- 17 unchanged lines hidden (view full) --- 768 769static struct targbh_cmd_desc* 770targbhallocdescr() 771{ 772 struct targbh_cmd_desc* descr; 773 774 /* Allocate the targbh_descr structure */ 775 descr = (struct targbh_cmd_desc *)malloc(sizeof(*descr), |
776 M_SCSIBH, M_NOWAIT); |
777 if (descr == NULL) 778 return (NULL); 779 780 bzero(descr, sizeof(*descr)); 781 782 /* Allocate buffer backing store */ |
783 descr->backing_store = malloc(MAX_BUF_SIZE, M_SCSIBH, M_NOWAIT); |
784 if (descr->backing_store == NULL) { |
785 free(descr, M_SCSIBH); |
786 return (NULL); 787 } 788 descr->max_size = MAX_BUF_SIZE; 789 return (descr); 790} 791 792static void 793targbhfreedescr(struct targbh_cmd_desc *descr) 794{ |
795 free(descr->backing_store, M_SCSIBH); 796 free(descr, M_SCSIBH); |
797} |