ctl.c (268556) | ctl.c (268673) |
---|---|
1/*- 2 * Copyright (c) 2003-2009 Silicon Graphics International Corp. 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Edward Tomasz Napierala 7 * under sponsorship from the FreeBSD Foundation. 8 * --- 28 unchanged lines hidden (view full) --- 37 * CAM Target Layer, a SCSI device emulation subsystem. 38 * 39 * Author: Ken Merry <ken@FreeBSD.org> 40 */ 41 42#define _CTL_C 43 44#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003-2009 Silicon Graphics International Corp. 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Edward Tomasz Napierala 7 * under sponsorship from the FreeBSD Foundation. 8 * --- 28 unchanged lines hidden (view full) --- 37 * CAM Target Layer, a SCSI device emulation subsystem. 38 * 39 * Author: Ken Merry <ken@FreeBSD.org> 40 */ 41 42#define _CTL_C 43 44#include <sys/cdefs.h> |
45__FBSDID("$FreeBSD: stable/10/sys/cam/ctl/ctl.c 268556 2014-07-12 04:34:39Z mav $"); | 45__FBSDID("$FreeBSD: stable/10/sys/cam/ctl/ctl.c 268673 2014-07-15 16:49:35Z mav $"); |
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> 52#include <sys/bio.h> 53#include <sys/fcntl.h> --- 24 unchanged lines hidden (view full) --- 78#include <cam/ctl/ctl_private.h> 79#include <cam/ctl/ctl_debug.h> 80#include <cam/ctl/ctl_scsi_all.h> 81#include <cam/ctl/ctl_error.h> 82 83struct ctl_softc *control_softc = NULL; 84 85/* | 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> 52#include <sys/bio.h> 53#include <sys/fcntl.h> --- 24 unchanged lines hidden (view full) --- 78#include <cam/ctl/ctl_private.h> 79#include <cam/ctl/ctl_debug.h> 80#include <cam/ctl/ctl_scsi_all.h> 81#include <cam/ctl/ctl_error.h> 82 83struct ctl_softc *control_softc = NULL; 84 85/* |
86 * Use the serial number and device ID provided by the backend, rather than 87 * making up our own. 88 */ 89#define CTL_USE_BACKEND_SN 90 91/* | |
92 * Size and alignment macros needed for Copan-specific HA hardware. These 93 * can go away when the HA code is re-written, and uses busdma for any 94 * hardware. 95 */ 96#define CTL_ALIGN_8B(target, source, type) \ 97 if (((uint32_t)source & 0x7) != 0) \ 98 target = (type)(source + (0x8 - ((uint32_t)source & 0x7)));\ 99 else \ --- 9375 unchanged lines hidden (view full) --- 9475 return (CTL_RETVAL_COMPLETE); 9476} 9477 9478static int 9479ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len) 9480{ 9481 struct scsi_vpd_unit_serial_number *sn_ptr; 9482 struct ctl_lun *lun; | 86 * Size and alignment macros needed for Copan-specific HA hardware. These 87 * can go away when the HA code is re-written, and uses busdma for any 88 * hardware. 89 */ 90#define CTL_ALIGN_8B(target, source, type) \ 91 if (((uint32_t)source & 0x7) != 0) \ 92 target = (type)(source + (0x8 - ((uint32_t)source & 0x7)));\ 93 else \ --- 9375 unchanged lines hidden (view full) --- 9469 return (CTL_RETVAL_COMPLETE); 9470} 9471 9472static int 9473ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len) 9474{ 9475 struct scsi_vpd_unit_serial_number *sn_ptr; 9476 struct ctl_lun *lun; |
9483#ifndef CTL_USE_BACKEND_SN 9484 char tmpstr[32]; 9485#endif | |
9486 9487 lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; 9488 9489 ctsio->kern_data_ptr = malloc(sizeof(*sn_ptr), M_CTL, M_WAITOK | M_ZERO); 9490 sn_ptr = (struct scsi_vpd_unit_serial_number *)ctsio->kern_data_ptr; 9491 ctsio->kern_sg_entries = 0; 9492 9493 if (sizeof(*sn_ptr) < alloc_len) { --- 17 unchanged lines hidden (view full) --- 9511 if (lun != NULL) 9512 sn_ptr->device = (SID_QUAL_LU_CONNECTED << 5) | 9513 lun->be_lun->lun_type; 9514 else 9515 sn_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT; 9516 9517 sn_ptr->page_code = SVPD_UNIT_SERIAL_NUMBER; 9518 sn_ptr->length = ctl_min(sizeof(*sn_ptr) - 4, CTL_SN_LEN); | 9477 9478 lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; 9479 9480 ctsio->kern_data_ptr = malloc(sizeof(*sn_ptr), M_CTL, M_WAITOK | M_ZERO); 9481 sn_ptr = (struct scsi_vpd_unit_serial_number *)ctsio->kern_data_ptr; 9482 ctsio->kern_sg_entries = 0; 9483 9484 if (sizeof(*sn_ptr) < alloc_len) { --- 17 unchanged lines hidden (view full) --- 9502 if (lun != NULL) 9503 sn_ptr->device = (SID_QUAL_LU_CONNECTED << 5) | 9504 lun->be_lun->lun_type; 9505 else 9506 sn_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT; 9507 9508 sn_ptr->page_code = SVPD_UNIT_SERIAL_NUMBER; 9509 sn_ptr->length = ctl_min(sizeof(*sn_ptr) - 4, CTL_SN_LEN); |
9519#ifdef CTL_USE_BACKEND_SN | |
9520 /* 9521 * If we don't have a LUN, we just leave the serial number as 9522 * all spaces. 9523 */ 9524 memset(sn_ptr->serial_num, 0x20, sizeof(sn_ptr->serial_num)); 9525 if (lun != NULL) { 9526 strncpy((char *)sn_ptr->serial_num, 9527 (char *)lun->be_lun->serial_num, CTL_SN_LEN); 9528 } | 9510 /* 9511 * If we don't have a LUN, we just leave the serial number as 9512 * all spaces. 9513 */ 9514 memset(sn_ptr->serial_num, 0x20, sizeof(sn_ptr->serial_num)); 9515 if (lun != NULL) { 9516 strncpy((char *)sn_ptr->serial_num, 9517 (char *)lun->be_lun->serial_num, CTL_SN_LEN); 9518 } |
9529#else 9530 /* 9531 * Note that we're using a non-unique serial number here, 9532 */ 9533 snprintf(tmpstr, sizeof(tmpstr), "MYSERIALNUMIS000"); 9534 memset(sn_ptr->serial_num, 0x20, sizeof(sn_ptr->serial_num)); 9535 strncpy(sn_ptr->serial_num, tmpstr, ctl_min(CTL_SN_LEN, 9536 ctl_min(sizeof(tmpstr), sizeof(*sn_ptr) - 4))); 9537#endif | |
9538 ctsio->scsi_status = SCSI_STATUS_OK; 9539 9540 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 9541 ctsio->be_move_done = ctl_config_move_done; 9542 ctl_datamove((union ctl_io *)ctsio); 9543 9544 return (CTL_RETVAL_COMPLETE); 9545} --- 5 unchanged lines hidden (view full) --- 9551 struct scsi_vpd_device_id *devid_ptr; 9552 struct scsi_vpd_id_descriptor *desc, *desc1; 9553 struct scsi_vpd_id_descriptor *desc2, *desc3; /* for types 4h and 5h */ 9554 struct scsi_vpd_id_t10 *t10id; 9555 struct ctl_softc *ctl_softc; 9556 struct ctl_lun *lun; 9557 struct ctl_frontend *fe; 9558 char *val; | 9519 ctsio->scsi_status = SCSI_STATUS_OK; 9520 9521 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 9522 ctsio->be_move_done = ctl_config_move_done; 9523 ctl_datamove((union ctl_io *)ctsio); 9524 9525 return (CTL_RETVAL_COMPLETE); 9526} --- 5 unchanged lines hidden (view full) --- 9532 struct scsi_vpd_device_id *devid_ptr; 9533 struct scsi_vpd_id_descriptor *desc, *desc1; 9534 struct scsi_vpd_id_descriptor *desc2, *desc3; /* for types 4h and 5h */ 9535 struct scsi_vpd_id_t10 *t10id; 9536 struct ctl_softc *ctl_softc; 9537 struct ctl_lun *lun; 9538 struct ctl_frontend *fe; 9539 char *val; |
9559#ifndef CTL_USE_BACKEND_SN 9560 char tmpstr[32]; 9561#endif /* CTL_USE_BACKEND_SN */ 9562 int devid_len; | 9540 int data_len, devid_len; |
9563 9564 ctl_softc = control_softc; 9565 9566 fe = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)]; 9567 9568 if (fe->devid != NULL) 9569 return ((fe->devid)(ctsio, alloc_len)); 9570 9571 lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; 9572 | 9541 9542 ctl_softc = control_softc; 9543 9544 fe = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)]; 9545 9546 if (fe->devid != NULL) 9547 return ((fe->devid)(ctsio, alloc_len)); 9548 9549 lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; 9550 |
9573 devid_len = sizeof(struct scsi_vpd_device_id) + | 9551 if (lun == NULL) { 9552 devid_len = CTL_DEVID_MIN_LEN; 9553 } else { 9554 devid_len = max(CTL_DEVID_MIN_LEN, 9555 strnlen(lun->be_lun->device_id, CTL_DEVID_LEN)); 9556 } 9557 9558 data_len = sizeof(struct scsi_vpd_device_id) + |
9574 sizeof(struct scsi_vpd_id_descriptor) + | 9559 sizeof(struct scsi_vpd_id_descriptor) + |
9575 sizeof(struct scsi_vpd_id_t10) + CTL_DEVID_LEN + | 9560 sizeof(struct scsi_vpd_id_t10) + devid_len + |
9576 sizeof(struct scsi_vpd_id_descriptor) + CTL_WWPN_LEN + 9577 sizeof(struct scsi_vpd_id_descriptor) + 9578 sizeof(struct scsi_vpd_id_rel_trgt_port_id) + 9579 sizeof(struct scsi_vpd_id_descriptor) + 9580 sizeof(struct scsi_vpd_id_trgt_port_grp_id); 9581 | 9561 sizeof(struct scsi_vpd_id_descriptor) + CTL_WWPN_LEN + 9562 sizeof(struct scsi_vpd_id_descriptor) + 9563 sizeof(struct scsi_vpd_id_rel_trgt_port_id) + 9564 sizeof(struct scsi_vpd_id_descriptor) + 9565 sizeof(struct scsi_vpd_id_trgt_port_grp_id); 9566 |
9582 ctsio->kern_data_ptr = malloc(devid_len, M_CTL, M_WAITOK | M_ZERO); | 9567 ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); |
9583 devid_ptr = (struct scsi_vpd_device_id *)ctsio->kern_data_ptr; 9584 ctsio->kern_sg_entries = 0; 9585 | 9568 devid_ptr = (struct scsi_vpd_device_id *)ctsio->kern_data_ptr; 9569 ctsio->kern_sg_entries = 0; 9570 |
9586 if (devid_len < alloc_len) { 9587 ctsio->residual = alloc_len - devid_len; 9588 ctsio->kern_data_len = devid_len; 9589 ctsio->kern_total_len = devid_len; | 9571 if (data_len < alloc_len) { 9572 ctsio->residual = alloc_len - data_len; 9573 ctsio->kern_data_len = data_len; 9574 ctsio->kern_total_len = data_len; |
9590 } else { 9591 ctsio->residual = 0; 9592 ctsio->kern_data_len = alloc_len; 9593 ctsio->kern_total_len = alloc_len; 9594 } 9595 ctsio->kern_data_resid = 0; 9596 ctsio->kern_rel_offset = 0; 9597 ctsio->kern_sg_entries = 0; 9598 9599 desc = (struct scsi_vpd_id_descriptor *)devid_ptr->desc_list; 9600 t10id = (struct scsi_vpd_id_t10 *)&desc->identifier[0]; 9601 desc1 = (struct scsi_vpd_id_descriptor *)(&desc->identifier[0] + | 9575 } else { 9576 ctsio->residual = 0; 9577 ctsio->kern_data_len = alloc_len; 9578 ctsio->kern_total_len = alloc_len; 9579 } 9580 ctsio->kern_data_resid = 0; 9581 ctsio->kern_rel_offset = 0; 9582 ctsio->kern_sg_entries = 0; 9583 9584 desc = (struct scsi_vpd_id_descriptor *)devid_ptr->desc_list; 9585 t10id = (struct scsi_vpd_id_t10 *)&desc->identifier[0]; 9586 desc1 = (struct scsi_vpd_id_descriptor *)(&desc->identifier[0] + |
9602 sizeof(struct scsi_vpd_id_t10) + CTL_DEVID_LEN); | 9587 sizeof(struct scsi_vpd_id_t10) + devid_len); |
9603 desc2 = (struct scsi_vpd_id_descriptor *)(&desc1->identifier[0] + 9604 CTL_WWPN_LEN); 9605 desc3 = (struct scsi_vpd_id_descriptor *)(&desc2->identifier[0] + 9606 sizeof(struct scsi_vpd_id_rel_trgt_port_id)); 9607 9608 /* 9609 * The control device is always connected. The disk device, on the 9610 * other hand, may not be online all the time. 9611 */ 9612 if (lun != NULL) 9613 devid_ptr->device = (SID_QUAL_LU_CONNECTED << 5) | 9614 lun->be_lun->lun_type; 9615 else 9616 devid_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT; 9617 9618 devid_ptr->page_code = SVPD_DEVICE_ID; 9619 | 9588 desc2 = (struct scsi_vpd_id_descriptor *)(&desc1->identifier[0] + 9589 CTL_WWPN_LEN); 9590 desc3 = (struct scsi_vpd_id_descriptor *)(&desc2->identifier[0] + 9591 sizeof(struct scsi_vpd_id_rel_trgt_port_id)); 9592 9593 /* 9594 * The control device is always connected. The disk device, on the 9595 * other hand, may not be online all the time. 9596 */ 9597 if (lun != NULL) 9598 devid_ptr->device = (SID_QUAL_LU_CONNECTED << 5) | 9599 lun->be_lun->lun_type; 9600 else 9601 devid_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT; 9602 9603 devid_ptr->page_code = SVPD_DEVICE_ID; 9604 |
9620 scsi_ulto2b(devid_len - 4, devid_ptr->length); | 9605 scsi_ulto2b(data_len - 4, devid_ptr->length); |
9621 9622 /* 9623 * For Fibre channel, 9624 */ 9625 if (fe->port_type == CTL_PORT_FC) 9626 { 9627 desc->proto_codeset = (SCSI_PROTO_FC << 4) | 9628 SVPD_ID_CODESET_ASCII; --- 9 unchanged lines hidden (view full) --- 9638 } 9639 desc2->proto_codeset = desc3->proto_codeset = desc1->proto_codeset; 9640 9641 /* 9642 * We're using a LUN association here. i.e., this device ID is a 9643 * per-LUN identifier. 9644 */ 9645 desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_LUN | SVPD_ID_TYPE_T10; | 9606 9607 /* 9608 * For Fibre channel, 9609 */ 9610 if (fe->port_type == CTL_PORT_FC) 9611 { 9612 desc->proto_codeset = (SCSI_PROTO_FC << 4) | 9613 SVPD_ID_CODESET_ASCII; --- 9 unchanged lines hidden (view full) --- 9623 } 9624 desc2->proto_codeset = desc3->proto_codeset = desc1->proto_codeset; 9625 9626 /* 9627 * We're using a LUN association here. i.e., this device ID is a 9628 * per-LUN identifier. 9629 */ 9630 desc->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_LUN | SVPD_ID_TYPE_T10; |
9646 desc->length = sizeof(*t10id) + CTL_DEVID_LEN; | 9631 desc->length = sizeof(*t10id) + devid_len; |
9647 if (lun == NULL || (val = ctl_get_opt(lun->be_lun, "vendor")) == NULL) { 9648 strncpy((char *)t10id->vendor, CTL_VENDOR, sizeof(t10id->vendor)); 9649 } else { 9650 memset(t10id->vendor, ' ', sizeof(t10id->vendor)); 9651 strncpy(t10id->vendor, val, 9652 min(sizeof(t10id->vendor), strlen(val))); 9653 } 9654 --- 40 unchanged lines hidden (view full) --- 9695 desc3->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT 9696 | SVPD_ID_TYPE_TPORTGRP; 9697 desc3->length = 4; 9698 if (ctsio->io_hdr.nexus.targ_port < CTL_MAX_PORTS || ctl_is_single) 9699 desc3->identifier[3] = 1; 9700 else 9701 desc3->identifier[3] = 2; 9702 | 9632 if (lun == NULL || (val = ctl_get_opt(lun->be_lun, "vendor")) == NULL) { 9633 strncpy((char *)t10id->vendor, CTL_VENDOR, sizeof(t10id->vendor)); 9634 } else { 9635 memset(t10id->vendor, ' ', sizeof(t10id->vendor)); 9636 strncpy(t10id->vendor, val, 9637 min(sizeof(t10id->vendor), strlen(val))); 9638 } 9639 --- 40 unchanged lines hidden (view full) --- 9680 desc3->id_type = SVPD_ID_PIV | SVPD_ID_ASSOC_PORT 9681 | SVPD_ID_TYPE_TPORTGRP; 9682 desc3->length = 4; 9683 if (ctsio->io_hdr.nexus.targ_port < CTL_MAX_PORTS || ctl_is_single) 9684 desc3->identifier[3] = 1; 9685 else 9686 desc3->identifier[3] = 2; 9687 |
9703#ifdef CTL_USE_BACKEND_SN | |
9704 /* 9705 * If we've actually got a backend, copy the device id from the 9706 * per-LUN data. Otherwise, set it to all spaces. 9707 */ 9708 if (lun != NULL) { 9709 /* 9710 * Copy the backend's LUN ID. 9711 */ 9712 strncpy((char *)t10id->vendor_spec_id, | 9688 /* 9689 * If we've actually got a backend, copy the device id from the 9690 * per-LUN data. Otherwise, set it to all spaces. 9691 */ 9692 if (lun != NULL) { 9693 /* 9694 * Copy the backend's LUN ID. 9695 */ 9696 strncpy((char *)t10id->vendor_spec_id, |
9713 (char *)lun->be_lun->device_id, CTL_DEVID_LEN); | 9697 (char *)lun->be_lun->device_id, devid_len); |
9714 } else { 9715 /* 9716 * No backend, set this to spaces. 9717 */ | 9698 } else { 9699 /* 9700 * No backend, set this to spaces. 9701 */ |
9718 memset(t10id->vendor_spec_id, 0x20, CTL_DEVID_LEN); | 9702 memset(t10id->vendor_spec_id, 0x20, devid_len); |
9719 } | 9703 } |
9720#else 9721 snprintf(tmpstr, sizeof(tmpstr), "MYDEVICEIDIS%4d", 9722 (lun != NULL) ? (int)lun->lun : 0); 9723 strncpy(t10id->vendor_spec_id, tmpstr, ctl_min(CTL_DEVID_LEN, 9724 sizeof(tmpstr))); 9725#endif | |
9726 9727 ctsio->scsi_status = SCSI_STATUS_OK; 9728 9729 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 9730 ctsio->be_move_done = ctl_config_move_done; 9731 ctl_datamove((union ctl_io *)ctsio); 9732 9733 return (CTL_RETVAL_COMPLETE); --- 3846 unchanged lines hidden --- | 9704 9705 ctsio->scsi_status = SCSI_STATUS_OK; 9706 9707 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 9708 ctsio->be_move_done = ctl_config_move_done; 9709 ctl_datamove((union ctl_io *)ctsio); 9710 9711 return (CTL_RETVAL_COMPLETE); --- 3846 unchanged lines hidden --- |