Deleted Added
full compact
ctl_backend_block.c (268150) ctl_backend_block.c (268151)
1/*-
2 * Copyright (c) 2003 Silicon Graphics International Corp.
3 * Copyright (c) 2009-2011 Spectra Logic Corporation
4 * Copyright (c) 2012 The FreeBSD Foundation
5 * All rights reserved.
6 *
7 * Portions of this software were developed by Edward Tomasz Napierala
8 * under sponsorship from the FreeBSD Foundation.

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

35 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend_block.c#5 $
36 */
37/*
38 * CAM Target Layer driver backend for block devices.
39 *
40 * Author: Ken Merry <ken@FreeBSD.org>
41 */
42#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2003 Silicon Graphics International Corp.
3 * Copyright (c) 2009-2011 Spectra Logic Corporation
4 * Copyright (c) 2012 The FreeBSD Foundation
5 * All rights reserved.
6 *
7 * Portions of this software were developed by Edward Tomasz Napierala
8 * under sponsorship from the FreeBSD Foundation.

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

35 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend_block.c#5 $
36 */
37/*
38 * CAM Target Layer driver backend for block devices.
39 *
40 * Author: Ken Merry <ken@FreeBSD.org>
41 */
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD: stable/10/sys/cam/ctl/ctl_backend_block.c 268150 2014-07-02 10:43:53Z mav $");
43__FBSDID("$FreeBSD: stable/10/sys/cam/ctl/ctl_backend_block.c 268151 2014-07-02 10:45:31Z mav $");
44
45#include <opt_kdtrace.h>
46
47#include <sys/param.h>
48#include <sys/systm.h>
49#include <sys/kernel.h>
50#include <sys/types.h>
51#include <sys/kthread.h>

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

89#include <cam/ctl/ctl_ioctl.h>
90#include <cam/ctl/ctl_scsi_all.h>
91#include <cam/ctl/ctl_error.h>
92
93/*
94 * The idea here is that we'll allocate enough S/G space to hold a 1MB
95 * I/O. If we get an I/O larger than that, we'll split it.
96 */
44
45#include <opt_kdtrace.h>
46
47#include <sys/param.h>
48#include <sys/systm.h>
49#include <sys/kernel.h>
50#include <sys/types.h>
51#include <sys/kthread.h>

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

