/* * Copyright (c) 2008, Intel Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU Lesser General Public License, * version 2.1, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * */ #include "utils.h" #include "api_lib.h" #include "adapt_impl.h" #include "bind_impl.h" #include "fc_scsi.h" /* * Inquiry V1. */ HBA_STATUS scsi_inquiry_v1(HBA_HANDLE handle, HBA_WWN disc_wwpn, HBA_UINT64 fc_lun, HBA_UINT8 evpd, HBA_UINT32 page_code, void *resp, HBA_UINT32 resp_len, void *sense, HBA_UINT32 sense_len) { struct port_info *pp; char sg_name[50]; HBA_UINT8 stat; HBA_STATUS status; /* * Find port. */ pp = adapter_get_port(handle, 0); if (pp == NULL) return HBA_STATUS_ERROR_INVALID_HANDLE; if (get_binding_sg_name( pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0) return HBA_STATUS_ERROR_TARGET_LUN; status = sg_issue_inquiry(sg_name, evpd ? SCSI_INQF_EVPD : 0, page_code, resp, &resp_len, &stat, sense, &sense_len); if (status == HBA_STATUS_OK && stat == SCSI_ST_CHECK) status = HBA_STATUS_SCSI_CHECK_CONDITION; return status; } /* * Inquiry V2. */ HBA_STATUS scsi_inquiry_v2(HBA_HANDLE handle, HBA_WWN wwpn, HBA_WWN disc_wwpn, HBA_UINT64 fc_lun, HBA_UINT8 cdb_byte1, HBA_UINT8 cdb_byte2, void *resp, HBA_UINT32 *resp_lenp, HBA_UINT8 *statp, void *sense, HBA_UINT32 *sense_lenp) { struct port_info *pp; char sg_name[50]; /* * Find port. */ pp = adapter_get_port_by_wwn(handle, wwpn, NULL); if (pp == NULL) return HBA_STATUS_ERROR_ILLEGAL_WWN; if (get_binding_sg_name( pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0) return HBA_STATUS_ERROR_TARGET_LUN; return sg_issue_inquiry(sg_name, cdb_byte1, cdb_byte2, resp, resp_lenp, statp, sense, sense_lenp); } /* * Read capacity V1. */ HBA_STATUS scsi_read_capacity_v1(HBA_HANDLE handle, HBA_WWN disc_wwpn, HBA_UINT64 fc_lun, void *resp, HBA_UINT32 resp_len, void *sense, HBA_UINT32 sense_len) { struct port_info *pp; char sg_name[50]; HBA_UINT8 stat; HBA_STATUS status; /* * Find port. */ pp = adapter_get_port(handle, 0); if (pp == NULL) return HBA_STATUS_ERROR_INVALID_HANDLE; if (get_binding_sg_name( pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0) return HBA_STATUS_ERROR_TARGET_LUN; status = sg_issue_read_capacity(sg_name, resp, &resp_len, &stat, sense, &sense_len); if (status == HBA_STATUS_OK && stat == SCSI_ST_CHECK) status = HBA_STATUS_SCSI_CHECK_CONDITION; return status; } /* * Read capacity V2. */ HBA_STATUS scsi_read_capacity_v2(HBA_HANDLE handle, HBA_WWN wwpn, HBA_WWN disc_wwpn, HBA_UINT64 fc_lun, void *resp, HBA_UINT32 *resp_lenp, HBA_UINT8 *statp, void *sense, HBA_UINT32 *sense_lenp) { struct port_info *pp; char sg_name[50]; /* * Find port. */ pp = adapter_get_port_by_wwn(handle, wwpn, NULL); if (pp == NULL) return HBA_STATUS_ERROR_ILLEGAL_WWN; if (get_binding_sg_name( pp, disc_wwpn, fc_lun, sg_name, sizeof(sg_name)) != 0) return HBA_STATUS_ERROR_TARGET_LUN; return sg_issue_read_capacity(sg_name, resp, resp_lenp, statp, sense, sense_lenp); } /* * Report LUNS V1. */ HBA_STATUS scsi_report_luns_v1(HBA_HANDLE handle, HBA_WWN disc_wwpn, void *resp, HBA_UINT32 resp_len, void *sense, HBA_UINT32 sense_len) { struct port_info *pp; char sg_name[50]; HBA_UINT8 stat; HBA_STATUS status; /* * Find port. */ pp = adapter_get_port(handle, 0); if (pp == NULL) return HBA_STATUS_ERROR_INVALID_HANDLE; if (get_binding_sg_name( pp, disc_wwpn, 0, sg_name, sizeof(sg_name)) != 0) return HBA_STATUS_ERROR_TARGET_PORT_WWN; status = sg_issue_report_luns(sg_name, resp, &resp_len, &stat, sense, &sense_len); if (status == HBA_STATUS_OK && stat == SCSI_ST_CHECK) status = HBA_STATUS_SCSI_CHECK_CONDITION; return status; } /* * Report LUNS V2. */ HBA_STATUS scsi_report_luns_v2(HBA_HANDLE handle, HBA_WWN wwpn, HBA_WWN disc_wwpn, void *resp, HBA_UINT32 *resp_lenp, HBA_UINT8 *statp, void *sense, HBA_UINT32 *sense_lenp) { struct port_info *pp; char sg_name[50]; /* * Find port. */ pp = adapter_get_port_by_wwn(handle, wwpn, NULL); if (pp == NULL) return HBA_STATUS_ERROR_ILLEGAL_WWN; if (get_binding_sg_name( pp, disc_wwpn, 0, sg_name, sizeof(sg_name)) != 0) return HBA_STATUS_ERROR_TARGET_PORT_WWN; return sg_issue_report_luns(sg_name, resp, resp_lenp, statp, sense, sense_lenp); }