Deleted Added
sdiff udiff text old ( 139743 ) new ( 147723 )
full compact
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 139743 2005-01-05 22:34:37Z imp $");
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
53typedef enum {
54 TARGBH_STATE_NORMAL,
55 TARGBH_STATE_EXCEPTION,
56 TARGBH_STATE_TEARDOWN
57} targbh_state;
58
59typedef enum {
60 TARGBH_FLAG_NONE = 0x00,

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

271
272 /*
273 * Build up a buffer of accept target I/O
274 * operations for incoming selections.
275 */
276 for (i = 0; i < MAX_ACCEPT; i++) {
277 struct ccb_accept_tio *atio;
278
279 atio = (struct ccb_accept_tio*)malloc(sizeof(*atio), M_DEVBUF,
280 M_NOWAIT);
281 if (atio == NULL) {
282 status = CAM_RESRC_UNAVAIL;
283 break;
284 }
285
286 atio->ccb_h.ccb_descr = targbhallocdescr();
287
288 if (atio->ccb_h.ccb_descr == NULL) {
289 free(atio, M_DEVBUF);
290 status = CAM_RESRC_UNAVAIL;
291 break;
292 }
293
294 xpt_setup_ccb(&atio->ccb_h, periph->path, /*priority*/1);
295 atio->ccb_h.func_code = XPT_ACCEPT_TARGET_IO;
296 atio->ccb_h.cbfcnp = targbhdone;
297 xpt_action((union ccb *)atio);
298 status = atio->ccb_h.status;
299 if (status != CAM_REQ_INPROG) {
300 targbhfreedescr(atio->ccb_h.ccb_descr);
301 free(atio, M_DEVBUF);
302 break;
303 }
304 ((struct targbh_cmd_desc*)atio->ccb_h.ccb_descr)->atio_link =
305 softc->accept_tio_list;
306 softc->accept_tio_list = atio;
307 }
308
309 if (i == 0) {

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

316
317 /*
318 * Build up a buffer of immediate notify CCBs
319 * so the SIM can tell us of asynchronous target mode events.
320 */
321 for (i = 0; i < MAX_ACCEPT; i++) {
322 struct ccb_immed_notify *inot;
323
324 inot = (struct ccb_immed_notify*)malloc(sizeof(*inot), M_DEVBUF,
325 M_NOWAIT);
326
327 if (inot == NULL) {
328 status = CAM_RESRC_UNAVAIL;
329 break;
330 }
331
332 xpt_setup_ccb(&inot->ccb_h, periph->path, /*priority*/1);
333 inot->ccb_h.func_code = XPT_IMMED_NOTIFY;
334 inot->ccb_h.cbfcnp = targbhdone;
335 xpt_action((union ccb *)inot);
336 status = inot->ccb_h.status;
337 if (status != CAM_REQ_INPROG) {
338 free(inot, M_DEVBUF);
339 break;
340 }
341 SLIST_INSERT_HEAD(&softc->immed_notify_slist, &inot->ccb_h,
342 periph_links.sle);
343 }
344
345 if (i == 0) {
346 xpt_print_path(periph->path);

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

404
405static cam_status
406targbhctor(struct cam_periph *periph, void *arg)
407{
408 struct targbh_softc *softc;
409
410 /* Allocate our per-instance private storage */
411 softc = (struct targbh_softc *)malloc(sizeof(*softc),
412 M_DEVBUF, M_NOWAIT);
413 if (softc == NULL) {
414 printf("targctor: unable to malloc softc\n");
415 return (CAM_REQ_CMP_ERR);
416 }
417
418 bzero(softc, sizeof(*softc));
419 TAILQ_INIT(&softc->pending_queue);
420 TAILQ_INIT(&softc->work_queue);

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

441 switch (softc->init_level) {
442 case 0:
443 panic("targdtor - impossible init level");;
444 case 1:
445 /* FALLTHROUGH */
446 default:
447 /* XXX Wait for callback of targbhdislun() */
448 tsleep(softc, PRIBIO, "targbh", hz/2);
449 free(softc, M_DEVBUF);
450 break;
451 }
452}
453
454static void
455targbhstart(struct cam_periph *periph, union ccb *start_ccb)
456{
457 struct targbh_softc *softc;

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

571 int priority;
572
573 atio = &done_ccb->atio;
574 descr = (struct targbh_cmd_desc*)atio->ccb_h.ccb_descr;
575 cdb = atio->cdb_io.cdb_bytes;
576 if (softc->state == TARGBH_STATE_TEARDOWN
577 || atio->ccb_h.status == CAM_REQ_ABORTED) {
578 targbhfreedescr(descr);
579 free(done_ccb, M_DEVBUF);
580 return;
581 }
582
583 /*
584 * Determine the type of incoming command and
585 * setup our buffer for a response.
586 */
587 switch (cdb[0]) {

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

720 ("Returning ATIO to target\n"));
721 /* Restore wildcards */
722 atio->ccb_h.target_id = CAM_TARGET_WILDCARD;
723 atio->ccb_h.target_lun = CAM_LUN_WILDCARD;
724 xpt_action((union ccb *)atio);
725 break;
726 } else {
727 targbhfreedescr(desc);
728 free(atio, M_DEVBUF);
729 }
730 break;
731 }
732 case XPT_IMMED_NOTIFY:
733 {
734 int frozen;
735
736 frozen = (done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
737 if (softc->state == TARGBH_STATE_TEARDOWN
738 || done_ccb->ccb_h.status == CAM_REQ_ABORTED) {
739 printf("Freed an immediate notify\n");
740 free(done_ccb, M_DEVBUF);
741 } else {
742 /* Requeue for another immediate event */
743 xpt_action(done_ccb);
744 }
745 if (frozen != 0)
746 cam_release_devq(periph->path,
747 /*relsim_flags*/0,
748 /*opening reduction*/0,

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

766
767static struct targbh_cmd_desc*
768targbhallocdescr()
769{
770 struct targbh_cmd_desc* descr;
771
772 /* Allocate the targbh_descr structure */
773 descr = (struct targbh_cmd_desc *)malloc(sizeof(*descr),
774 M_DEVBUF, M_NOWAIT);
775 if (descr == NULL)
776 return (NULL);
777
778 bzero(descr, sizeof(*descr));
779
780 /* Allocate buffer backing store */
781 descr->backing_store = malloc(MAX_BUF_SIZE, M_DEVBUF, M_NOWAIT);
782 if (descr->backing_store == NULL) {
783 free(descr, M_DEVBUF);
784 return (NULL);
785 }
786 descr->max_size = MAX_BUF_SIZE;
787 return (descr);
788}
789
790static void
791targbhfreedescr(struct targbh_cmd_desc *descr)
792{
793 free(descr->backing_store, M_DEVBUF);
794 free(descr, M_DEVBUF);
795}