89#include <cam/ctl/ctl_ioctl.h>
90#include <cam/ctl/ctl_scsi_all.h>
91#include <cam/ctl/ctl_error.h>
92
93/*
94 * The idea here is that we'll allocate enough S/G space to hold a 1MB
95 * I/O. If we get an I/O larger than that, we'll split it.
96 */
97#define CTLBLK_MAX_IO_SIZE (1024 * 1024)
97#define CTLBLK_HALF_IO_SIZE (512 * 1024)
98#define CTLBLK_MAX_IO_SIZE (CTLBLK_HALF_IO_SIZE * 2)
98#define CTLBLK_MAX_SEG MAXPHYS
99#define CTLBLK_MAX_SEG MAXPHYS
99#define CTLBLK_MAX_SEGS MAX(CTLBLK_MAX_IO_SIZE / CTLBLK_MAX_SEG, 1)
100#define CTLBLK_HALF_SEGS MAX(CTLBLK_HALF_IO_SIZE / CTLBLK_MAX_SEG, 1)
101#define CTLBLK_MAX_SEGS (CTLBLK_HALF_SEGS * 2)
100
101#ifdef CTLBLK_DEBUG
102#define DPRINTF(fmt, args...) \
103 printf("cbb(%s:%d): " fmt, __FUNCTION__, __LINE__, ##args)
104#else
105#define DPRINTF(fmt, args...) do {} while(0)
106#endif
107
108#define PRIV(io) \
109 ((struct ctl_ptr_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_BACKEND])
102
103#ifdef CTLBLK_DEBUG
104#define DPRINTF(fmt, args...) \
105 printf("cbb(%s:%d): " fmt, __FUNCTION__, __LINE__, ##args)
106#else
107#define DPRINTF(fmt, args...) do {} while(0)
108#endif
109
110#define PRIV(io) \
111 ((struct ctl_ptr_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_BACKEND])
112#define ARGS(io) \
113 ((struct ctl_lba_len_flags *)&(io)->io_hdr.ctl_private[CTL_PRIV_LBA_LEN])
110
111SDT_PROVIDER_DEFINE(cbb);
112
113typedef enum {
114 CTL_BE_BLOCK_LUN_UNCONFIGURED = 0x01,
115 CTL_BE_BLOCK_LUN_CONFIG_ERR = 0x02,
116 CTL_BE_BLOCK_LUN_WAITING = 0x04,
117 CTL_BE_BLOCK_LUN_MULTI_THREAD = 0x08

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

309 duplicate_free = 0;
310
311 for (i = 0; i < beio->num_segs; i++) {
312 if (beio->sg_segs[i].addr == NULL)
313 duplicate_free++;
314
315 uma_zfree(beio->lun->lun_zone, beio->sg_segs[i].addr);
316 beio->sg_segs[i].addr = NULL;
114
115SDT_PROVIDER_DEFINE(cbb);
116
117typedef enum {
118 CTL_BE_BLOCK_LUN_UNCONFIGURED = 0x01,
119 CTL_BE_BLOCK_LUN_CONFIG_ERR = 0x02,
120 CTL_BE_BLOCK_LUN_WAITING = 0x04,
121 CTL_BE_BLOCK_LUN_MULTI_THREAD = 0x08

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

313 duplicate_free = 0;
314
315 for (i = 0; i < beio->num_segs; i++) {
316 if (beio->sg_segs[i].addr == NULL)
317 duplicate_free++;
318
319 uma_zfree(beio->lun->lun_zone, beio->sg_segs[i].addr);
320 beio->sg_segs[i].addr = NULL;
321
322 /* For compare we had two equal S/G lists. */
323 if (ARGS(beio->io)->flags & CTL_LLF_COMPARE) {
324 uma_zfree(beio->lun->lun_zone,
325 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr);
326 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr = NULL;
327 }
317 }
318
319 if (duplicate_free > 0) {
320 printf("%s: %d duplicate frees out of %d segments\n", __func__,
321 duplicate_free, beio->num_segs);
322 }
323
324 uma_zfree(beio_zone, beio);

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

343 beio->ds_trans_type,
344 /*now*/ NULL,
345 /*then*/&beio->ds_t0);
346
347 if (beio->beio_cont != NULL) {
348 beio->beio_cont(beio);
349 } else {
350 ctl_free_beio(beio);
328 }
329
330 if (duplicate_free > 0) {
331 printf("%s: %d duplicate frees out of %d segments\n", __func__,
332 duplicate_free, beio->num_segs);
333 }
334
335 uma_zfree(beio_zone, beio);

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

354 beio->ds_trans_type,
355 /*now*/ NULL,
356 /*then*/&beio->ds_t0);
357
358 if (beio->beio_cont != NULL) {
359 beio->beio_cont(beio);
360 } else {
361 ctl_free_beio(beio);
351 ctl_done(io);
362 ctl_data_submit_done(io);
352 }
353}
354
355static int
356ctl_be_block_move_done(union ctl_io *io)
357{
358 struct ctl_be_block_io *beio;
359 struct ctl_be_block_lun *be_lun;
363 }
364}
365
366static int
367ctl_be_block_move_done(union ctl_io *io)
368{
369 struct ctl_be_block_io *beio;
370 struct ctl_be_block_lun *be_lun;
371 struct ctl_lba_len_flags *lbalen;
360#ifdef CTL_TIME_IO
361 struct bintime cur_bt;
372#ifdef CTL_TIME_IO
373 struct bintime cur_bt;
362#endif
374#endif
375 int i;
363
364 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
365 be_lun = beio->lun;
366
367 DPRINTF("entered\n");
368
369#ifdef CTL_TIME_IO
370 getbintime(&cur_bt);
371 bintime_sub(&cur_bt, &io->io_hdr.dma_start_bt);
372 bintime_add(&io->io_hdr.dma_bt, &cur_bt);
373 io->io_hdr.num_dmas++;
374#endif
376
377 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
378 be_lun = beio->lun;
379
380 DPRINTF("entered\n");
381
382#ifdef CTL_TIME_IO
383 getbintime(&cur_bt);
384 bintime_sub(&cur_bt, &io->io_hdr.dma_start_bt);
385 bintime_add(&io->io_hdr.dma_bt, &cur_bt);
386 io->io_hdr.num_dmas++;
387#endif
388 io->scsiio.kern_rel_offset += io->scsiio.kern_data_len;
375
376 /*
377 * We set status at this point for read commands, and write
378 * commands with errors.
379 */
389
390 /*
391 * We set status at this point for read commands, and write
392 * commands with errors.
393 */
380 if ((beio->bio_cmd == BIO_READ)
381 && (io->io_hdr.port_status == 0)
382 && ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0)
383 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE))
384 ctl_set_success(&io->scsiio);
394 if ((io->io_hdr.port_status == 0) &&
395 ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0) &&
396 ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) {
397 lbalen = ARGS(beio->io);
398 if (lbalen->flags & CTL_LLF_READ) {
399 ctl_set_success(&io->scsiio);
400 } else if (lbalen->flags & CTL_LLF_COMPARE) {
401 /* We have two data blocks ready for comparison. */
402 for (i = 0; i < beio->num_segs; i++) {
403 if (memcmp(beio->sg_segs[i].addr,
404 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr,
405 beio->sg_segs[i].len) != 0)
406 break;
407 }
408 if (i < beio->num_segs)
409 ctl_set_sense(&io->scsiio,
410 /*current_error*/ 1,
411 /*sense_key*/ SSD_KEY_MISCOMPARE,
412 /*asc*/ 0x1D,
413 /*ascq*/ 0x00,
414 SSD_ELEM_NONE);
415 else
416 ctl_set_success(&io->scsiio);
417 }
418 }
385 else if ((io->io_hdr.port_status != 0)
386 && ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0)
387 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) {
388 /*
389 * For hardware error sense keys, the sense key
390 * specific value is defined to be a retry count,
391 * but we use it to pass back an internal FETD
392 * error code. XXX KDM Hopefully the FETD is only

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

488 /*retry_count*/ 0xbad2);
489 } else
490 ctl_set_medium_error(&io->scsiio);
491 ctl_complete_beio(beio);
492 return;
493 }
494
495 /*
419 else if ((io->io_hdr.port_status != 0)
420 && ((io->io_hdr.flags & CTL_FLAG_ABORT) == 0)
421 && ((io->io_hdr.status & CTL_STATUS_MASK) == CTL_STATUS_NONE)) {
422 /*
423 * For hardware error sense keys, the sense key
424 * specific value is defined to be a retry count,
425 * but we use it to pass back an internal FETD
426 * error code. XXX KDM Hopefully the FETD is only

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

522 /*retry_count*/ 0xbad2);
523 } else
524 ctl_set_medium_error(&io->scsiio);
525 ctl_complete_beio(beio);
526 return;
527 }
528
529 /*
496 * If this is a write, a flush or a delete, we're all done.
530 * If this is a write, a flush, a delete or verify, we're all done.
497 * If this is a read, we can now send the data to the user.
498 */
499 if ((beio->bio_cmd == BIO_WRITE)
500 || (beio->bio_cmd == BIO_FLUSH)
531 * If this is a read, we can now send the data to the user.
532 */
533 if ((beio->bio_cmd == BIO_WRITE)
534 || (beio->bio_cmd == BIO_FLUSH)
501 || (beio->bio_cmd == BIO_DELETE)) {
535 || (beio->bio_cmd == BIO_DELETE)
536 || (ARGS(io)->flags & CTL_LLF_VERIFY)) {
502 ctl_set_success(&io->scsiio);
503 ctl_complete_beio(beio);
504 } else {
505#ifdef CTL_TIME_IO
506 getbintime(&io->io_hdr.dma_start_bt);
507#endif
508 ctl_datamove(io);
509 }

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

569 int error, i;
570
571 DPRINTF("entered\n");
572
573 file_data = &be_lun->backend.file;
574 io = beio->io;
575 flags = beio->bio_flags;
576
537 ctl_set_success(&io->scsiio);
538 ctl_complete_beio(beio);
539 } else {
540#ifdef CTL_TIME_IO
541 getbintime(&io->io_hdr.dma_start_bt);
542#endif
543 ctl_datamove(io);
544 }

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

