From owner-svn-src-all@FreeBSD.ORG Tue Jul 15 17:09:53 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 6CDB0386; Tue, 15 Jul 2014 17:09:53 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4D1662CDA; Tue, 15 Jul 2014 17:09:53 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s6FH9rqd085123; Tue, 15 Jul 2014 17:09:53 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s6FH9qmp085121; Tue, 15 Jul 2014 17:09:52 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201407151709.s6FH9qmp085121@svn.freebsd.org> From: Alexander Motin Date: Tue, 15 Jul 2014 17:09:52 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r268687 - in stable/10/sys/cam: ctl scsi X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jul 2014 17:09:53 -0000 Author: mav Date: Tue Jul 15 17:09:52 2014 New Revision: 268687 URL: http://svnweb.freebsd.org/changeset/base/268687 Log: MFC r268309: Add support for SCSI Ports (88h) VPD page. Modified: stable/10/sys/cam/ctl/ctl.c stable/10/sys/cam/scsi/scsi_all.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/cam/ctl/ctl.c ============================================================================== --- stable/10/sys/cam/ctl/ctl.c Tue Jul 15 17:09:02 2014 (r268686) +++ stable/10/sys/cam/ctl/ctl.c Tue Jul 15 17:09:52 2014 (r268687) @@ -317,10 +317,11 @@ SYSCTL_INT(_kern_cam_ctl, OID_AUTO, verb &verbose, 0, "Show SCSI errors returned to initiator"); /* - * Serial number (0x80), device id (0x83), supported pages (0x00), - * Block limits (0xB0) and Logical Block Provisioning (0xB2) + * Supported pages (0x00), Serial number (0x80), Device ID (0x83), + * SCSI Ports (0x88), Block limits (0xB0) and + * Logical Block Provisioning (0xB2) */ -#define SCSI_EVPD_NUM_SUPPORTED_PAGES 5 +#define SCSI_EVPD_NUM_SUPPORTED_PAGES 6 static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event, int param); @@ -378,6 +379,8 @@ static void ctl_hndl_per_res_out_on_othe static int ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len); static int ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len); static int ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len); +static int ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, + int alloc_len); static int ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len); static int ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len); @@ -7240,7 +7243,7 @@ ctl_report_tagret_port_groups(struct ctl TPG_ASYMMETRIC_ACCESS_NONOPTIMIZED; tpg_desc->support = TPG_AO_SUP; if (!single) - tpg_desc->support = TPG_AN_SUP; + tpg_desc->support |= TPG_AN_SUP; scsi_ulto2b(g + 1, tpg_desc->target_port_group); tpg_desc->status = TPG_IMPLICIT; pc = 0; @@ -9628,10 +9631,12 @@ ctl_inquiry_evpd_supported(struct ctl_sc pages->page_list[1] = SVPD_UNIT_SERIAL_NUMBER; /* Device Identification */ pages->page_list[2] = SVPD_DEVICE_ID; + /* SCSI Ports */ + pages->page_list[3] = SVPD_SCSI_PORTS; /* Block limits */ - pages->page_list[3] = SVPD_BLOCK_LIMITS; + pages->page_list[4] = SVPD_BLOCK_LIMITS; /* Logical Block Provisioning */ - pages->page_list[4] = SVPD_LBP; + pages->page_list[5] = SVPD_LBP; ctsio->scsi_status = SCSI_STATUS_OK; @@ -9822,6 +9827,117 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio } static int +ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len) +{ + struct ctl_softc *softc = control_softc; + struct scsi_vpd_scsi_ports *sp; + struct scsi_vpd_port_designation *pd; + struct scsi_vpd_port_designation_cont *pdc; + struct ctl_lun *lun; + struct ctl_port *port; + int data_len, num_target_ports, id_len, g, pg, p; + int num_target_port_groups, single; + + lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; + + single = ctl_is_single; + if (single) + num_target_port_groups = 1; + else + num_target_port_groups = NUM_TARGET_PORT_GROUPS; + num_target_ports = 0; + id_len = 0; + mtx_lock(&softc->ctl_lock); + STAILQ_FOREACH(port, &softc->port_list, links) { + if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) + continue; + if (ctl_map_lun_back(port->targ_port, lun->lun) >= + CTL_MAX_LUNS) + continue; + num_target_ports++; + if (port->port_devid) + id_len += port->port_devid->len; + } + mtx_unlock(&softc->ctl_lock); + + data_len = sizeof(struct scsi_vpd_scsi_ports) + num_target_port_groups * + num_target_ports * (sizeof(struct scsi_vpd_port_designation) + + sizeof(struct scsi_vpd_port_designation_cont)) + id_len; + ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO); + sp = (struct scsi_vpd_scsi_ports *)ctsio->kern_data_ptr; + ctsio->kern_sg_entries = 0; + + if (data_len < alloc_len) { + ctsio->residual = alloc_len - data_len; + ctsio->kern_data_len = data_len; + ctsio->kern_total_len = data_len; + } else { + ctsio->residual = 0; + ctsio->kern_data_len = alloc_len; + ctsio->kern_total_len = alloc_len; + } + ctsio->kern_data_resid = 0; + ctsio->kern_rel_offset = 0; + ctsio->kern_sg_entries = 0; + + /* + * The control device is always connected. The disk device, on the + * other hand, may not be online all the time. Need to change this + * to figure out whether the disk device is actually online or not. + */ + if (lun != NULL) + sp->device = (SID_QUAL_LU_CONNECTED << 5) | + lun->be_lun->lun_type; + else + sp->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT; + + sp->page_code = SVPD_SCSI_PORTS; + scsi_ulto2b(data_len - sizeof(struct scsi_vpd_scsi_ports), + sp->page_length); + pd = &sp->design[0]; + + mtx_lock(&softc->ctl_lock); + if (softc->flags & CTL_FLAG_MASTER_SHELF) + pg = 0; + else + pg = 1; + for (g = 0; g < num_target_port_groups; g++) { + STAILQ_FOREACH(port, &softc->port_list, links) { + if ((port->status & CTL_PORT_STATUS_ONLINE) == 0) + continue; + if (ctl_map_lun_back(port->targ_port, lun->lun) >= + CTL_MAX_LUNS) + continue; + p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS; + scsi_ulto2b(p, pd->relative_port_id); + scsi_ulto2b(0, pd->initiator_transportid_length); + pdc = (struct scsi_vpd_port_designation_cont *) + &pd->initiator_transportid[0]; + if (port->port_devid && g == pg) { + id_len = port->port_devid->len; + scsi_ulto2b(port->port_devid->len, + pdc->target_port_descriptors_length); + memcpy(pdc->target_port_descriptors, + port->port_devid->data, port->port_devid->len); + } else { + id_len = 0; + scsi_ulto2b(0, pdc->target_port_descriptors_length); + } + pd = (struct scsi_vpd_port_designation *) + ((uint8_t *)pdc->target_port_descriptors + id_len); + } + } + mtx_unlock(&softc->ctl_lock); + + ctsio->scsi_status = SCSI_STATUS_OK; + ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; + ctsio->be_move_done = ctl_config_move_done; + ctl_datamove((union ctl_io *)ctsio); + + return (CTL_RETVAL_COMPLETE); +} + +static int ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len) { struct scsi_vpd_block_limits *bl_ptr; @@ -9952,6 +10068,9 @@ ctl_inquiry_evpd(struct ctl_scsiio *ctsi case SVPD_DEVICE_ID: retval = ctl_inquiry_evpd_devid(ctsio, alloc_len); break; + case SVPD_SCSI_PORTS: + retval = ctl_inquiry_evpd_scsi_ports(ctsio, alloc_len); + break; case SVPD_BLOCK_LIMITS: retval = ctl_inquiry_evpd_block_limits(ctsio, alloc_len); break; Modified: stable/10/sys/cam/scsi/scsi_all.h ============================================================================== --- stable/10/sys/cam/scsi/scsi_all.h Tue Jul 15 17:09:02 2014 (r268686) +++ stable/10/sys/cam/scsi/scsi_all.h Tue Jul 15 17:09:52 2014 (r268687) @@ -1564,6 +1564,31 @@ struct scsi_diag_page { uint8_t params[0]; }; +struct scsi_vpd_port_designation +{ + uint8_t reserved[2]; + uint8_t relative_port_id[2]; + uint8_t reserved2[2]; + uint8_t initiator_transportid_length[2]; + uint8_t initiator_transportid[0]; +}; + +struct scsi_vpd_port_designation_cont +{ + uint8_t reserved[2]; + uint8_t target_port_descriptors_length[2]; + struct scsi_vpd_id_descriptor target_port_descriptors[0]; +}; + +struct scsi_vpd_scsi_ports +{ + u_int8_t device; + u_int8_t page_code; +#define SVPD_SCSI_PORTS 0x88 + u_int8_t page_length[2]; + struct scsi_vpd_port_designation design[]; +}; + /* * ATA Information VPD Page based on * T10/2126-D Revision 04 @@ -1754,8 +1779,9 @@ struct scsi_target_group { uint8_t opcode; uint8_t service_action; +#define STG_PDF_MASK 0xe0 #define STG_PDF_LENGTH 0x00 -#define RPL_PDF_EXTENDED 0x20 +#define STG_PDF_EXTENDED 0x20 uint8_t reserved1[4]; uint8_t length[4]; uint8_t reserved2; @@ -1805,7 +1831,7 @@ struct scsi_target_group_data { struct scsi_target_group_data_extended { uint8_t length[4]; /* length of returned data, in bytes */ - uint8_t format_type; /* STG_PDF_LENGTH or RPL_PDF_EXTENDED */ + uint8_t format_type; /* STG_PDF_LENGTH or STG_PDF_EXTENDED */ uint8_t implicit_transition_time; uint8_t reserved[2]; struct scsi_target_port_group_descriptor groups[];