604 int error, i;
605
606 DPRINTF("entered\n");
607
608 file_data = &be_lun->backend.file;
609 io = beio->io;
610 flags = beio->bio_flags;
611
612 bzero(&xuio, sizeof(xuio));
577 if (beio->bio_cmd == BIO_READ) {
578 SDT_PROBE(cbb, kernel, read, file_start, 0, 0, 0, 0, 0);
613 if (beio->bio_cmd == BIO_READ) {
614 SDT_PROBE(cbb, kernel, read, file_start, 0, 0, 0, 0, 0);
615 xuio.uio_rw = UIO_READ;
579 } else {
580 SDT_PROBE(cbb, kernel, write, file_start, 0, 0, 0, 0, 0);
616 } else {
617 SDT_PROBE(cbb, kernel, write, file_start, 0, 0, 0, 0, 0);
581 }
582
583 bzero(&xuio, sizeof(xuio));
584 if (beio->bio_cmd == BIO_READ)
585 xuio.uio_rw = UIO_READ;
586 else
587 xuio.uio_rw = UIO_WRITE;
618 xuio.uio_rw = UIO_WRITE;
588
619 }
589 xuio.uio_offset = beio->io_offset;
590 xuio.uio_resid = beio->io_len;
591 xuio.uio_segflg = UIO_SYSSPACE;
592 xuio.uio_iov = beio->xiovecs;
593 xuio.uio_iovcnt = beio->num_segs;
594 xuio.uio_td = curthread;
595
596 for (i = 0, xiovec = xuio.uio_iov; i < xuio.uio_iovcnt; i++, xiovec++) {

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

623 *
624 * So, to attempt to provide some barrier semantics in the
625 * BIO_ORDERED case, set both IO_DIRECT and IO_SYNC.
626 */
627 error = VOP_READ(be_lun->vn, &xuio, (flags & BIO_ORDERED) ?
628 (IO_DIRECT|IO_SYNC) : 0, file_data->cred);
629
630 VOP_UNLOCK(be_lun->vn, 0);
620 xuio.uio_offset = beio->io_offset;
621 xuio.uio_resid = beio->io_len;
622 xuio.uio_segflg = UIO_SYSSPACE;
623 xuio.uio_iov = beio->xiovecs;
624 xuio.uio_iovcnt = beio->num_segs;
625 xuio.uio_td = curthread;
626
627 for (i = 0, xiovec = xuio.uio_iov; i < xuio.uio_iovcnt; i++, xiovec++) {

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

654 *
655 * So, to attempt to provide some barrier semantics in the
656 * BIO_ORDERED case, set both IO_DIRECT and IO_SYNC.
657 */
658 error = VOP_READ(be_lun->vn, &xuio, (flags & BIO_ORDERED) ?
659 (IO_DIRECT|IO_SYNC) : 0, file_data->cred);
660
661 VOP_UNLOCK(be_lun->vn, 0);
662 SDT_PROBE(cbb, kernel, read, file_done, 0, 0, 0, 0, 0);
631 } else {
632 struct mount *mountpoint;
633 int lock_flags;
634
635 (void)vn_start_write(be_lun->vn, &mountpoint, V_WAIT);
636
637 if (MNT_SHARED_WRITES(mountpoint)
638 || ((mountpoint == NULL)

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

664 * So if we've got the BIO_ORDERED flag set, we want
665 * IO_SYNC in either the UFS or ZFS case.
666 */
667 error = VOP_WRITE(be_lun->vn, &xuio, (flags & BIO_ORDERED) ?
668 IO_SYNC : 0, file_data->cred);
669 VOP_UNLOCK(be_lun->vn, 0);
670
671 vn_finished_write(mountpoint);
663 } else {
664 struct mount *mountpoint;
665 int lock_flags;
666
667 (void)vn_start_write(be_lun->vn, &mountpoint, V_WAIT);
668
669 if (MNT_SHARED_WRITES(mountpoint)
670 || ((mountpoint == NULL)

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

696 * So if we've got the BIO_ORDERED flag set, we want
697 * IO_SYNC in either the UFS or ZFS case.
698 */
699 error = VOP_WRITE(be_lun->vn, &xuio, (flags & BIO_ORDERED) ?
700 IO_SYNC : 0, file_data->cred);
701 VOP_UNLOCK(be_lun->vn, 0);
702
703 vn_finished_write(mountpoint);
704 SDT_PROBE(cbb, kernel, write, file_done, 0, 0, 0, 0, 0);
672 }
673
674 /*
675 * If we got an error, set the sense data to "MEDIUM ERROR" and
676 * return the I/O to the user.
677 */
678 if (error != 0) {
679 char path_str[32];

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

690 ctl_complete_beio(beio);
691 return;
692 }
693
694 /*
695 * If this is a write, we're all done.
696 * If this is a read, we can now send the data to the user.
697 */
705 }
706
707 /*
708 * If we got an error, set the sense data to "MEDIUM ERROR" and
709 * return the I/O to the user.
710 */
711 if (error != 0) {
712 char path_str[32];

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

723 ctl_complete_beio(beio);
724 return;
725 }
726
727 /*
728 * If this is a write, we're all done.
729 * If this is a read, we can now send the data to the user.
730 */
698 if (beio->bio_cmd == BIO_WRITE) {
731 if (ARGS(io)->flags & (CTL_LLF_WRITE | CTL_LLF_VERIFY)) {
699 ctl_set_success(&io->scsiio);
732 ctl_set_success(&io->scsiio);
700 SDT_PROBE(cbb, kernel, write, file_done, 0, 0, 0, 0, 0);
701 ctl_complete_beio(beio);
702 } else {
733 ctl_complete_beio(beio);
734 } else {
703 SDT_PROBE(cbb, kernel, read, file_done, 0, 0, 0, 0, 0);
704#ifdef CTL_TIME_IO
705 getbintime(&io->io_hdr.dma_start_bt);
706#endif
707 ctl_datamove(io);
708 }
709}
710
711static void

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

932 uint64_t len_left, lba;
933 int i, seglen;
934 uint8_t *buf, *end;
935
936 DPRINTF("entered\n");
937
938 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
939 softc = be_lun->softc;
735#ifdef CTL_TIME_IO
736 getbintime(&io->io_hdr.dma_start_bt);
737#endif
738 ctl_datamove(io);
739 }
740}
741
742static void

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

963 uint64_t len_left, lba;
964 int i, seglen;
965 uint8_t *buf, *end;
966
967 DPRINTF("entered\n");
968
969 beio = (struct ctl_be_block_io *)PRIV(io)->ptr;
970 softc = be_lun->softc;
940 lbalen = (struct ctl_lba_len_flags *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
971 lbalen = ARGS(beio->io);
941
942 if (lbalen->flags & ~(SWS_LBDATA | SWS_UNMAP) ||
943 (lbalen->flags & SWS_UNMAP && be_lun->unmap == NULL)) {
944 ctl_free_beio(beio);
945 ctl_set_invalid_field(&io->scsiio,
946 /*sks_valid*/ 1,
947 /*command*/ 1,
948 /*field*/ 1,

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

1152 struct ctl_be_block_lun *be_lun;
1153 union ctl_io *io;
1154
1155 io = beio->io;
1156 be_lun = beio->lun;
1157 ctl_free_beio(beio);
1158 if (((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE)
1159 && ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_SUCCESS)) {
972
973 if (lbalen->flags & ~(SWS_LBDATA | SWS_UNMAP) ||
974 (lbalen->flags & SWS_UNMAP && be_lun->unmap == NULL)) {
975 ctl_free_beio(beio);
976 ctl_set_invalid_field(&io->scsiio,
977 /*sks_valid*/ 1,
978 /*command*/ 1,
979 /*field*/ 1,

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

1183 struct ctl_be_block_lun *be_lun;
1184 union ctl_io *io;
1185
1186 io = beio->io;
1187 be_lun = beio->lun;
1188 ctl_free_beio(beio);
1189 if (((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE)
1190 && ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_SUCCESS)) {
1160 ctl_done(io);
1191 ctl_data_submit_done(io);
1161 return;
1162 }
1163
1192 return;
1193 }
1194
1164 io->scsiio.kern_rel_offset += io->scsiio.kern_data_len;
1165 io->io_hdr.status &= ~CTL_STATUS_MASK;
1166 io->io_hdr.status |= CTL_STATUS_NONE;
1167
1168 mtx_lock(&be_lun->lock);
1169 /*
1170 * XXX KDM make sure that links is okay to use at this point.
1171 * Otherwise, we either need to add another field to ctl_io_hdr,
1172 * or deal with resource allocation here.

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

1178}
1179
1180static void
1181ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun,
1182 union ctl_io *io)
1183{
1184 struct ctl_be_block_io *beio;
1185 struct ctl_be_block_softc *softc;
1195 io->io_hdr.status &= ~CTL_STATUS_MASK;
1196 io->io_hdr.status |= CTL_STATUS_NONE;
1197
1198 mtx_lock(&be_lun->lock);
1199 /*
1200 * XXX KDM make sure that links is okay to use at this point.
1201 * Otherwise, we either need to add another field to ctl_io_hdr,
1202 * or deal with resource allocation here.

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

1208}
1209
1210static void
1211ctl_be_block_dispatch(struct ctl_be_block_lun *be_lun,
1212 union ctl_io *io)
1213{
1214 struct ctl_be_block_io *beio;
1215 struct ctl_be_block_softc *softc;
1186 struct ctl_lba_len *lbalen;
1216 struct ctl_lba_len_flags *lbalen;
1187 struct ctl_ptr_len_flags *bptrlen;
1188 uint64_t len_left, lbas;
1189 int i;
1190
1191 softc = be_lun->softc;
1192
1193 DPRINTF("entered\n");
1194
1217 struct ctl_ptr_len_flags *bptrlen;
1218 uint64_t len_left, lbas;
1219 int i;
1220
1221 softc = be_lun->softc;
1222
1223 DPRINTF("entered\n");
1224
1195 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) {
1196 SDT_PROBE(cbb, kernel, read, start, 0, 0, 0, 0, 0);
1197 } else {
1225 lbalen = ARGS(io);
1226 if (lbalen->flags & CTL_LLF_WRITE) {
1198 SDT_PROBE(cbb, kernel, write, start, 0, 0, 0, 0, 0);
1227 SDT_PROBE(cbb, kernel, write, start, 0, 0, 0, 0, 0);
1228 } else {
1229 SDT_PROBE(cbb, kernel, read, start, 0, 0, 0, 0, 0);
1199 }
1200
1201 beio = ctl_alloc_beio(softc);
1202 beio->io = io;
1203 beio->lun = be_lun;
1204 bptrlen = PRIV(io);
1205 bptrlen->ptr = (void *)beio;
1206

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

1228 case CTL_TAG_UNTAGGED:
1229 case CTL_TAG_SIMPLE:
1230 case CTL_TAG_ACA:
1231 default:
1232 beio->ds_tag_type = DEVSTAT_TAG_SIMPLE;
1233 break;
1234 }
1235
1230 }
1231
1232 beio = ctl_alloc_beio(softc);
1233 beio->io = io;
1234 beio->lun = be_lun;
1235 bptrlen = PRIV(io);
1236 bptrlen->ptr = (void *)beio;
1237

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

1259 case CTL_TAG_UNTAGGED:
1260 case CTL_TAG_SIMPLE:
1261 case CTL_TAG_ACA:
1262 default:
1263 beio->ds_tag_type = DEVSTAT_TAG_SIMPLE;
1264 break;
1265 }
1266
1236 /*
1237 * This path handles read and write only. The config write path
1238 * handles flush operations.
1239 */
1240 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) {
1241 beio->bio_cmd = BIO_READ;
1242 beio->ds_trans_type = DEVSTAT_READ;
1243 } else {
1267 if (lbalen->flags & CTL_LLF_WRITE) {
1244 beio->bio_cmd = BIO_WRITE;
1245 beio->ds_trans_type = DEVSTAT_WRITE;
1268 beio->bio_cmd = BIO_WRITE;
1269 beio->ds_trans_type = DEVSTAT_WRITE;
1270 } else {
1271 beio->bio_cmd = BIO_READ;
1272 beio->ds_trans_type = DEVSTAT_READ;
1246 }
1247
1273 }
1274
1248 lbalen = (struct ctl_lba_len *)&io->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
1249 DPRINTF("%s at LBA %jx len %u @%ju\n",
1250 (beio->bio_cmd == BIO_READ) ? "READ" : "WRITE",
1251 (uintmax_t)lbalen->lba, lbalen->len, bptrlen->len);
1275 DPRINTF("%s at LBA %jx len %u @%ju\n",
1276 (beio->bio_cmd == BIO_READ) ? "READ" : "WRITE",
1277 (uintmax_t)lbalen->lba, lbalen->len, bptrlen->len);
1252 lbas = MIN(lbalen->len - bptrlen->len,
1253 CTLBLK_MAX_IO_SIZE / be_lun->blocksize);
1278 if (lbalen->flags & CTL_LLF_COMPARE)
1279 lbas = CTLBLK_HALF_IO_SIZE;
1280 else
1281 lbas = CTLBLK_MAX_IO_SIZE;
1282 lbas = MIN(lbalen->len - bptrlen->len, lbas / be_lun->blocksize);
1254 beio->io_offset = (lbalen->lba + bptrlen->len) * be_lun->blocksize;
1255 beio->io_len = lbas * be_lun->blocksize;
1256 bptrlen->len += lbas;
1257
1258 for (i = 0, len_left = beio->io_len; len_left > 0; i++) {
1259 KASSERT(i < CTLBLK_MAX_SEGS, ("Too many segs (%d >= %d)",
1260 i, CTLBLK_MAX_SEGS));
1261
1262 /*
1263 * Setup the S/G entry for this chunk.
1264 */
1265 beio->sg_segs[i].len = min(CTLBLK_MAX_SEG, len_left);
1266 beio->sg_segs[i].addr = uma_zalloc(be_lun->lun_zone, M_WAITOK);
1267
1268 DPRINTF("segment %d addr %p len %zd\n", i,
1269 beio->sg_segs[i].addr, beio->sg_segs[i].len);
1270
1283 beio->io_offset = (lbalen->lba + bptrlen->len) * be_lun->blocksize;
1284 beio->io_len = lbas * be_lun->blocksize;
1285 bptrlen->len += lbas;
1286
1287 for (i = 0, len_left = beio->io_len; len_left > 0; i++) {
1288 KASSERT(i < CTLBLK_MAX_SEGS, ("Too many segs (%d >= %d)",
1289 i, CTLBLK_MAX_SEGS));
1290
1291 /*
1292 * Setup the S/G entry for this chunk.
1293 */
1294 beio->sg_segs[i].len = min(CTLBLK_MAX_SEG, len_left);
1295 beio->sg_segs[i].addr = uma_zalloc(be_lun->lun_zone, M_WAITOK);
1296
1297 DPRINTF("segment %d addr %p len %zd\n", i,
1298 beio->sg_segs[i].addr, beio->sg_segs[i].len);
1299
1300 /* Set up second segment for compare operation. */
1301 if (lbalen->flags & CTL_LLF_COMPARE) {
1302 beio->sg_segs[i + CTLBLK_HALF_SEGS].len =
1303 beio->sg_segs[i].len;
1304 beio->sg_segs[i + CTLBLK_HALF_SEGS].addr =
1305 uma_zalloc(be_lun->lun_zone, M_WAITOK);
1306 }
1307
1271 beio->num_segs++;
1272 len_left -= beio->sg_segs[i].len;
1273 }
1274 if (bptrlen->len < lbalen->len)
1275 beio->beio_cont = ctl_be_block_next;
1276 io->scsiio.be_move_done = ctl_be_block_move_done;
1308 beio->num_segs++;
1309 len_left -= beio->sg_segs[i].len;
1310 }
1311 if (bptrlen->len < lbalen->len)
1312 beio->beio_cont = ctl_be_block_next;
1313 io->scsiio.be_move_done = ctl_be_block_move_done;
1277 io->scsiio.kern_data_ptr = (uint8_t *)beio->sg_segs;
1314 /* For compare we have separate S/G lists for read and datamove. */
1315 if (lbalen->flags & CTL_LLF_COMPARE)
1316 io->scsiio.kern_data_ptr = (uint8_t *)&beio->sg_segs[CTLBLK_HALF_SEGS];
1317 else
1318 io->scsiio.kern_data_ptr = (uint8_t *)beio->sg_segs;
1278 io->scsiio.kern_data_len = beio->io_len;
1279 io->scsiio.kern_data_resid = 0;
1280 io->scsiio.kern_sg_entries = beio->num_segs;
1281 io->io_hdr.flags |= CTL_FLAG_ALLOCATED | CTL_FLAG_KDPTR_SGLIST;
1282
1283 /*
1284 * For the read case, we need to read the data into our buffers and
1285 * then we can send it back to the user. For the write case, we

--- 1228 unchanged lines hidden ---
1319 io->scsiio.kern_data_len = beio->io_len;
1320 io->scsiio.kern_data_resid = 0;
1321 io->scsiio.kern_sg_entries = beio->num_segs;
1322 io->io_hdr.flags |= CTL_FLAG_ALLOCATED | CTL_FLAG_KDPTR_SGLIST;
1323
1324 /*
1325 * For the read case, we need to read the data into our buffers and
1326 * then we can send it back to the user. For the write case, we

--- 1228 unchanged lines hidden ---