sata.c revision 8d483882aa3390058094b043f3d62187b5d1de03
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CDDL HEADER START
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The contents of this file are subject to the terms of the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Common Development and Distribution License (the "License").
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * You may not use this file except in compliance with the License.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * See the License for the specific language governing permissions
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * and limitations under the License.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * When distributing Covered Code, include this CDDL HEADER in each
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If applicable, add the following below this CDDL HEADER, with the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * fields enclosed by brackets "[]" replaced with your own identifying
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * information: Portions Copyright [yyyy] [name of copyright owner]
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * CDDL HEADER END
4e54023805e14cf984b9f0041df73c16334a7a88ls * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Use is subject to license terms.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#pragma ident "%Z%%M% %I% %E% SMI"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA Framework
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Generic SATA Host Adapter Implementation
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* Debug flags - defined in sata.h */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Flags enabling selected SATA HBA framework functionality
37a077ef1920ee044b2887247b2a802e726d3368ls SATA_ENABLE_PROCESS_EVENTS | SATA_ENABLE_QUEUING | SATA_ENABLE_NCQ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic void sata_save_atapi_trace(sata_pkt_txlate_t *, int);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown#define SATAATAPITRACE(spx, count) if (sata_atapi_trace_save) \
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_test_atapi_packet_command(sata_hba_inst_t *, int);
8d483882aa3390058094b043f3d62187b5d1de03mlf#define LEGACY_HWID_LEN 64 /* Model (40) + Serial (20) + pad */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA cb_ops functions
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_hba_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCSA required entry points
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_scsi_tgt_init(dev_info_t *, dev_info_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf int (*callback)(void));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_scsi_tgt_free(dev_info_t *, dev_info_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_scsi_start(struct scsi_address *, struct scsi_pkt *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_scsi_abort(struct scsi_address *, struct scsi_pkt *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_scsi_getcap(struct scsi_address *, char *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_scsi_setcap(struct scsi_address *, char *, int, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic struct scsi_pkt *sata_scsi_init_pkt(struct scsi_address *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf struct scsi_pkt *, struct buf *, int, int, int, int, int (*)(caddr_t),
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_scsi_destroy_pkt(struct scsi_address *, struct scsi_pkt *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_scsi_dmafree(struct scsi_address *, struct scsi_pkt *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_scsi_sync_pkt(struct scsi_address *, struct scsi_pkt *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA HBA interface functions are defined in sata_hba.h header file
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* Event processing functions */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_event_daemon(void *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_event_thread_control(int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_process_controller_events(sata_hba_inst_t *sata_hba_inst);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_process_device_reset(sata_hba_inst_t *, sata_address_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_process_port_failed_event(sata_hba_inst_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_process_port_link_events(sata_hba_inst_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_process_device_detached(sata_hba_inst_t *, sata_address_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_process_device_attached(sata_hba_inst_t *, sata_address_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_process_port_pwr_change(sata_hba_inst_t *, sata_address_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_process_cntrl_pwr_level_change(sata_hba_inst_t *);
4360436b3c604bc28d37be269ad152b4c38157c3pawelwstatic void sata_process_target_node_cleanup(sata_hba_inst_t *,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Local translation functions
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_txlt_test_unit_ready(sata_pkt_txlate_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_txlt_start_stop_unit(sata_pkt_txlate_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_txlt_synchronize_cache(sata_pkt_txlate_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_txlt_nodata_cmd_immediate(sata_pkt_txlate_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_txlt_invalid_command(sata_pkt_txlate_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_txlt_lba_out_of_range(sata_pkt_txlate_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_txlt_nodata_cmd_completion(sata_pkt_t *);
a022fe3e0bc959fae460b8b5b818cd1265bf4c66lsstatic void sata_txlt_download_mcode_cmd_completion(sata_pkt_t *);
4360436b3c604bc28d37be269ad152b4c38157c3pawelwstatic int sata_emul_rw_completion(sata_pkt_txlate_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic struct scsi_extended_sense *sata_immediate_error_response(
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic struct scsi_extended_sense *sata_arq_sense(sata_pkt_txlate_t *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic void sata_txlt_atapi_completion(sata_pkt_t *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Local functions for ioctl
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int32_t sata_get_port_num(sata_hba_inst_t *, struct devctl_iocdata *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic void sata_cfgadm_state(sata_hba_inst_t *, int32_t,
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic dev_info_t *sata_get_target_dip(dev_info_t *, int32_t);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Local functions
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_validate_sata_hba_tran(dev_info_t *, sata_hba_tran_t *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_reprobe_port(sata_hba_inst_t *, sata_device_t *, int);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_add_device(dev_info_t *, sata_hba_inst_t *, int cport,
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic dev_info_t *sata_create_target_node(dev_info_t *, sata_hba_inst_t *,
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_validate_scsi_address(sata_hba_inst_t *,
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_validate_sata_address(sata_hba_inst_t *, int, int, int);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic sata_pkt_t *sata_pkt_alloc(sata_pkt_txlate_t *, int (*)(caddr_t));
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_dma_buf_setup(sata_pkt_txlate_t *, int, int (*)(caddr_t),
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_probe_device(sata_hba_inst_t *, sata_device_t *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic sata_drive_info_t *sata_get_device_info(sata_hba_inst_t *,
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_identify_device(sata_hba_inst_t *, sata_drive_info_t *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic struct buf *sata_alloc_local_buffer(sata_pkt_txlate_t *, int);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic void sata_free_local_buffer(sata_pkt_txlate_t *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic uint64_t sata_check_capacity(sata_drive_info_t *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownvoid sata_adjust_dma_attr(sata_drive_info_t *, ddi_dma_attr_t *,
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_fetch_device_identify_data(sata_hba_inst_t *,
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic void sata_update_port_info(sata_hba_inst_t *, sata_device_t *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic void sata_update_port_scr(sata_port_scr_t *, sata_device_t *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_set_dma_mode(sata_hba_inst_t *, sata_drive_info_t *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_set_cache_mode(sata_hba_inst_t *, sata_drive_info_t *, int);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_set_rmsn(sata_hba_inst_t *, sata_drive_info_t *, int);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_set_drive_features(sata_hba_inst_t *,
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic void sata_init_write_cache_mode(sata_drive_info_t *sdinfo);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_initialize_device(sata_hba_inst_t *, sata_drive_info_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_identdev_to_inquiry(sata_hba_inst_t *, sata_drive_info_t *,
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_get_atapi_inquiry_data(sata_hba_inst_t *, sata_address_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_build_msense_page_1(sata_drive_info_t *, int, uint8_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_build_msense_page_8(sata_drive_info_t *, int, uint8_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_build_msense_page_1a(sata_drive_info_t *, int, uint8_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_build_msense_page_1c(sata_drive_info_t *, int, uint8_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf struct mode_cache_scsi3 *, int, int *, int *, int *);
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls struct mode_info_excpt_page *, int, int *, int *, int *);
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960lsstatic int sata_build_msense_page_30(sata_drive_info_t *, int, uint8_t *);
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls struct mode_acoustic_management *, int, int *, int *, int *);
c03acfcad7780db4ddf763511a82026680b3b2c1lsstatic int sata_build_lsense_page_0(sata_drive_info_t *, uint8_t *);
c03acfcad7780db4ddf763511a82026680b3b2c1lsstatic int sata_build_lsense_page_10(sata_drive_info_t *, uint8_t *,
c03acfcad7780db4ddf763511a82026680b3b2c1lsstatic int sata_build_lsense_page_2f(sata_drive_info_t *, uint8_t *,
c03acfcad7780db4ddf763511a82026680b3b2c1lsstatic int sata_build_lsense_page_30(sata_drive_info_t *, uint8_t *,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_save_drive_settings(sata_drive_info_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_show_drive_info(sata_hba_inst_t *, sata_drive_info_t *);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void sata_log(sata_hba_inst_t *, uint_t, char *fmt, ...);
4360436b3c604bc28d37be269ad152b4c38157c3pawelwstatic int sata_fetch_smart_return_status(sata_hba_inst_t *,
4360436b3c604bc28d37be269ad152b4c38157c3pawelwstatic int sata_fetch_smart_data(sata_hba_inst_t *, sata_drive_info_t *,
4360436b3c604bc28d37be269ad152b4c38157c3pawelwstatic int sata_ext_smart_selftest_read_log(sata_hba_inst_t *,
c03acfcad7780db4ddf763511a82026680b3b2c1ls sata_drive_info_t *, struct smart_ext_selftest_log *, uint16_t);
c03acfcad7780db4ddf763511a82026680b3b2c1lsstatic int sata_smart_read_log(sata_hba_inst_t *, sata_drive_info_t *,
c03acfcad7780db4ddf763511a82026680b3b2c1lsstatic int sata_read_log_ext_directory(sata_hba_inst_t *, sata_drive_info_t *,
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelwstatic void sata_gen_sysevent(sata_hba_inst_t *, sata_address_t *, int);
4360436b3c604bc28d37be269ad152b4c38157c3pawelwstatic boolean_t sata_check_device_removed(dev_info_t *);
4360436b3c604bc28d37be269ad152b4c38157c3pawelwstatic void sata_set_target_node_cleanup(sata_hba_inst_t *, int cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic int sata_atapi_err_ret_cmd_setup(sata_pkt_txlate_t *,
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic void sata_atapi_packet_cmd_setup(sata_cmd_t *, sata_drive_info_t *);
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic void sata_fixed_sense_data_preset(struct scsi_extended_sense *);
8d483882aa3390058094b043f3d62187b5d1de03mlfstatic void sata_target_devid_register(dev_info_t *, sata_drive_info_t *);
8d483882aa3390058094b043f3d62187b5d1de03mlfstatic int sata_check_modser(char *, int);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA Framework will ignore SATA HBA driver cb_ops structure and
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * register following one with SCSA framework.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Open & close are provided, so scsi framework will not use its own
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf 0, /* streamtab */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Default sata pkt timeout. Used when a target driver scsi_pkt time is zero,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * i.e. when scsi_pkt has not timeout specified.
7a70ede882eacbae00c8d5209afb443e7755684cpawelw * Intermediate buffer device access attributes - they are required,
7a70ede882eacbae00c8d5209afb443e7755684cpawelw * but not necessarily used.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Mutexes protecting structures in multithreaded operations.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Because events are relatively rare, a single global mutex protecting
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * data structures should be sufficient. To increase performance, add
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * separate mutex per each sata port and use global mutex only to protect
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * common data structures.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown/* Default write cache setting for SATA hard disks */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown/* Default write cache setting for SATA ATAPI CD/DVD */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Linked list of HBA instances
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Pointer to per-instance SATA HBA soft structure is stored in sata_hba_tran
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * structure and in sata soft state.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Event daemon related variables
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic int sata_event_pending = 0;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * NCQ error recovery command
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * ATAPI error recovery CDB
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic const uint8_t sata_rqsense_cdb[SATA_ATAPI_RQSENSE_CDB_LEN] = {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown 0, /* Only fixed RQ format is supported */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_ATAPI_MIN_RQSENSE_LEN, /* Less data may be returned */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* Warlock directives */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_hba_tran))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_device))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_extended_sense))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", scsi_arq_status))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", ddi_dma_attr))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", ddi_dma_cookie_t))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", devctl_ap_state))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", dev_info::devi_state))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(MUTEX_PROTECTS_DATA(sata_mutex, sata_hba_inst::satahba_next))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(MUTEX_PROTECTS_DATA(sata_mutex, sata_hba_inst::satahba_prev))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", sata_hba_inst::satahba_tran))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", sata_hba_inst::satahba_dip))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(SCHEME_PROTECTS_DATA("Scheme", sata_hba_inst::satahba_attached))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(DATA_READABLE_WITHOUT_LOCK(sata_hba_inst::satahba_dev_port))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(MUTEX_PROTECTS_DATA(sata_cport_info::cport_mutex, \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(DATA_READABLE_WITHOUT_LOCK(sata_cport_info::cport_devp))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(SCHEME_PROTECTS_DATA("Scheme", sata_cport_info::cport_addr))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(MUTEX_PROTECTS_DATA(sata_cport_info::cport_mutex, \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(DATA_READABLE_WITHOUT_LOCK(sata_cport_info::cport_dev_type))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(MUTEX_PROTECTS_DATA(sata_cport_info::cport_mutex, \
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(DATA_READABLE_WITHOUT_LOCK(sata_cport_info::cport_state))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(DATA_READABLE_WITHOUT_LOCK(sata_pmport_info::pmport_dev_type))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(DATA_READABLE_WITHOUT_LOCK(sata_pmport_info::pmport_sata_drive))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(DATA_READABLE_WITHOUT_LOCK(sata_pmult_info::pmult_dev_port))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf_NOTE(DATA_READABLE_WITHOUT_LOCK(sata_pmult_info::pmult_num_dev_ports))
37a077ef1920ee044b2887247b2a802e726d3368ls_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mbuf_count))
37a077ef1920ee044b2887247b2a802e726d3368ls_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", mbuffail_count))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", sata_atapi_trace))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown_NOTE(SCHEME_PROTECTS_DATA("No Mutex Needed", sata_atapi_trace_index))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* End of warlock directives */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* ************** loadable module configuration functions ************** */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_init(&sata_event_mutex, NULL, MUTEX_DRIVER, NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* ********************* SATA HBA entry points ********************* */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Called by SATA HBA from _init().
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Registers HBA driver instance/sata framework pair with scsi framework, by
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * calling scsi_hba_init().
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA HBA driver cb_ops are ignored - SATA HBA framework cb_ops are used
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * instead. SATA HBA framework cb_ops pointer overwrites SATA HBA driver
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * cb_ops pointer in SATA HBA driver dev_ops structure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA HBA framework cb_ops supplies cb_open cb_close and cb_ioctl vectors.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Return status of the scsi_hba_init() is returned to a calling SATA HBA
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_init: name %s \n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ((struct modldrv *)(modlp->ml_linkage[0]))->drv_linkinfo);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Fill-up cb_ops and dev_ops when necessary
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf hba_ops = ((struct modldrv *)(modlp->ml_linkage[0]))->drv_dev_ops;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Provide pointer to SATA dev_ops
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Register SATA HBA with SCSI framework
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* HBA attach stages */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Called from SATA HBA driver's attach routine to attach an instance of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the HBA.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * For DDI_ATTACH command:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_hba_inst structure is allocated here and initialized with pointers to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA framework implementation of required scsi tran functions.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The scsi_tran's tran_hba_private field is used by SATA Framework to point
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to the soft structure (sata_hba_inst) allocated by SATA framework for
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA HBA instance related data.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The scsi_tran's tran_hba_private field is used by SATA framework to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * store a pointer to per-HBA-instance of sata_hba_inst structure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The sata_hba_inst structure is cross-linked to scsi tran structure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Among other info, a pointer to sata_hba_tran structure is stored in
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_hba_inst. The sata_hba_inst structures for different HBA instances are
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * linked together into the list, pointed to by sata_hba_list.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * On the first HBA instance attach the sata event thread is initialized.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Attachment points are created for all SATA ports of the HBA being attached.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * All HBA instance's SATA ports are probed and type of plugged devices is
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * determined. For each device of a supported type, a target node is created.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DDI_SUCCESS is returned when attachment process is successful,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DDI_FAILURE is returned otherwise.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * For DDI_RESUME command:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Not implemented at this time (postponed until phase 2 of the development).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_hba_attach(dev_info_t *dip, sata_hba_tran_t *sata_tran,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_attach: node %s (%s%d)\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Postponed until phase 2 of the development
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* cmd == DDI_ATTACH */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_validate_sata_hba_tran(dip, sata_tran) != SATA_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_attach: invalid sata_hba_tran"));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Allocate and initialize SCSI tran structure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA copy of tran_bus_config is provided to create port nodes.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf scsi_tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Allocate soft structure for SATA HBA instance.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * There is a separate softstate for each HBA instance.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_inst = kmem_zalloc(sizeof (struct sata_hba_inst), KM_SLEEP);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT(sata_hba_inst != NULL); /* this should not fail */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_init(&sata_hba_inst->satahba_mutex, NULL, MUTEX_DRIVER, NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * scsi_trans's tran_hba_private is used by SATA Framework to point to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * soft structure allocated by SATA framework for
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA HBA instance related data.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (scsi_hba_attach_setup(dip, sata_tran->sata_tran_hba_dma_attr,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "sata")) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "failed to create hba sata prop"));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Save pointers in hba instance soft state.
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw * Create a task queue to handle emulated commands completion
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw * Use node name, dash, instance number as the queue name.
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw (void) strlcat(taskq_name, DEVI(dip)->devi_node_name,
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw sata_hba_inst->satahba_taskq = taskq_create(taskq_name, 1,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Create events thread if not created yet.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Link this hba instance into the list.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Create SATA HBA devctl minor node for sata_hba_open, close, ioctl
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA HBA driver should not use its own open/close entry points.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Make sure that instance number doesn't overflow
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * when forming minor numbers.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT(ddi_get_instance(dip) <= (L_MAXMIN >> INST_MINOR_SHIFT));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "cannot create devctl minor node");
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Set-up kstats here, if necessary.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * (postponed until phase 2 of the development).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Probe controller ports. This operation will describe a current
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * controller/port/multipliers/device configuration and will create
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * attachment points.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We may end-up with just a controller with no devices attached.
6ed1276fb5fe78fb1cce38682748a830ef8bd157pawelw * For the ports with a supported device attached, device target nodes
6ed1276fb5fe78fb1cce38682748a830ef8bd157pawelw * are created and devices are initialized.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (hba_attach_state & HBA_ATTACH_STAGE_SATA_HBA_INST) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sizeof (struct sata_hba_inst));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_log(NULL, CE_WARN, "?SATA: %s%d hba attach failed",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Called by SATA HBA from to detach an instance of the driver.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * For DDI_DETACH command:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Free local structures allocated for SATA HBA instance during
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_hba_attach processing.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns DDI_SUCCESS when HBA was detached, DDI_FAILURE otherwise.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * For DDI_SUSPEND command:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Not implemented at this time (postponed until phase 2 of the development)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returnd DDI_SUCCESS.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * When the last HBA instance is detached, the event daemon is terminated.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * NOTE: cport support only, no port multiplier support.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SATADBG3(SATA_DBG_HBA_IF, NULL, "sata_hba_detach: node %s (%s%d)\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ddi_node_name(dip), ddi_driver_name(dip), ddi_get_instance(dip));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (cmd) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((scsi_hba_tran = ddi_get_driver_private(dip)) == NULL)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Free all target nodes - at this point
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * devices should be at least offlined
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * otherwise scsi_hba_detach() should not be called.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (ncport = 0; ncport < SATA_NUM_CPORTS(sata_hba_inst);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_detach: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Target node not "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "removed !"));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Disable sata event daemon processing for this HBA
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Remove event daemon thread, if it is last HBA instance.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Remove this HBA instance from the HBA list */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * At this point there should be no target nodes attached.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Detach and destroy device and port info structures.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (ncport = 0; ncport < SATA_NUM_CPORTS(sata_hba_inst);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Release device structure */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Release cport info */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sizeof (struct sata_hba_inst));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Postponed until phase 2
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Called by an HBA drive from _fini() routine.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Unregisters SATA HBA instance/SATA framework pair from the scsi framework.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_fini: name %s\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ((struct modldrv *)(modlp->ml_linkage[0]))->drv_linkinfo);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Default open and close routine for sata_hba framework.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Open devctl node.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 0 if node was open successfully, error code otherwise.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_hba_open(dev_t *devp, int flags, int otyp, cred_t *credp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SATADBG1(SATA_DBG_IOCTL_IF, NULL, "sata_hba_open: entered", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((scsi_hba_tran = ddi_get_driver_private(dip)) == NULL)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_hba_inst == NULL || sata_hba_inst->satahba_attached == 0)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_hba_inst->satahba_open_flag == SATA_DEVCTL_EXOPENED) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Close devctl node.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 0 if node was closed successfully, error code otherwise.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_hba_close(dev_t dev, int flag, int otyp, cred_t *credp)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SATADBG1(SATA_DBG_IOCTL_IF, NULL, "sata_hba_close: entered", NULL);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((scsi_hba_tran = ddi_get_driver_private(dip)) == NULL)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_hba_inst == NULL || sata_hba_inst->satahba_attached == 0)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Standard IOCTL commands for SATA hotplugging.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implemented DEVCTL_AP commands:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_AP_CONNECT
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_AP_DISCONNECT
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_AP_CONFIGURE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_UNCONFIGURE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_AP_CONTROL
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Commands passed to default ndi ioctl handler:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_DEVICE_GETSTATE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_DEVICE_ONLINE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_DEVICE_OFFLINE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_DEVICE_REMOVE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_DEVICE_INSERT
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_BUS_GETSTATE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * All other cmds are passed to HBA if it provide ioctl handler, or failed
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 0 if successful,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * error code if operation failed.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * NOTE: Port Multiplier is not supported.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_hba_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((scsi_hba_tran = ddi_get_driver_private(dip)) == NULL)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (cmd) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * There may be more cases that we want to pass to default
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * handler rather than fail them.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* read devctl ioctl data */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((comp_port = sata_get_port_num(sata_hba_inst, dcp)) ==
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Only cport is considered now, i.e. SATA_ADDR_CPORT */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_validate_sata_address(sata_hba_inst, cport, pmport,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (cportinfo->cport_event_flags & SATA_EVNT_LOCK_PORT_BUSY) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Cannot process ioctl request now. Come back later.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Block event processing for this port */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cportinfo->cport_event_flags |= SATA_APCTL_LOCK_PORT_BUSY;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (cmd) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Normally, cfgadm sata plugin will try to offline
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * (unconfigure) device before this request. Nevertheless,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * if a device is still configured, we need to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * attempt to offline and unconfigure device first, and we will
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * deactivate the port regardless of the unconfigure
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * operation results.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_AP_DISCONNECT invokes
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_hba_inst->satahba_tran->
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_tran_hotplug_ops->sata_tran_port_deactivate().
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If successful, the device structure (if any) attached
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to a port is removed and state of the port marked
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * appropriately.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Failure of the port_deactivate may keep port in
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the active state, or may fail the port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Check the current state of the port */
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw /* Sanity check */
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw if (SATA_PORT_DEACTIVATE_FUNC(sata_hba_inst) == NULL) {
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw /* No physical port deactivation supported. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * set port's dev_state to not ready - this will disable
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * an access to an attached device.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If a target node exists, try to offline
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a device and remove target node.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * A target node remained
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * attached. This happens when
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * the file was open or a node
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * was waiting for resources.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Cannot do anything about it.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "sata_hba_ioctl: "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "disconnect: could not "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "unconfigure device before "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "disconnecting the SATA "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Set DEVICE REMOVED state
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * in the target node. It
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * will prevent access to
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * the device even when a
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * new device is attached,
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * until the old target node
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * is released, removed and
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * recreated for a new
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Instruct event daemon to
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * try the target node cleanup
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Remove and release sata_drive_info
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * structure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note: PMult info requires different handling.
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * Put PMult handling code here, when PMult is
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * supported.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Just ask HBA driver to deactivate port */
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * Generate sysevent - EC_DR / ESC_DR_AP_STATE_CHANGE
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * without the hint.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Port deactivation failure - do not
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * change port state unless the state
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * returned by HBA indicates a port failure.
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * Deactivation succeded. From now on the framework
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * will not know what is happening to the device, until
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * the port is activated again.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The unconfigure operation uses generic nexus operation to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * offline a device. It leaves a target device node attached.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * and obviously sata_drive_info attached as well, because
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * from the hardware point of view nothing has changed.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((tdip = sata_get_target_dip(dip, comp_port)) != NULL) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: unconfigure: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "failed to unconfigure "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The target node devi_state should be marked with
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVI_DEVICE_OFFLINE by ndi_devi_offline().
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This would be the indication for cfgadm that
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the AP node occupant state is 'unconfigured'.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This would indicate a failure on the part of cfgadm
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to detect correct state of the node prior to this
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * call - one cannot unconfigure non-existing device.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: unconfigure: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "attempt to unconfigure non-existing device "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The sata cfgadm pluging will invoke this operation only if
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * port was found in the disconnect state (failed state
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * is also treated as the disconnected state).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DEVCTL_AP_CONNECT would invoke
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_hba_inst->satahba_tran->
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_tran_hotplug_ops->sata_tran_port_activate().
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If successful and a device is found attached to the port,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the initialization sequence is executed to attach
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a device structure to a port structure. The device is not
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * set in configured state (system-wise) by this operation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The state of the port and a device would be set
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * appropriately.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note, that activating the port may generate link events,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * so is is important that following processing and the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * event processing does not interfere with each other!
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This operation may remove port failed state and will
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * try to make port active and in good standing.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We only care about host sata cport for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Just let HBA driver to activate port */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Port activation failure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: connect: "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "failed to activate SATA port %d",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Virgin port state - will be updated by the port re-probe. */
6ed1276fb5fe78fb1cce38682748a830ef8bd157pawelw * Probe the port to find its state and attached device.
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * Generate sysevent - EC_DR / ESC_DR_AP_STATE_CHANGE
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * without the hint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If there is a device attached to the port, emit
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a message.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * A port may be in an active or shutdown state.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If port is in a failed state, operation is aborted - one
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * has to use explicit connect or port activate request
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to try to get a port into non-failed mode.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If a port is in a shutdown state, arbitrarily invoke
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_tran_port_activate() prior to any other operation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Verify that port state is READY and there is a device
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * of a supported type attached to this port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If target node exists, a device was most likely offlined.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If target node does not exist, create a target node an
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * attempt to online it.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * NO PMult or devices beyond PMult are supported yet.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We only care about host controller's sata cport for now. */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Check the current state of the port */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Just let HBA driver to activate port */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Port activation failure - do not
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * change port state unless the state
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * returned by HBA indicates a port
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * failure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: configure: "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "failed to activate SATA port %d",
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * Generate sysevent - EC_DR / ESC_DR_AP_STATE_CHANGE
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * without the hint.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Virgin port state */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Always reprobe port, to get current device info.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * That's the transition from "inactive" port
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * to active one with device attached.
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw "SATA device detected at port %d",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This is where real configure starts.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Change following check for PMult support.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(sata_device.satadev_type & SATA_VALID_DEV_TYPE)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* No device to configure */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Here we may have a device in reset condition,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * but because we are just configuring it, there is
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * no need to process the reset other than just
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to clear device reset condition in the HBA driver.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Setting the flag SATA_EVNT_CLEAR_DEVICE_RESET will
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * cause a first command sent the HBA driver with the request
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to clear device reset condition.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdinfo = sata_get_device_info(sata_hba_inst, &sata_device);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (SATA_EVNT_DEVICE_RESET | SATA_EVNT_INPROC_DEVICE_RESET))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdinfo->satadrv_event_flags |= SATA_EVNT_CLEAR_DEVICE_RESET;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((tdip = sata_get_target_dip(dip, comp_port)) != NULL) {
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Target node exists. Verify, that it belongs
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * to existing, attached device and not to
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * a removed device.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "sata_hba_ioctl: configure: "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "onlining device at SATA port %d "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "SATA device at port %d cannot be "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "configured. "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "Application(s) accessing previously "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "attached device "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "have to release it before newly inserted "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "device can be made accessible.",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * No target node - need to create a new target node.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* configure failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: configure: "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "configuring SATA device at port %d "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Copy the return AP-state information to the user space */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ndi_dc_return_ap_state(&ap_state, dcp) != NDI_SUCCESS) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Generic devctl for hardware specific functionality
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Copy in user ioctl data first */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#endif /* _MULTI_DATAMODEL */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: DEVCTL_AP_CONTROL "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * To avoid BE/LE and 32/64 issues, a get_size always returns
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a 32-bit number.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (ioc.get_size != 0 && ioc.bufsiz != (sizeof (uint32_t))) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* validate address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Override address qualifier - handle cport only for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Is the port locked by event processing daemon ? */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (cportinfo->cport_event_flags & SATA_EVNT_LOCK_PORT_BUSY) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Cannot process ioctl request now. Come back later
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Block event processing for this port */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cportinfo->cport_event_flags |= SATA_APCTL_LOCK_PORT_BUSY;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * There is no protection here for configured
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Sanity check */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_tran missing required "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "function sata_tran_reset_dport"));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* handle cport only for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: reset port: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "failed cport %d pmport %d",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Since the port was reset, it should be probed and
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * attached device reinitialized. At this point the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * port state is unknown - it's state is HBA-specific.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Re-probe port to get its state.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * There is no protection here for configured
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Sanity check */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_tran missing required "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "function sata_tran_reset_dport"));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* handle only device attached to cports, for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* only handle cport for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: reset device: failed "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Device info structure remains
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * attached. Another device reset or
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * port disconnect/connect and re-probing is
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * needed to change it's state
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Since the device was reset, we expect reset event
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to be reported and processed.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * There is no protection here for configured
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * devices.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Sanity check */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_tran missing required "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "function sata_tran_reset_dport"));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Need to lock all ports, not just one.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If any port is locked by event processing, fail
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the whole operation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * One port is already locked, but for simplicity
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * lock it again.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (rv == 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * All cports successfully locked.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Reset main SATA controller only for now -
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * no PMult.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: reset controller "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "failed"));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Since ports were reset, they should be
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * re-probed and attached devices
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * reinitialized.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * At this point port states are unknown,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Re-probe ports to get their state -
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * cports only for now.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Unlock all ports
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This operation returns EFAULT if either reset
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * controller failed or a re-probing of any ports
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We return here, because common return is for
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a single cport operation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Sanity check */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Arbitrarily unconfigure attached device, if any.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Even if the unconfigure fails, proceed with the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * port deactivation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Handle only device attached to cports, for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Handle only device attached to cports,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If a target node exists, try to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * offline a device and remove target
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* target node exist */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "port deactivate: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "target node exists.",
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "sata_hba_ioctl:"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "port deactivate: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "failed to "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "unconfigure "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "device at port "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "%d before "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "deactivating "
926d91c0d8888f362a92507239936b4ca35fd152pawelw * Set DEVICE REMOVED
926d91c0d8888f362a92507239936b4ca35fd152pawelw * state in the target
926d91c0d8888f362a92507239936b4ca35fd152pawelw * node. It will
926d91c0d8888f362a92507239936b4ca35fd152pawelw * prevent access to
926d91c0d8888f362a92507239936b4ca35fd152pawelw * the device even when
926d91c0d8888f362a92507239936b4ca35fd152pawelw * a new device is
926d91c0d8888f362a92507239936b4ca35fd152pawelw * attached, until the
926d91c0d8888f362a92507239936b4ca35fd152pawelw * old target node is
926d91c0d8888f362a92507239936b4ca35fd152pawelw * released, removed and
926d91c0d8888f362a92507239936b4ca35fd152pawelw * recreated for a new
926d91c0d8888f362a92507239936b4ca35fd152pawelw * Instruct event
926d91c0d8888f362a92507239936b4ca35fd152pawelw * daemon to try the
926d91c0d8888f362a92507239936b4ca35fd152pawelw * target node cleanup
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * In any case,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * remove and release sata_drive_info
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * structure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * (cport attached device ony, for now)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note: PMult info requires different
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * handling. This comment is a placeholder for
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a code handling PMult, to be implemented
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * in phase 2.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* handle cport only for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Just let HBA driver to deactivate port */
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * Generate sysevent -
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * EC_DR / ESC_DR_AP_STATE_CHANGE
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * without the hint
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Port deactivation failure - do not
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * change port state unless the state
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * returned by HBA indicates a port failure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: port deactivate: "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "cannot deactivate SATA port %d",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Sanity check */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* handle cport only for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Just let HBA driver to activate port */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Port activation failure - do not
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * change port state unless the state
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * returned by HBA indicates a port failure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: port activate: "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "cannot activate SATA port %d",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Re-probe port to find its current state and
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * possibly attached device.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Port re-probing may change the cportinfo device
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * type if device is found attached.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If port probing failed, the device type would be
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * set to SATA_DTYPE_NONE.
6ed1276fb5fe78fb1cce38682748a830ef8bd157pawelw (void) sata_reprobe_port(sata_hba_inst, &sata_device,
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * Generate sysevent -
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * EC_DR / ESC_DR_AP_STATE_CHANGE
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * without the hint.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * That's the transition from "inactive" port
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * state or active port without a device
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * attached to the active port state with
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a device attached.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Sanity check */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * There is no protection here for a configured
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * device attached to this port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* only handle cport for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_ioctl: port selftest: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "failed cport %d pmport %d",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Since the port was reset, it should be probed and
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * attached device reinitialized. At this point the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * port state is unknown - it's state is HBA-specific.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Force port re-probing to get it into a known state.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * No such device.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If this is a request for a size, do not
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * return EINVAL for non-exisiting target,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * because cfgadm will indicate a meaningless
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * ioctl failure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If this is a real request for a path,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * indicate invalid argument.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf const char *ap_type;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* cport only, no port multiplier support */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } /* end of dev_type switch */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This operation should return to cfgadm the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * device model information string
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* only handle device connected to cport for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This operation should return to cfgadm the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * device firmware revision information string
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* only handle device connected to cport for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This operation should return to cfgadm the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * device serial number information string
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* only handle device connected to cport for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } /* End of DEVCTL_AP_CONTROL cmd switch */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If we got here, we got an IOCTL that SATA HBA Framework
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * does not recognize. Pass ioctl to HBA driver, in case
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * it could process it.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_tran_t *sata_tran = sata_hba_inst->satahba_tran;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "IOCTL 0x%2x not supported in SATA framework, "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (rval != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } /* End of main IOCTL switch */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cportinfo->cport_event_flags &= ~SATA_APCTL_LOCK_PORT_BUSY;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Create error retrieval sata packet
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * A sata packet is allocated and set-up to contain specified error retrieval
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * command and appropriate dma-able data buffer.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * No association with any scsi packet is made and no callback routine is
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * specified.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns a pointer to sata packet upon successfull packet creation.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns NULL, if packet cannot be created.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_get_error_retrieval_pkt(dev_info_t *dip, sata_device_t *sata_device,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (sata_hba_inst = sata_hba_list; sata_hba_inst != NULL;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo = sata_get_device_info(sata_hba_inst, sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata: error recovery request for non-attached device at "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* address is needed now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sata_device->satadev_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Placeholder only */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_atapi_err_ret_cmd_setup(spx, sdinfo) == SATA_SUCCESS)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Free error retrieval sata packet
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Free sata packet and any associated resources allocated previously by
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_get_error_retrieval_pkt().
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Void return.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sata_pkt_txlate_t *)sata_pkt->satapkt_framework_private;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* ****************** SCSA required entry points *********************** */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implementation of scsi tran_tgt_init.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_scsi_tgt_init() initializes scsi_device structure
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If successful, DDI_SUCCESS is returned.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DDI_FAILURE is returned if addressed device does not exist
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_scsi_tgt_init(dev_info_t *hba_dip, dev_info_t *tgt_dip,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_inst = (sata_hba_inst_t *)(hba_tran->tran_hba_private);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Validate scsi device address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_validate_scsi_address(sata_hba_inst, &sd->sd_address,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* sata_device now contains a valid sata address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdinfo = sata_get_device_info(sata_hba_inst, &sata_device);
8d483882aa3390058094b043f3d62187b5d1de03mlf * Check if we need to create a legacy devid (i.e cmdk style) for
8d483882aa3390058094b043f3d62187b5d1de03mlf * the target disks.
8d483882aa3390058094b043f3d62187b5d1de03mlf * HBA devinfo node will have the property "use-cmdk-devid-format"
8d483882aa3390058094b043f3d62187b5d1de03mlf * if we need to create cmdk-style devid for all the disk devices
8d483882aa3390058094b043f3d62187b5d1de03mlf * attached to this controller. This property may have been set
8d483882aa3390058094b043f3d62187b5d1de03mlf * from HBA driver's .conf file or by the HBA driver in its
8d483882aa3390058094b043f3d62187b5d1de03mlf * attach(9F) function.
8d483882aa3390058094b043f3d62187b5d1de03mlf /* register a legacy devid for this target node */
184cd04c26b064536977dfbb913a1240eaf6f708cth * 'Identify Device Data' does not always fit in standard SCSI
184cd04c26b064536977dfbb913a1240eaf6f708cth * INQUIRY data, so establish INQUIRY_* properties with full-form
184cd04c26b064536977dfbb913a1240eaf6f708cth * of information.
184cd04c26b064536977dfbb913a1240eaf6f708cth#else /* _LITTLE_ENDIAN */
184cd04c26b064536977dfbb913a1240eaf6f708cth#endif /* _LITTLE_ENDIAN */
184cd04c26b064536977dfbb913a1240eaf6f708cth /* split model into into vid/pid */
184cd04c26b064536977dfbb913a1240eaf6f708cth for (i = 0, pid = model; i < SATA_ID_MODEL_LEN; i++, pid++)
184cd04c26b064536977dfbb913a1240eaf6f708cth (void) scsi_hba_prop_update_inqstring(sd, INQUIRY_VENDOR_ID,
184cd04c26b064536977dfbb913a1240eaf6f708cth (void) scsi_hba_prop_update_inqstring(sd, INQUIRY_PRODUCT_ID,
184cd04c26b064536977dfbb913a1240eaf6f708cth (void) scsi_hba_prop_update_inqstring(sd, INQUIRY_REVISION_ID,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implementation of scsi tran_tgt_probe.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Probe target, by calling default scsi routine scsi_hba_probe()
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_scsi_tgt_probe(struct scsi_device *sd, int (*callback)(void))
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (sata_hba_inst_t *)(sd->sd_address.a_hba_tran->tran_hba_private);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Set property "pm-capable" on the target device node, so that
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the target driver will not try to fetch scsi cycle counters
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * before enabling device power-management.
184cd04c26b064536977dfbb913a1240eaf6f708cth "SATA device at port %d: "
184cd04c26b064536977dfbb913a1240eaf6f708cth "will not be power-managed ",
184cd04c26b064536977dfbb913a1240eaf6f708cth "failure updating pm-capable property"));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implementation of scsi tran_tgt_free.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Release all resources allocated for scsi_device
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_inst = (sata_hba_inst_t *)(hba_tran->tran_hba_private);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Validate scsi device address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_validate_scsi_address(sata_hba_inst, &sd->sd_address,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* sata_device now should contain a valid sata address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdinfo = sata_get_device_info(sata_hba_inst, &sata_device);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We did not allocate any resources in sata_scsi_tgt_init()
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * other than few properties.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Free them.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (ndi_prop_remove(DDI_DEV_T_NONE, tgt_dip, "pm-capable") !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_scsi_tgt_free: pm-capable "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "property could not be removed"));
8d483882aa3390058094b043f3d62187b5d1de03mlf * If devid was previously created but not freed up from
8d483882aa3390058094b043f3d62187b5d1de03mlf * sd(7D) driver (i.e during detach(9F)) then do it here.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implementation of scsi tran_init_pkt
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Upon successful return, scsi pkt buffer has DMA resources allocated.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * It seems that we should always allocate pkt, even if the address is
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * for non-existing device - just use some default for dma_attr.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The reason is that there is no way to communicate this to a caller here.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Subsequent call to sata_scsi_start may fail appropriately.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Simply returning NULL does not seem to discourage a target driver...
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns a pointer to initialized scsi_pkt, or NULL otherwise.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic struct scsi_pkt *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_scsi_init_pkt(struct scsi_address *ap, struct scsi_pkt *pkt,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf struct buf *bp, int cmdlen, int statuslen, int tgtlen, int flags,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We need to translate the address, even if it could be
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a bogus one, for a non-existing device
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_device.satadev_addr.qual = SCSI_TO_SATA_ADDR_QUAL(ap->a_target);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_device.satadev_addr.cport = SCSI_TO_SATA_CPORT(ap->a_target);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_device.satadev_addr.pmport = SCSI_TO_SATA_PMPORT(ap->a_target);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Have to allocate a brand new scsi packet.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We need to operate with auto request sense enabled.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Fill scsi packet structure */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * pkt_hba_private will point to sata pkt txlate structure
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Allocate sata_pkt */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Could not allocate sata pkt */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Set sata address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Packet was preallocated/initialized by previous call
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Pkt is available already: spx->txlt_scsi_pkt == pkt; */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We use an adjusted version of the dma_attr, to account
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * for device addressing limitations.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_adjust_dma_attr() will handle sdinfo == NULL which may
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * happen when a device is not yet configured.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* NULL sdinfo may be passsed to sata_adjust_dma_attr() */
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Allocate necessary DMA resources for the packet's data buffer
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * In case of read/write commands, DMA resource allocation here is
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * based on the premise that the transfer length specified in
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * the read/write scsi cdb will match exactly DMA resources -
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * returning correct packet residue is crucial.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((rval = sata_dma_buf_setup(spx, flags, callback, arg,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If a DMA allocation request fails with
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DDI_DMA_NOMAPPING, indicate the error by calling
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * bioerror(9F) with bp and an error code of EFAULT.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If a DMA allocation request fails with
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * DDI_DMA_TOOBIG, indicate the error by calling
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * bioerror(9F) with bp and an error code of EINVAL.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (rval) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Set number of bytes that are not yet accounted for */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implementation of scsi tran_start.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Translate scsi cmd into sata operation and return status.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Supported scsi commands:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_INQUIRY
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_TEST_UNIT_READY
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_START_STOP
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_READ_CAPACITY
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_REQUEST_SENSE
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw * SCMD_LOG_SENSE_G1
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw * SCMD_LOG_SELECT_G1
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_MODE_SENSE (specific pages)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_MODE_SENSE_G1 (specific pages)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_MODE_SELECT (specific pages)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_MODE_SELECT_G1 (specific pages)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_SYNCHRONIZE_CACHE
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_SYNCHRONIZE_CACHE_G1
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_READ
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_READ_G1
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_READ_G4
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_READ_G5
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_WRITE
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * SCMD_WRITE_BUFFER
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_WRITE_G1
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_WRITE_G4
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_WRITE_G5
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCMD_SEEK (noop)
489f952b4388bd1ea1feff97164a4416e0c621eals * SCMD_SDIAG
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * All other commands are rejected as unsupported.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * TRAN_ACCEPT if command was executed successfully or accepted by HBA driver
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * for execution. TRAN_ACCEPT may be returned also if device was removed but
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * a callback could be scheduled.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * TRAN_BADPKT if cmd was directed to invalid address.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * TRAN_FATAL_ERROR is command was rejected due to hardware error, including
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * some unspecified error. TRAN_FATAL_ERROR may be also returned if a device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * was removed and there was no callback specified in scsi pkt.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * TRAN_BUSY if command could not be executed becasue HBA driver or SATA
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * framework was busy performing some other operation(s).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_scsi_start(struct scsi_address *ap, struct scsi_pkt *pkt)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_pkt_txlate_t *spx = (sata_pkt_txlate_t *)pkt->pkt_ha_private;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spx->txlt_scsi_pkt == pkt && spx->txlt_sata_pkt != NULL);
4360436b3c604bc28d37be269ad152b4c38157c3pawelw SATA_CPORT_INFO(sata_hba_inst, cport)->cport_tgtnode_clean ==
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * The sd target driver is checking CMD_DEV_GONE pkt_reason
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * only in callback function (for normal requests) and
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * in the dump code path.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * So, if the callback is available, we need to do
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * the callback rather than returning TRAN_FATAL_ERROR here.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw /* scsi callback required */
4360436b3c604bc28d37be269ad152b4c38157c3pawelw /* Scheduling the callback failed */
4360436b3c604bc28d37be269ad152b4c38157c3pawelw /* No callback available */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* ATA Disk commands processing starts here */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Mapped to identify device */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SAT "SATA to ATA Translation" doc specifies translation
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to ATA CHECK POWER MODE.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Mapping depends on the command */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Always No Sense, since we force ARQ
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Other cases will be filed later */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* postponed until phase 2 of the development */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implementation of scsi tran_abort.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Abort specific pkt or all packets.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns 1 if one or more packets were aborted, returns 0 otherwise
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * May be called from an interrupt level.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_scsi_abort(struct scsi_address *ap, struct scsi_pkt *scsi_pkt)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_scsi_abort: %s at target: 0x%x\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf scsi_pkt == NULL ? "all packets" : "one pkt", ap->a_target);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Validate address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_validate_scsi_address(sata_hba_inst, ap, &sata_device) != 0)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Invalid address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_get_device_info(sata_hba_inst, &sata_device) == NULL) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* invalid address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Abort all packets.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Although we do not have specific packet, we still need
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * dummy packet structure to pass device address to HBA.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Allocate one, without sleeping. Fail if pkt cannot be
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * allocated.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_pkt = kmem_zalloc(sizeof (sata_pkt_t), KM_NOSLEEP);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "could not allocate sata_pkt"));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0); /* Bad scsi pkt */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* extract pointer to sata pkt */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_pkt = ((sata_pkt_txlate_t *)scsi_pkt->pkt_ha_private)->
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Send abort request to HBA */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf scsi_pkt == NULL ? SATA_ABORT_ALL_PACKETS : SATA_ABORT_PACKET) ==
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Success */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Else, something did not go right */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Failure */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Implementation of scsi tran_reset.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * RESET_ALL request is translated into port reset.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * RESET_TARGET requests is translated into a device reset,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * RESET_LUN request is accepted only for LUN 0 and translated into
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * device reset.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The target reset should cause all HBA active and queued packets to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * be terminated and returned with pkt reason SATA_PKT_RESET prior to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the return. HBA should report reset event for the device.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns 1 upon success, 0 upon failure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_scsi_reset: level %d target: 0x%x\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Validate address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf val = sata_validate_scsi_address(sata_hba_inst, ap, &sata_device);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Invalid address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_get_device_info(sata_hba_inst, &sata_device) == NULL) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* invalid address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* port reset - cport only */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (SATA_DIP(sata_hba_inst), &sata_device) == SATA_SUCCESS)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else if (val == 0 &&
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* reset device (device attached) */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (SATA_DIP(sata_hba_inst), &sata_device) == SATA_SUCCESS)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implementation of scsi tran_getcap (get transport/device capabilities).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Supported capabilities for SATA hard disks:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * auto-rqsense (always supported)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * tagged-qing (supported if HBA supports it)
37a077ef1920ee044b2887247b2a802e726d3368ls * untagged-qing (could be supported if disk supports it, but because
37a077ef1920ee044b2887247b2a802e726d3368ls * caching behavior allowing untagged queuing actually
37a077ef1920ee044b2887247b2a802e726d3368ls * results in reduced performance. sd tries to throttle
37a077ef1920ee044b2887247b2a802e726d3368ls * back to only 3 outstanding commands, which may
37a077ef1920ee044b2887247b2a802e726d3368ls * work for real SCSI disks, but with read ahead
37a077ef1920ee044b2887247b2a802e726d3368ls * caching, having more than 1 outstanding command
37a077ef1920ee044b2887247b2a802e726d3368ls * results in cache thrashing.)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sector_size
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * interconnect-type (INTERCONNECT_SATA)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Supported capabilities for ATAPI devices (CD/DVD):
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * auto-rqsense (always supported)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sector_size
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * interconnect-type (INTERCONNECT_SATA)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Request for other capabilities is rejected as unsupported.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns supported capability value, or -1 if capability is unsuppported or
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the address is invalid - no device.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_scsi_getcap(struct scsi_address *ap, char *cap, int whom)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_scsi_getcap: target: 0x%x, cap: %s\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We want to process the capabilities on per port granularity.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * So, we are specifically restricting ourselves to whom != 0
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to exclude the controller wide handling.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (-1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_validate_scsi_address(sata_hba_inst, ap, &sata_device) != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Invalid address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (-1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((sdinfo = sata_get_device_info(sata_hba_inst, &sata_device)) ==
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* invalid address */
4e54023805e14cf984b9f0041df73c16334a7a88ls return (-1);
37a077ef1920ee044b2887247b2a802e726d3368ls * untagged queuing cause a performance inversion because of
37a077ef1920ee044b2887247b2a802e726d3368ls * the way sd operates. Because of this reason we do not
37a077ef1920ee044b2887247b2a802e726d3368ls * use it when available.
4e54023805e14cf984b9f0041df73c16334a7a88ls if (sdinfo->satadrv_features_enabled & SATA_DEV_F_E_TAGGED_QING)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_adjust_dma_attr(sdinfo, SATA_DMA_ATTR(sata_hba_inst),
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We rely on the fact that dma_attr_maxxfer < 0x80000000 */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implementation of scsi tran_setcap
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Only SCSI_CAP_UNTAGGED_QING and SCSI_CAP_TAGGED_QING are changeable.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_scsi_setcap(struct scsi_address *ap, char *cap, int value, int whom)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_scsi_setcap: target: 0x%x, cap: %s\n", ap->a_target, cap);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We want to process the capabilities on per port granularity.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * So, we are specifically restricting ourselves to whom != 0
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to exclude the controller wide handling.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (-1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sata_validate_scsi_address(sata_hba_inst, ap, &sata_device) != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Invalid address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (-1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* invalid address */
4e54023805e14cf984b9f0041df73c16334a7a88ls return (-1);
4e54023805e14cf984b9f0041df73c16334a7a88ls } else if (value == 0) {
4e54023805e14cf984b9f0041df73c16334a7a88ls /* This can TCQ or NCQ */
4e54023805e14cf984b9f0041df73c16334a7a88ls } else if (value == 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implementations of scsi tran_destroy_pkt.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Free resources allocated by sata_scsi_init_pkt()
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_scsi_destroy_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
7a70ede882eacbae00c8d5209afb443e7755684cpawelw * Intermediate DMA buffer was allocated.
7a70ede882eacbae00c8d5209afb443e7755684cpawelw * Free allocated buffer and associated access handle.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Free DMA resources - cookies and handles
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implementation of scsi tran_dmafree.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Free DMA resources allocated by sata_scsi_init_pkt()
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_scsi_dmafree(struct scsi_address *ap, struct scsi_pkt *pkt)
8d483882aa3390058094b043f3d62187b5d1de03mlf * Intermediate DMA buffer was allocated.
8d483882aa3390058094b043f3d62187b5d1de03mlf * Free allocated buffer and associated access handle.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Free DMA resources - cookies and handles
8d483882aa3390058094b043f3d62187b5d1de03mlf /* ASSERT(spx->txlt_dma_cookie_list != NULL); */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Implementation of scsi tran_sync_pkt.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The assumption below is that pkt is unique - there is no need to check ap
7a70ede882eacbae00c8d5209afb443e7755684cpawelw * Synchronize DMA buffer and, if the intermediate buffer is used, copy data
7a70ede882eacbae00c8d5209afb443e7755684cpawelw * into/from the real buffer.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_scsi_sync_pkt(struct scsi_address *ap, struct scsi_pkt *pkt)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_pkt_txlate_t *spx = (sata_pkt_txlate_t *)pkt->pkt_ha_private;
7a70ede882eacbae00c8d5209afb443e7755684cpawelw /* Intermediate DMA buffer used */
7a70ede882eacbae00c8d5209afb443e7755684cpawelw /* Sync the buffer for device or for CPU */
7a70ede882eacbae00c8d5209afb443e7755684cpawelw /* Intermediate DMA buffer used for read */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf/* ******************* SATA - SCSI Translation functions **************** */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SCSI to SATA pkt and command translation and SATA to SCSI status/error
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * translation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Checks if a device exists and can be access and translates common
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * scsi_pkt data to sata_pkt data.
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * Returns TRAN_ACCEPT and scsi pkt_reason CMD_CMPLT if device exists and
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * sata_pkt was set-up.
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * Returns TRAN_ACCEPT and scsi pkt_reason CMD_DEV_GONE if device does not
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * exist and pkt_comp callback was scheduled.
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * Returns other TRAN_XXXXX values when error occured and command should be
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * rejected with the returned TRAN_XXXXX value.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This function should be called with port mutex held.
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* all other values to 0/FALSE */
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * Pkt_reason has to be set if the pkt_comp callback is invoked,
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * and that implies TRAN_ACCEPT return value. Any other returned value
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * indicates that the scsi packet was not accepted (the reason will not
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * be checked by the scsi traget driver).
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * To make debugging easier, we set pkt_reason to know value here.
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * It may be changed later when different completion reason is
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * determined.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Validate address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (sata_validate_scsi_address(spx->txlt_sata_hba_inst,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Invalid address or invalid device type */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* valid address but no device - it has disappeared ? */
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * The sd target driver is checking CMD_DEV_GONE pkt_reason
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * only in callback function (for normal requests) and
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * in the dump code path.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * So, if the callback is available, we need to do
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * the callback rather than returning TRAN_FATAL_ERROR here.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw /* scsi callback required */
4360436b3c604bc28d37be269ad152b4c38157c3pawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* all OK */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If device is in reset condition, reject the packet with
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * TRAN_BUSY, unless:
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * 1. system is panicking (dumping)
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * In such case only one thread is running and there is no way to
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * process reset.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * 2. cfgadm operation is is progress (internal APCTL lock is set)
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Some cfgadm operations involve drive commands, so reset condition
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * needs to be ignored for IOCTL operations.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw (SATA_EVNT_DEVICE_RESET | SATA_EVNT_INPROC_DEVICE_RESET)) != 0) {
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "sata_scsi_start: rejecting command because "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Fix the dev_type in the sata_pkt->satapkt_device. It was not set by
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_scsi_pkt_init() because pkt init had to work also with
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * non-existing devices.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Now we know that the packet was set-up for a real device, so its
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * type is known.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spx->txlt_sata_pkt->satapkt_device.satadev_type = sdinfo->satadrv_type;
c03acfcad7780db4ddf763511a82026680b3b2c1ls spx->txlt_sata_pkt->satapkt_cmd.satacmd_flags = sata_initial_cmd_flags;
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * At this point the generic translation routine determined that the
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * scsi packet should be accepted. Packet completion reason may be
5613bc2e005997fad3da93edffa0a790eda9d130pawelw * changed later when a different completion reason is determined.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((spx->txlt_scsi_pkt->pkt_flags & FLAG_NOINTR) != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Synchronous execution */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spx->txlt_sata_pkt->satapkt_op_mode = SATA_OPMODE_SYNCH |
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Asynchronous execution */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spx->txlt_sata_pkt->satapkt_op_mode = SATA_OPMODE_ASYNCH |
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Convert queuing information */
c03acfcad7780db4ddf763511a82026680b3b2c1ls spx->txlt_sata_pkt->satapkt_cmd.satacmd_flags.sata_queue_stag =
c03acfcad7780db4ddf763511a82026680b3b2c1ls spx->txlt_sata_pkt->satapkt_cmd.satacmd_flags.sata_queue_otag =
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Always limit pkt time */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spx->txlt_sata_pkt->satapkt_time = sata_default_pkt_time;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Pass on scsi_pkt time */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Translate ATA Identify Device data to SCSI Inquiry data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function may be called only for ATA devices.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function should not be called for ATAPI devices - they
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * respond directly to SCSI Inquiry command.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA Identify Device data has to be valid in sata_rive_info.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Buffer has to accomodate the inquiry length (36 bytes).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This function should be called with a port mutex held.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* Start with a nice clean slate */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Rely on the dev_type for setting paripheral qualifier.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Assume that DTYPE_RODIRECT applies to CD/DVD R/W devices.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * It could be that DTYPE_OPTICAL could also qualify in the future.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * ATAPI Inquiry may provide more data to the target driver.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_dtype = sdinfo->satadrv_type == SATA_DTYPE_ATADISK ?
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_qual = 0; /* Device type qualifier (obsolete in SCSI3? */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown inq->inq_trmiop = 0; /* Supports TERMINATE I/O PROC msg - NO */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_normaca = 0; /* setting NACA bit supported - NO */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_rdf = RDF_SCSI2; /* Response data format- SPC-3 */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_reladdr = 0; /* Supports relative addressing - NO */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_sync = 0; /* Supports synchronous data xfers - NO */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_linked = 0; /* Supports linked commands - NO */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Queuing support - controller has to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * support some sort of command queuing.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_cmdque = 1; /* Supports command queueing - YES */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_cmdque = 0; /* Supports command queueing - NO */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_sftre = 0; /* Supports Soft Reset option - NO ??? */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_wbus32 = 0; /* Supports 32 bit wide data xfers - NO */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf inq->inq_wbus16 = 0; /* Supports 16 bit wide data xfers - NO */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Swap text fields to match SCSI format */
c03acfcad7780db4ddf763511a82026680b3b2c1ls swab(sid->ai_fw, inq->inq_revision, 4); /* Revision level */
c03acfcad7780db4ddf763511a82026680b3b2c1ls swab(&sid->ai_fw[4], inq->inq_revision, 4); /* Rev. level */
184cd04c26b064536977dfbb913a1240eaf6f708cth#else /* _LITTLE_ENDIAN */
184cd04c26b064536977dfbb913a1240eaf6f708cth bcopy(sid->ai_model, inq->inq_pid, 16); /* Product ID */
c03acfcad7780db4ddf763511a82026680b3b2c1ls bcopy(sid->ai_fw, inq->inq_revision, 4); /* Revision level */
c03acfcad7780db4ddf763511a82026680b3b2c1ls bcopy(&sid->ai_fw[4], inq->inq_revision, 4); /* Rev. level */
184cd04c26b064536977dfbb913a1240eaf6f708cth#endif /* _LITTLE_ENDIAN */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Scsi response set up for invalid command (command not supported)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT and appropriate values in scsi_pkt fields.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_COMMAND_CODE;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n", scsipkt->pkt_reason);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Scsi response setup for
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * emulated non-data command that requires no action/return data
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT and appropriate values in scsi_pkt fields.
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spx->txlt_scsi_pkt->pkt_state = STATE_GOT_BUS | STATE_GOT_TARGET |
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if ((spx->txlt_scsi_pkt->pkt_flags & FLAG_NOINTR) == 0 &&
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA translate command: Inquiry / Identify Device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Use cached Identify Device data for now, rather than issuing actual
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Device Identify cmd request. If device is detached and re-attached,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * asynchromous event processing should fetch and refresh Identify Device
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Two VPD pages are supported now:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Vital Product Data page
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Unit Serial Number page
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT and appropriate values in scsi_pkt fields.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#define INQUIRY_SUP_VPD_PAGE 0 /* Supported VDP Pages Page COde */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#define INQUIRY_USN_PAGE 0x80 /* Unit Serial Number Page Code */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf#define INQUIRY_DEV_IDENTIFICATION_PAGE 0x83 /* Not needed yet */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf struct buf *bp = spx->txlt_sata_pkt->satapkt_cmd.satacmd_bp;
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Reject not supported request */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (scsipkt->pkt_cdbp[1] & CMDDT) { /* No support for this bit */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_CDB;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Valid Inquiry request */
8d483882aa3390058094b043f3d62187b5d1de03mlf * Because it is fully emulated command storing data
8d483882aa3390058094b043f3d62187b5d1de03mlf * programatically in the specified buffer, release
8d483882aa3390058094b043f3d62187b5d1de03mlf * preallocated DMA resources before storing data in the buffer,
8d483882aa3390058094b043f3d62187b5d1de03mlf * so no unwanted DMA sync would take place.
8d483882aa3390058094b043f3d62187b5d1de03mlf /* Standard Inquiry Data request */
c03acfcad7780db4ddf763511a82026680b3b2c1ls unsigned int bufsize;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Copy no more than requested */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sizeof (struct scsi_inquiry));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * peripheral_qualifier = 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We are dealing only with HD and will be
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * dealing with CD/DVD devices soon
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Request for suported Vital Product Data
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * pages - assuming only 2 page codes
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * supported
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Copy no more than requested */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Request for Unit Serial Number page
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (i = 0; i < 20; i++) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * 'i' contains string length.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Least significant character of the serial
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * number shall appear as the last byte,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * according to SBC-3 spec.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (j = i; j > 0; j--, p--) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *p = *(p - 20 + i);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf for (j = 20 - i; j > 0; j--) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *p++ = '\040';
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We may want to implement this page, when
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * identifiers are common for SATA devices
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * But not now.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw /*FALLTHROUGH*/
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Request for unsupported VPD page */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw /* Scheduling the callback failed */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA translate command: Request Sense.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Emulated command (ATA version for SATA hard disks)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Always NO SENSE, because any sense data should be reported by ARQ sense.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT and appropriate values in scsi_pkt fields.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf struct buf *bp = spx->txlt_sata_pkt->satapkt_cmd.satacmd_bp;
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
8d483882aa3390058094b043f3d62187b5d1de03mlf * Because it is fully emulated command storing data
8d483882aa3390058094b043f3d62187b5d1de03mlf * programatically in the specified buffer, release
8d483882aa3390058094b043f3d62187b5d1de03mlf * preallocated DMA resources before storing data in the buffer,
8d483882aa3390058094b043f3d62187b5d1de03mlf * so no unwanted DMA sync would take place.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sizeof (struct scsi_extended_sense));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sense.es_class = 7; /* Response code 0x70 - current err */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Copy no more than requested */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA translate command: Test Unit Ready
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * At the moment this is an emulated command (ATA version for SATA hard disks).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * May be translated into Check Power Mode command in the future
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT and appropriate values in scsi_pkt fields.
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* At this moment, emulate it rather than execute anything */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* PWR mode standby */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n", scsipkt->pkt_reason);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA translate command: Start Stop Unit
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Translation depends on a command:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Start Unit translated into Idle Immediate
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Stop Unit translated into Standby Immediate
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Unload Media / NOT SUPPORTED YET
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Load Media / NOT SUPPROTED YET
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Power condition bits are ignored, so is Immediate bit
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Requesting synchronous execution.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT or code returned by sata_hba_start() and
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * appropriate values in scsi_pkt fields.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_txlt_start_stop_unit: %d\n", scsipkt->pkt_scbp[4] & 1);
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Load/Unload Media - invalid request */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_CDB;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n", scsipkt->pkt_reason);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Start Unit */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Stop Unit */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(spx->txlt_sata_pkt->satapkt_op_mode & SATA_OPMODE_SYNCH)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Need to set-up a callback function */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spx->txlt_sata_pkt->satapkt_op_mode = SATA_OPMODE_SYNCH;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Transfer command to HBA */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Pkt not accepted for execution */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If execution is non-synchronous,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a callback function will handle potential errors, translate
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the response and will do a callback to a target driver.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If it was synchronous, check execution status using the same
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * framework callback.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "synchronous execution status %x\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA translate command: Read Capacity.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Emulated command for SATA disks.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Capacity is retrieved from cached Idenifty Device data.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Identify Device data shows effective disk capacity, not the native
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * capacity, which may be limitted by Set Max Address command.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This is ATA version for SATA hard disks.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT and appropriate values in scsi_pkt fields.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf struct buf *bp = spx->txlt_sata_pkt->satapkt_cmd.satacmd_bp;
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
8d483882aa3390058094b043f3d62187b5d1de03mlf * Because it is fully emulated command storing data
8d483882aa3390058094b043f3d62187b5d1de03mlf * programatically in the specified buffer, release
8d483882aa3390058094b043f3d62187b5d1de03mlf * preallocated DMA resources before storing data in the buffer,
8d483882aa3390058094b043f3d62187b5d1de03mlf * so no unwanted DMA sync would take place.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Last logical block address */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Need to swap endians to match scsi format */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* block size - always 512 bytes, for now */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf SATADBG1(SATA_DBG_SCSI_IF, spx->txlt_sata_hba_inst, "%d\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If a callback was requested, do it now.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n", scsipkt->pkt_reason);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA translate command: Mode Sense.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Translated into appropriate SATA command or emulated.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Saved Values Page Control (03) are not supported.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * NOTE: only caching mode sense page is currently implemented.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT and appropriate values in scsi_pkt fields.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf struct buf *bp = spx->txlt_sata_pkt->satapkt_cmd.satacmd_bp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_txlt_mode_sense, pc %x page code 0x%02x\n",
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
8d483882aa3390058094b043f3d62187b5d1de03mlf * Because it is fully emulated command storing data
8d483882aa3390058094b043f3d62187b5d1de03mlf * programatically in the specified buffer, release
8d483882aa3390058094b043f3d62187b5d1de03mlf * preallocated DMA resources before storing data in the buffer,
8d483882aa3390058094b043f3d62187b5d1de03mlf * so no unwanted DMA sync would take place.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Build mode parameter header */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (spx->txlt_scsi_pkt->pkt_cdbp[0] == SCMD_MODE_SENSE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 4-byte mode parameter header */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 8-byte mode parameter header */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Build block descriptor only if not disabled (DBD) */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Block descriptor - direct-access device format */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* build regular block descriptor */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* ATAPI */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Long LBA Accepted */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* build long lba block descriptor */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* ATAPI */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Add requested pages.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Page 3 and 4 are obsolete and we are not supporting them.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We deal now with:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * caching (read/write cache control).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We should eventually deal with following mode pages:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * error recovery (0x01),
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * power condition (0x1a),
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * exception control page (enables SMART) (0x1c),
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * enclosure management (ses),
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * protocol-specific port mode (port control).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* DAD_MODE_ERR_RECOV */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* R/W recovery */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* DAD_MODE_CACHE */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls /* Reject not supported request for saved parameters */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* caching */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* exception cntrl */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* DAD_MODE_POWER_COND */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* power condition */
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls /* acoustic management */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* all pages */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Invalid request */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_CDB;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* fix total mode data length */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (spx->txlt_scsi_pkt->pkt_cdbp[0] == SCMD_MODE_SENSE) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 4-byte mode parameter header */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Check allocation length */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We do not check for possible parameters truncation
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * (alc_len < len) assuming that the target driver works
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * correctly. Just avoiding overrun.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Copy no more than requested and possible, buffer-wise.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf scsipkt->pkt_resid = alc_len > count ? alc_len - count : 0;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n", scsipkt->pkt_reason);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA translate command: Mode Select.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Translated into appropriate SATA command or emulated.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Saving parameters is not supported.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Changing device capacity is not supported (although theoretically
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * possible by executing SET FEATURES/SET MAX ADDRESS)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Assumption is that the target driver is working correctly.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * More than one SATA command may be executed to perform operations specified
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * by mode select pages. The first error terminates further execution.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Operations performed successully are not backed-up in such case.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * NOTE: only caching mode select page is implemented.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Caching setup is remembered so it could be re-stored in case of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * an unexpected device reset.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT and appropriate values in scsi_pkt fields.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf struct buf *bp = spx->txlt_sata_pkt->satapkt_cmd.satacmd_bp;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_txlt_mode_select, pc %x page code 0x%02x\n",
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Reject not supported request */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls if (! (scsipkt->pkt_cdbp[1] & 0x10)) { /* No support for PF bit = 0 */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_CDB;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *scsipkt->pkt_scbp = STATUS_GOOD; /* Presumed outcome */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (bp != NULL && bp->b_un.b_addr && bp->b_bcount && pllen != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Check the header to skip the block descriptor(s) - we
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * do not support setting device capacity.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Existing macros do not recognize long LBA dscriptor,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * hence manual calculation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 6-bytes CMD, 4 bytes header */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 10-bytes CMD, 8 bytes header */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We may be executing SATA command and want to execute it
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * in SYNCH mode, regardless of scsi_pkt setting.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Save scsi_pkt setting and indicate SYNCH mode
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spx->txlt_sata_pkt->satapkt_op_mode = SATA_OPMODE_SYNCH;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * len is now the offset to a first mode select page
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Process all pages
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf while (pllen > 0) {
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls /* No support for SP (saving) */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * The pagelen value indicates the number of
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * parameter bytes already processed.
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * The rval is the return value from
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * sata_tran_start().
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * The stat indicates the overall status of
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * the operation(s).
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * Page processing did not succeed -
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * all error info is already set-up,
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * just return
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * The pagelen value indicates the number of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * parameter bytes already processed.
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * The rval is the return value from
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_tran_start().
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The stat indicates the overall status of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the operation(s).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Page processing did not succeed -
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * all error info is already set-up,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * just return
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * The pagelen value indicates the number of
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * parameter bytes already processed.
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * The rval is the return value from
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * sata_tran_start().
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * The stat indicates the overall status of
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * the operation(s).
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * Page processing did not succeed -
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * all error info is already set-up,
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * just return
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If device parameters were modified, fetch and store the new
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Identify Device data. Since port mutex could have been released
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * for accessing HBA driver, we need to re-check device existence.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (dmod != 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf rv = sata_fetch_device_identify_data(spx->txlt_sata_hba_inst,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Since port mutex could have been released when
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * accessing HBA driver, we need to re-check that the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * framework still holds the device info structure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Device still has info structure in the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata framework. Copy newly fetched info
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (rv == 0) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Could not fetch new data - invalidate
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_drive_info. That makes device
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * unusable.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This changes the overall mode select completion
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * reason to a failed one !!!!!
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Restore the scsi pkt flags */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n", scsipkt->pkt_reason);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Translate command: Log Sense
c03acfcad7780db4ddf763511a82026680b3b2c1ls struct buf *bp = spx->txlt_sata_pkt->satapkt_cmd.satacmd_bp;
c03acfcad7780db4ddf763511a82026680b3b2c1ls "sata_txlt_log_sense, pc 0x%x, page code 0x%x\n",
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
37a077ef1920ee044b2887247b2a802e726d3368ls /* Reject not supported request for all but cumulative values */
c03acfcad7780db4ddf763511a82026680b3b2c1ls switch (pc) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_CDB;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_CDB;
8d483882aa3390058094b043f3d62187b5d1de03mlf * Because log sense uses local buffers for data retrieval from
8d483882aa3390058094b043f3d62187b5d1de03mlf * the devices and sets the data programatically in the
8d483882aa3390058094b043f3d62187b5d1de03mlf * original specified buffer, release preallocated DMA
8d483882aa3390058094b043f3d62187b5d1de03mlf * resources before storing data in the original buffer,
8d483882aa3390058094b043f3d62187b5d1de03mlf * so no unwanted DMA sync would take place.
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* Build log parameter header */
c03acfcad7780db4ddf763511a82026680b3b2c1ls * Add requested pages.
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* This page doesn't include a page header */
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* Invalid request */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_CDB;
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* set parameter log sense data length */
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* Check allocation length */
c03acfcad7780db4ddf763511a82026680b3b2c1ls * We do not check for possible parameters truncation
c03acfcad7780db4ddf763511a82026680b3b2c1ls * (alc_len < len) assuming that the target driver works
c03acfcad7780db4ddf763511a82026680b3b2c1ls * correctly. Just avoiding overrun.
c03acfcad7780db4ddf763511a82026680b3b2c1ls * Copy no more than requested and possible, buffer-wise.
c03acfcad7780db4ddf763511a82026680b3b2c1ls scsipkt->pkt_resid = alc_len > count ? alc_len - count : 0;
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* scsi callback required */
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Translate command: Log Select
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Not implemented at this time - returns invalid command response.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Translate command: Read (various types).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Translated into appropriate type of ATA READ command
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * for SATA hard disks.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Both the device capabilities and requested operation mode are
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * considered.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Following scsi cdb fields are ignored:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * rdprotect, dpo, fua, fua_nv, group_number.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If SATA_ENABLE_QUEUING flag is set (in the global SATA HBA framework
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * enable variable sata_func_enable), the capability of the controller and
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * capability of a device are checked and if both support queueing, read
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * request will be translated to READ_DMA_QUEUEING or READ_DMA_QUEUEING_EXT
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * command rather than plain READ_XXX command.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If SATA_ENABLE_NCQ flag is set in addition to SATA_ENABLE_QUEUING flag and
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * both the controller and device suport such functionality, the read
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * request will be translated to READ_FPDMA_QUEUED command.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT or code returned by sata_hba_start() and
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * appropriate values in scsi_pkt fields.
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Extract LBA and sector count from scsi CDB.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 6-byte scsi read cmd : 0x08 */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* sec_count 0 will be interpreted as 256 by a device */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 10-bytes scsi read command : 0x28 */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 12-bytes scsi read command : 0xA8 */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 16-bytes scsi read command : 0x88 */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Unsupported command */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Check if specified address exceeds device capacity
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA out of range */
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * For zero-length transfer, emulate good completion of the command
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * (reasons for rejecting the command were already checked).
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * No DMA resources were allocated.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Build cmd block depending on the device capability and
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * requested operation mode.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Do not bother with non-dma mode - we are working only with
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * devices supporting DMA.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sdinfo->satadrv_features_support & SATA_DEV_F_LBA48) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else if (sdinfo->satadrv_features_support & SATA_DEV_F_LBA28) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf scmd->satacmd_device_reg = SATA_ADH_LBA | ((lba >> 24) & 0xf);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Check if queueing commands should be used and switch
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to appropriate command if possible
489f952b4388bd1ea1feff97164a4416e0c621eals /* Queuing supported by controller and device? */
489f952b4388bd1ea1feff97164a4416e0c621eals /* NCQ supported - use FPDMA READ */
489f952b4388bd1ea1feff97164a4416e0c621eals /* Legacy queueing */
489f952b4388bd1ea1feff97164a4416e0c621eals } else /* Queuing not supported */
489f952b4388bd1ea1feff97164a4416e0c621eals * If queuing, the sector count goes in the features register
489f952b4388bd1ea1feff97164a4416e0c621eals * and the secount count will contain the tag.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_txlt_read cmd 0x%2x, lba %llx, sec count %x\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(spx->txlt_sata_pkt->satapkt_op_mode & SATA_OPMODE_SYNCH)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Need callback function */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spx->txlt_sata_pkt->satapkt_comp = sata_txlt_rw_completion;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Transfer command to HBA */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Pkt not accepted for execution */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If execution is non-synchronous,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a callback function will handle potential errors, translate
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the response and will do a callback to a target driver.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If it was synchronous, check execution status using the same
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * framework callback.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "synchronous execution status %x\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA translate command: Write (various types)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Translated into appropriate type of ATA WRITE command
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * for SATA hard disks.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Both the device capabilities and requested operation mode are
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * considered.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Following scsi cdb fields are ignored:
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * rwprotect, dpo, fua, fua_nv, group_number.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT or code returned by sata_hba_start() and
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * appropriate values in scsi_pkt fields.
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
c03acfcad7780db4ddf763511a82026680b3b2c1ls scmd->satacmd_flags.sata_data_direction = SATA_DIR_WRITE;
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Extract LBA and sector count from scsi CDB
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 6-byte scsi read cmd : 0x0A */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* sec_count 0 will be interpreted as 256 by a device */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 10-bytes scsi write command : 0x2A */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 12-bytes scsi read command : 0xAA */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* 16-bytes scsi write command : 0x8A */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Unsupported command */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Check if specified address and length exceeds device capacity
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* LBA out of range */
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * For zero-length transfer, emulate good completion of the command
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * (reasons for rejecting the command were already checked).
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * No DMA resources were allocated.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Build cmd block depending on the device capability and
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * requested operation mode.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Do not bother with non-dma mode- we are working only with
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * devices supporting DMA.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sdinfo->satadrv_features_support & SATA_DEV_F_LBA48) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else if (sdinfo->satadrv_features_support & SATA_DEV_F_LBA28) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf scmd->satacmd_device_reg = SATA_ADH_LBA | ((lba >> 24) & 0xf);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Check if queueing commands should be used and switch
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * to appropriate command if possible
489f952b4388bd1ea1feff97164a4416e0c621eals /* Queuing supported by controller and device? */
489f952b4388bd1ea1feff97164a4416e0c621eals /* NCQ supported - use FPDMA WRITE */
489f952b4388bd1ea1feff97164a4416e0c621eals /* Legacy queueing */
489f952b4388bd1ea1feff97164a4416e0c621eals } else /* Queuing not supported */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_txlt_write cmd 0x%2x, lba %llx, sec count %x\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (!(spx->txlt_sata_pkt->satapkt_op_mode & SATA_OPMODE_SYNCH)) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Need callback function */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf spx->txlt_sata_pkt->satapkt_comp = sata_txlt_rw_completion;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Transfer command to HBA */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Pkt not accepted for execution */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If execution is non-synchronous,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a callback function will handle potential errors, translate
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the response and will do a callback to a target driver.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If it was synchronous, check execution status using the same
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * framework callback.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "synchronous execution status %x\n",
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * Implements SCSI SBC WRITE BUFFER command download microcode option
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls struct buf *bp = spx->txlt_sata_pkt->satapkt_cmd.satacmd_bp;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls synch = (spx->txlt_sata_pkt->satapkt_op_mode & SATA_OPMODE_SYNCH) != 0;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls if ((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) {
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls scmd->satacmd_flags.sata_data_direction = SATA_DIR_WRITE;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * The SCSI to ATA translation specification only calls
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * for WB_DOWNLOAD_MICROCODE_AND_SAVE_MODE.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * WB_DOWNLOAD_MICROC_AND_REVERT_MODE is implemented, but
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * ATA 8 (draft) got rid of download microcode for temp
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * and it is even optional for ATA 7, so it may be aborted.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * WB_DOWNLOAD_MICROCODE_WITH_OFFSET is not implemented as
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * it is not specified and the buffer offset for SCSI is a 16-bit
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * value in bytes, but for ATA it is a 16-bit offset in 512 byte
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * sectors. Thus the offset really doesn't buy us anything.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * If and when ATA 8 is stabilized and the SCSI to ATA specification
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * is revised, this can be revisisted.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* Reject not supported request */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls switch (mode) {
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls scmd->satacmd_lba_low_lsb = ((uint16_t)sector_count) >> 8;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* Transfer command to HBA */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* Pkt not accepted for execution */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * If execution is non-synchronous,
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * a callback function will handle potential errors, translate
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * the response and will do a callback to a target driver.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * If it was synchronous, check execution status using the same
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * framework callback.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* Calling pre-set completion routine */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_CDB;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* scsi callback required */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* Scheduling the callback failed */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * Retry identify device when command returns SATA_INCOMPLETE_DATA
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * after doing a firmware download.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66lsstatic void
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls (sata_pkt_txlate_t *)sata_pkt->satapkt_framework_private;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls sata_hba_inst_t *sata_hba_inst = spx->txlt_sata_hba_inst;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls sata_device_t sata_device = spx->txlt_sata_pkt->satapkt_device;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * Before returning good status, probe device.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * Device probing will get IDENTIFY DEVICE data, if possible.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * The assumption is that the new microcode is applied by the
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * device. It is a caller responsibility to verify this.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls retry_cnt < DOWNLOAD_WAIT_TIME_SECS / DOWNLOAD_WAIT_INTERVAL_SECS;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* retry */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls } else /* failed - no reason to retry */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * Something went wrong, device probing failed.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls "Cannot probe device after downloading microcode\n"));
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* Reset device to force retrying the probe. */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * Translate completion status of download microcode command.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * pkt completion_reason is checked to determine the completion status.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * Do scsi callback if necessary (FLAG_NOINTR == 0)
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * Note: this function may be called also for synchronously executed
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * command.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * This function may be used only if scsi_pkt is non-NULL.
a022fe3e0bc959fae460b8b5b818cd1265bf4c66lsstatic void
a022fe3e0bc959fae460b8b5b818cd1265bf4c66lssata_txlt_download_mcode_cmd_completion(sata_pkt_t *sata_pkt)
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls (sata_pkt_txlate_t *)sata_pkt->satapkt_framework_private;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls sata_hba_inst_t *sata_hba_inst = spx->txlt_sata_hba_inst;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls sata_device_t sata_device = spx->txlt_sata_pkt->satapkt_device;
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* retry */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* Something went wrong, microcode download command failed */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls * We have no device data. Assume no data transfered.
184cd04c26b064536977dfbb913a1240eaf6f708cth * determine dev error reason from error
184cd04c26b064536977dfbb913a1240eaf6f708cth * reg content
184cd04c26b064536977dfbb913a1240eaf6f708cth /* No extended sense key - no info available */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* scsipkt->pkt_reason = CMD_TIMEOUT; */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* No extended sense key ? */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* No extended sense key ? */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* pkt aborted by an explicit reset from a host */
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls "sata_txlt_nodata_cmd_completion: "
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls "invalid packet completion reason %d",
a022fe3e0bc959fae460b8b5b818cd1265bf4c66ls /* scsi callback required */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Translate command: Synchronize Cache.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Translates into Flush Cache command for SATA hard disks.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns TRAN_ACCEPT or code returned by sata_hba_start() and
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * appropriate values in scsi_pkt fields.
5613bc2e005997fad3da93edffa0a790eda9d130pawelw if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (!(spx->txlt_sata_pkt->satapkt_op_mode & SATA_OPMODE_SYNCH)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Need to set-up a callback function */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Transfer command to HBA */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Pkt not accepted for execution */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If execution non-synchronous, it had to be completed
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * a callback function will handle potential errors, translate
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the response and will do a callback to a target driver.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If it was synchronous, check status, using the same
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * framework callback.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "synchronous execution status %x\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Send pkt to SATA HBA driver
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This function may be called only if the operation is requested by scsi_pkt,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * i.e. scsi_pkt is not NULL.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This function has to be called with cport mutex held. It does release
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the mutex when it calls HBA driver sata_tran_start function and
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * re-acquires it afterwards.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If return value is 0, pkt was accepted, -1 otherwise
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * rval is set to appropriate sata_scsi_start return value.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note 1:If HBA driver returns value other than TRAN_ACCEPT, it should not
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * have called the sata_pkt callback function for this packet.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The scsi callback has to be performed by the caller of this routine.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note 2: No port multiplier support for now.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_hba_inst_t *sata_hba_inst = spx->txlt_sata_hba_inst;
415e5120fdbacf132d1845300d92a6cd74eed2fayt ASSERT(mutex_owned(&SATA_CPORT_MUTEX(sata_hba_inst, cport)));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Clear device reset state? */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (sdinfo->satadrv_event_flags & SATA_EVNT_CLEAR_DEVICE_RESET) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sdinfo->satadrv_event_flags &= ~SATA_EVNT_CLEAR_DEVICE_RESET;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf cmd_flags = spx->txlt_sata_pkt->satapkt_cmd.satacmd_flags;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf stat = (*SATA_START_FUNC(sata_hba_inst))(SATA_DIP(sata_hba_inst),
415e5120fdbacf132d1845300d92a6cd74eed2fayt sdinfo = sata_get_device_info(sata_hba_inst, sata_device);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If sata pkt was accepted and executed in asynchronous mode, i.e.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * with the sata callback, the sata_pkt could be already destroyed
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * by the time we check ther return status from the hba_start()
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * function, because sata_scsi_destroy_pkt() could have been already
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * called (perhaps in the interrupt context). So, in such case, there
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * should be no references to it. In other cases, sata_pkt still
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf switch (stat) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * pkt accepted for execution.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If it was executed synchronously, it is already completed
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * and pkt completion_reason indicates completion status.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Controller detected queue full condition.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Communication/link with device or general port error
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * detected before pkt execution begun.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (spx->txlt_sata_pkt->satapkt_device.satadev_addr.qual ==
6ed1276fb5fe78fb1cce38682748a830ef8bd157pawelw spx->txlt_sata_pkt->satapkt_device.satadev_addr.qual ==
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "SATA port %d error",
4360436b3c604bc28d37be269ad152b4c38157c3pawelw "SATA port %d pmport %d error\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Update the port/device structure.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * sata_pkt should be still valid. Since port error is
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * returned, sata_device content should reflect port
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * state - it means, that sata address have been changed,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * because original packet's sata address refered to a device
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * attached to some port.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Command rejected by HBA as unsupported. It was HBA driver
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * that rejected the command, command was not sent to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * an attached device.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sat_hba_start: cmd 0x%2x rejected "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Command rejected by HBA because other operation prevents
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * accepting the packet, or device is in RESET condition.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_start: cmd 0x%2x rejected "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "because of device reset condition\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_start: cmd 0x%2x rejected "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "with SATA_TRAN_BUSY status\n",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Unrecognized HBA response */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_hba_start: unrecognized HBA response "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If we got here, the packet was rejected.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Check if we need to remember reset state clearing request
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Check if device is still configured - it may have
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * disapeared from the configuration
6ed1276fb5fe78fb1cce38682748a830ef8bd157pawelw sdinfo = sata_get_device_info(sata_hba_inst, sata_device);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Restore the flag that requests clearing of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the device reset state,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * so the next sata packet may carry it to HBA.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (-1);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Scsi response setup for invalid LBA
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns TRAN_ACCEPT and appropriate values in scsi_pkt fields.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n", scsipkt->pkt_reason);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
7a1efdfee8cbdecea34d3d866bbfb46e39b06e0apawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Analyze device status and error registers and translate them into
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * appropriate scsi sense codes.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * NOTE: non-packet commands only for now
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf uint8_t err_reg = spx->txlt_sata_pkt->satapkt_cmd.satacmd_error_reg;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf ASSERT(spx->txlt_sata_pkt->satapkt_cmd.satacmd_status_reg &
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Information bytes (LBA) need to be set by a caller */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* ADD HERE: MC error bit handling for ATAPI CD/DVD */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Extract error LBA from sata_pkt.satapkt_cmd register fields
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_extract_error_lba(sata_pkt_txlate_t *spx, uint64_t *lba)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf sata_cmd_t *sata_cmd = &spx->txlt_sata_pkt->satapkt_cmd;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf } else if (sata_cmd->satacmd_addr_type == ATA_ADDR_LBA28) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This is fixed sense format - if LBA exceeds the info field size,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * no valid info will be returned (valid bit in extended sense will
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * be set to 0).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic struct scsi_extended_sense *
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Fill ARQ sense data */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf arqs->sts_rqpkt_state = STATE_GOT_BUS | STATE_GOT_TARGET |
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Emulated SATA Read/Write command completion for zero-length requests.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * This request always succedes, so in synchronous mode it always returns
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * TRAN_ACCEPT, and in non-synchronous mode it may return TRAN_BUSY if the
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * callback cannot be scheduled.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw scsipkt->pkt_state = STATE_GOT_BUS | STATE_GOT_TARGET |
4360436b3c604bc28d37be269ad152b4c38157c3pawelw if (!(spx->txlt_sata_pkt->satapkt_op_mode & SATA_OPMODE_SYNCH)) {
4360436b3c604bc28d37be269ad152b4c38157c3pawelw /* scsi callback required - have to schedule it */
4360436b3c604bc28d37be269ad152b4c38157c3pawelw /* Scheduling the callback failed */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Translate completion status of SATA read/write commands into scsi response.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * pkt completion_reason is checked to determine the completion status.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Do scsi callback if necessary.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note: this function may be called also for synchronously executed
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * commands.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This function may be used only if scsi_pkt is non-NULL.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (sata_pkt_txlate_t *)sata_pkt->satapkt_framework_private;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Normal completion */
7a70ede882eacbae00c8d5209afb443e7755684cpawelw /* Temporary buffer was used */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Something went wrong - analyze return
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SATA_PKT_DEV_ERROR is the only case where we may be able to
c03acfcad7780db4ddf763511a82026680b3b2c1ls * extract from device registers the failing LBA.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We have problem reporting this cmd LBA
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * in fixed sense data format, because of
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the size of the scsi LBA fields.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Invalid extended sense info */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* We may want to handle DEV GONE state as well */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We have no device data. Assume no data transfered.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * determine dev error reason from error
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * reg content
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Unrecovered read error */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Write error */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Internal error */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_txlt_rw_completion :"
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "internal error - invalid "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "command 0x%2x",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* No extended sense key - no info available */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsipkt->pkt_reason = CMD_TIMEOUT; */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* No extended sense key ? */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* No extended sense key ? */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_txlt_rw_completion: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "invalid packet completion reason"));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n", scsipkt->pkt_reason);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Translate completion status of non-data commands (i.e. commands returning
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * no data).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * pkt completion_reason is checked to determine the completion status.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Do scsi callback if necessary (FLAG_NOINTR == 0)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note: this function may be called also for synchronously executed
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * commands.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This function may be used only if scsi_pkt is non-NULL.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf (sata_pkt_txlate_t *)sata_pkt->satapkt_framework_private;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Normal completion */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Something went wrong */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We have no device data. Assume no data transfered.
184cd04c26b064536977dfbb913a1240eaf6f708cth * determine dev error reason from error
184cd04c26b064536977dfbb913a1240eaf6f708cth * reg content
184cd04c26b064536977dfbb913a1240eaf6f708cth /* No extended sense key - no info available */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsipkt->pkt_reason = CMD_TIMEOUT; */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* No extended sense key ? */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* No extended sense key ? */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* pkt aborted by an explicit reset from a host */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "sata_txlt_nodata_cmd_completion: "
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "invalid packet completion reason %d",
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf "Scsi_pkt completion reason %x\n", scsipkt->pkt_reason);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* scsi callback required */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Build Mode sense R/W recovery page
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * NOT IMPLEMENTED
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_build_msense_page_1(sata_drive_info_t *sdinfo, int pcntrl, uint8_t *buf)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Build Mode sense caching page - scsi-3 implementation.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Page length distinguishes previous format from scsi-3 format.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * buf must have space for 0x12 bytes.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Only DRA (disable read ahead ) and WCE (write cache enable) are changeable.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_build_msense_page_8(sata_drive_info_t *sdinfo, int pcntrl, uint8_t *buf)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf struct mode_cache_scsi3 *page = (struct mode_cache_scsi3 *)buf;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Most of the fields are set to 0, being not supported and/or disabled
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls /* Saved paramters not supported */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * For now treat current and default parameters as same
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * That may have to change, if target driver will complain
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf page->mode_page.length = PAGELENGTH_DAD_MODE_CACHE_SCSI3;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Changeable parameters */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf page->mode_page.length = PAGELENGTH_DAD_MODE_CACHE_SCSI3;
184cd04c26b064536977dfbb913a1240eaf6f708cth sizeof (struct mode_page));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Build Mode sense exception cntrl page
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_build_msense_page_1c(sata_drive_info_t *sdinfo, int pcntrl, uint8_t *buf)
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls struct mode_info_excpt_page *page = (struct mode_info_excpt_page *)buf;
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * Most of the fields are set to 0, being not supported and/or disabled
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls /* Indicate that this is page is saveable */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * We will return the same data for default, current and saved page.
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * The only changeable bit is dexcpt and that bit is required
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * by the ATA specification to be preserved across power cycles.
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls page->dexcpt = !(sata_id->ai_features85 & SATA_SMART_SUPPORTED);
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls return (PAGELENGTH_INFO_EXCPT + sizeof (struct mode_info_excpt_page));
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960lssata_build_msense_page_30(sata_drive_info_t *sdinfo, int pcntrl, uint8_t *buf)
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * Most of the fields are set to 0, being not supported and/or disabled
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls switch (pcntrl) {
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls /* default paramters not supported */
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls return (0);
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls /* Saved and current are supported and are identical */
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls /* Word 83 indicates if feature is supported */
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls /* If feature is not supported */
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls /* Word 94 inidicates the value */
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls /* Word 83 indicates if the feature is supported */
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls sizeof (struct mode_page));
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Build Mode sense power condition page
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * NOT IMPLEMENTED.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_build_msense_page_1a(sata_drive_info_t *sdinfo, int pcntrl, uint8_t *buf)
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf return (0);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Process mode select caching page 8 (scsi3 format only).
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Read Ahead (same as read cache) and Write Cache may be turned on and off
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * if these features are supported by the device. If these features are not
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * supported, quietly ignore them.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This function fails only if the SET FEATURE command sent to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * the device fails. The page format is not varified, assuming that the
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * target driver operates correctly - if parameters length is too short,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * we just drop the page.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Two command may be sent if both Read Cache/Read Ahead and Write Cache
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * setting have to be changed.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * SET FEATURE command is executed synchronously, i.e. we wait here until
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * it is completed, regardless of the scsi pkt directives.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Note: Mode Select Caching page RCD and DRA bits are tied together, i.e.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * changing DRA will change RCD.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * More than one SATA command may be executed to perform operations specified
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * by mode select pages. The first error terminates further execution.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Operations performed successully are not backed-up in such case.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Return SATA_SUCCESS if operation succeeded, SATA_FAILURE otherwise.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * If operation resulted in changing device setup, dmod flag should be set to
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * one (1). If parameters were not changed, dmod flag should be set to 0.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Upon return, if operation required sending command to the device, the rval
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * should be set to the value returned by sata_hba_start. If operation
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * did not require device access, rval should be set to TRAN_ACCEPT.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * The pagelen should be set to the length of the page.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * This function has to be called with a port mutex held.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Returns SATA_SUCCESS if operation was successful, SATA_FAILURE otherwise.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfsata_mode_select_page_8(sata_pkt_txlate_t *spx, struct mode_cache_scsi3 *page,
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Verify parameters length. If too short, drop it */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_PARAMS_LIST;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf *pagelen = PAGELENGTH_DAD_MODE_CACHE_SCSI3 + sizeof (struct mode_page);
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * We can manipulate only write cache and read ahead
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * (read cache) setting.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * None of the features is supported - ignore
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Current setting of Read Ahead (and Read Cache) */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Current setting of Write Cache */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf if (page->dra == dra && page->wce == wce && page->rcd == dra) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* nothing to do */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Need to flip some setting
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Set-up Internal SET FEATURES command(s)
c03acfcad7780db4ddf763511a82026680b3b2c1ls scmd->satacmd_flags.sata_data_direction = SATA_DIR_NODATA_XFER;
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Need to flip read ahead setting */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Disable read ahead / read cache */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Enable read ahead / read cache */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Transfer command to HBA */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Pkt not accepted for execution.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now process return */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Note that the packet is not removed, so it could be re-used */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Need to flip Write Cache setting */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Enable write cache */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Disable write cache */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Transfer command to HBA */
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf * Pkt not accepted for execution.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Now process return */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * Process mode select informational exceptions control page 0x1c
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * The only changeable bit is dexcpt (disable exceptions).
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * MRIE (method of reporting informational exceptions) must be
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * "only on request".
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * Return SATA_SUCCESS if operation succeeded, SATA_FAILURE otherwise.
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * If operation resulted in changing device setup, dmod flag should be set to
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * one (1). If parameters were not changed, dmod flag should be set to 0.
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * Upon return, if operation required sending command to the device, the rval
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * should be set to the value returned by sata_hba_start. If operation
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * did not require device access, rval should be set to TRAN_ACCEPT.
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * The pagelen should be set to the length of the page.
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * This function has to be called with a port mutex held.
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * Returns SATA_SUCCESS if operation was successful, SATA_FAILURE otherwise.
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls /* Verify parameters length. If too short, drop it */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls if (((PAGELENGTH_INFO_EXCPT + sizeof (struct mode_page)) < parmlen) ||
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls page->perf || page->test || (page->mrie != MRIE_ONLY_ON_REQUEST)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_PARAMS_LIST;
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls *pagelen = PAGELENGTH_INFO_EXCPT + sizeof (struct mode_page);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_CDB;
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls /* If already in the state requested, we are done */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls if (page->dexcpt == ! (sata_id->ai_features85 & SATA_SMART_ENABLED)) {
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls /* nothing to do */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls scmd->satacmd_flags.sata_data_direction = SATA_DIR_NODATA_XFER;
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls /* Build SMART_ENABLE or SMART_DISABLE command */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls /* Transfer command to HBA */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls * Pkt not accepted for execution.
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls /* Now process return */
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls if (spx->txlt_sata_pkt->satapkt_reason == SATA_PKT_COMPLETED)
2c9565cfcd87a2045c2e4b76f31ac4e978903589ls /* Packet did not complete successfully */
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls mode_acoustic_management *page, int parmlen, int *pagelen,
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls /* If parmlen is too short or the feature is not supported, drop it */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_code = SD_SCSI_ASC_INVALID_FIELD_IN_PARAMS_LIST;
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls sizeof (struct mode_page);
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * We can enable and disable acoustice management and
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * set the acoustic management level.
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * Set-up Internal SET FEATURES command(s)
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls scmd->satacmd_flags.sata_data_direction = SATA_DIR_NODATA_XFER;
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls scmd->satacmd_sec_count_lsb = page->acoustic_manag_level;
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls } else { /* disabling acoustic management */
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls /* Transfer command to HBA */
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls * Pkt not accepted for execution.
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls /* Now process return */
b8b2574e5d3933aeb12d6ab6efd4dcf9fe9a5960ls if (spx->txlt_sata_pkt->satapkt_reason != SATA_PKT_COMPLETED) {
c03acfcad7780db4ddf763511a82026680b3b2c1ls * sata_build_lsense_page0() is used to create the
c03acfcad7780db4ddf763511a82026680b3b2c1ls * SCSI LOG SENSE page 0 (supported log pages)
c03acfcad7780db4ddf763511a82026680b3b2c1ls * Currently supported pages are 0, 0x10, 0x2f and 0x30
c03acfcad7780db4ddf763511a82026680b3b2c1ls * (supported log pages, self-test results, informational exceptions
c03acfcad7780db4ddf763511a82026680b3b2c1ls * and Sun vendor specific ATA SMART data).
c03acfcad7780db4ddf763511a82026680b3b2c1ls * Takes a sata_drive_info t * and the address of a buffer
c03acfcad7780db4ddf763511a82026680b3b2c1ls * in which to create the page information.
c03acfcad7780db4ddf763511a82026680b3b2c1ls * Returns the number of bytes valid in the buffer.
c03acfcad7780db4ddf763511a82026680b3b2c1lssata_build_lsense_page_0(sata_drive_info_t *sdinfo, uint8_t *buf)
c03acfcad7780db4ddf763511a82026680b3b2c1ls int num_pages_supported = 1; /* Always have GET_SUPPORTED_LOG_PAGES */
c03acfcad7780db4ddf763511a82026680b3b2c1ls if (sata_id->ai_cmdset84 & SATA_SMART_SELF_TEST_SUPPORTED) {
c03acfcad7780db4ddf763511a82026680b3b2c1ls * sata_build_lsense_page_10() is used to create the
c03acfcad7780db4ddf763511a82026680b3b2c1ls * SCSI LOG SENSE page 0x10 (self-test results)
c03acfcad7780db4ddf763511a82026680b3b2c1ls * Takes a sata_drive_info t * and the address of a buffer
c03acfcad7780db4ddf763511a82026680b3b2c1ls * in which to create the page information as well as a sata_hba_inst_t *.
c03acfcad7780db4ddf763511a82026680b3b2c1ls * Returns the number of bytes valid in the buffer.
c03acfcad7780db4ddf763511a82026680b3b2c1ls if (sdinfo->satadrv_features_support & SATA_DEV_F_LBA48) {
c03acfcad7780db4ddf763511a82026680b3b2c1ls rval = sata_ext_smart_selftest_read_log(sata_hba_inst, sdinfo,
c03acfcad7780db4ddf763511a82026680b3b2c1ls if (rval == 0) {
c03acfcad7780db4ddf763511a82026680b3b2c1ls if (block_num != 0) {
489f952b4388bd1ea1feff97164a4416e0c621eals /* If this is an unused entry, we are done */
489f952b4388bd1ea1feff97164a4416e0c621eals /* Broken firmware on some disks */
489f952b4388bd1ea1feff97164a4416e0c621eals sizeof (empty)) == 0)
c03acfcad7780db4ddf763511a82026680b3b2c1ls switch (status) {
489f952b4388bd1ea1feff97164a4416e0c621eals if (status != 0) {
489f952b4388bd1ea1feff97164a4416e0c621eals } else { /* No bad block address */
c03acfcad7780db4ddf763511a82026680b3b2c1ls if (index < 0) {
c03acfcad7780db4ddf763511a82026680b3b2c1ls [0] == 0) &&
c03acfcad7780db4ddf763511a82026680b3b2c1ls [1] == 0))
c03acfcad7780db4ddf763511a82026680b3b2c1ls sizeof (struct smart_ext_selftest_log));
c03acfcad7780db4ddf763511a82026680b3b2c1ls selftest_log = kmem_zalloc(sizeof (struct smart_selftest_log),
c03acfcad7780db4ddf763511a82026680b3b2c1ls if (rval == 0) {
c03acfcad7780db4ddf763511a82026680b3b2c1ls switch (status) {
489f952b4388bd1ea1feff97164a4416e0c621eals if (status != 0) {
489f952b4388bd1ea1feff97164a4416e0c621eals } else { /* No block address */
c03acfcad7780db4ddf763511a82026680b3b2c1ls if (index < 0) {
c03acfcad7780db4ddf763511a82026680b3b2c1ls kmem_free(selftest_log, sizeof (struct smart_selftest_log));
c03acfcad7780db4ddf763511a82026680b3b2c1ls return ((SCSI_LOG_PARAM_HDR_LEN + SCSI_LOG_SENSE_SELFTEST_PARAM_LEN) *
c03acfcad7780db4ddf763511a82026680b3b2c1ls * sata_build_lsense_page_2f() is used to create the
c03acfcad7780db4ddf763511a82026680b3b2c1ls * SCSI LOG SENSE page 0x10 (informational exceptions)
c03acfcad7780db4ddf763511a82026680b3b2c1ls * Takes a sata_drive_info t * and the address of a buffer
c03acfcad7780db4ddf763511a82026680b3b2c1ls * in which to create the page information as well as a sata_hba_inst_t *.
c03acfcad7780db4ddf763511a82026680b3b2c1ls * Returns the number of bytes valid in the buffer.
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* Now get the SMART status w.r.t. threshold exceeded */
c03acfcad7780db4ddf763511a82026680b3b2c1ls rval = sata_fetch_smart_return_status(sata_hba_inst, sdinfo);
c03acfcad7780db4ddf763511a82026680b3b2c1ls switch (rval) {
c03acfcad7780db4ddf763511a82026680b3b2c1ls#if defined(SATA_DEBUG)
c03acfcad7780db4ddf763511a82026680b3b2c1ls cmn_err(CE_PANIC, "sata_build_lsense_page_2f bad return value");
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* NOTREACHED */
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* Now get the temperature */
c03acfcad7780db4ddf763511a82026680b3b2c1ls rval = sata_smart_read_log(sata_hba_inst, sdinfo, smart_data,
489f952b4388bd1ea1feff97164a4416e0c621eals lpp->param_values[2] = temp; /* most recent temperature */
489f952b4388bd1ea1feff97164a4416e0c621eals lpp->param_values[3] = 0; /* required vendor specific byte */
c03acfcad7780db4ddf763511a82026680b3b2c1ls return (SCSI_INFO_EXCEPTIONS_PARAM_LEN + SCSI_LOG_PARAM_HDR_LEN);
c03acfcad7780db4ddf763511a82026680b3b2c1ls * sata_build_lsense_page_30() is used to create the
c03acfcad7780db4ddf763511a82026680b3b2c1ls * SCSI LOG SENSE page 0x30 (Sun's vendor specific page for ATA SMART data).
c03acfcad7780db4ddf763511a82026680b3b2c1ls * Takes a sata_drive_info t * and the address of a buffer
c03acfcad7780db4ddf763511a82026680b3b2c1ls * in which to create the page information as well as a sata_hba_inst_t *.
c03acfcad7780db4ddf763511a82026680b3b2c1ls * Returns the number of bytes valid in the buffer.
c03acfcad7780db4ddf763511a82026680b3b2c1ls struct smart_data *smart_data = (struct smart_data *)buf;
c03acfcad7780db4ddf763511a82026680b3b2c1ls /* Now do the SMART READ DATA */
c03acfcad7780db4ddf763511a82026680b3b2c1ls rval = sata_fetch_smart_data(sata_hba_inst, sdinfo, smart_data);
c03acfcad7780db4ddf763511a82026680b3b2c1ls return (0);
c03acfcad7780db4ddf763511a82026680b3b2c1ls return (sizeof (struct smart_data));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown/* ************************** ATAPI-SPECIFIC FUNCTIONS ********************** */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Start command for ATAPI device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function processes scsi_pkt requests.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Only CD/DVD devices are supported.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Most commands are packet without any translation into Packet Command.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Some may be trapped and executed as SATA commands (not clear which one).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns TRAN_ACCEPT if command is accepted for execution (or completed
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * execution).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns other TRAN_XXXX codes if command is not accepted or completed
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * (see return values for sata_hba_start()).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Inquiry cdb format differs between transport version 2 and 3.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * However, the transport version 3 devices that were checked did not adhere
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * to the specification (ignored MSB of the allocation length). Therefore,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the transport version is not checked, but Inquiry allocation length is
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * truncated to 255 bytes if the original allocation length set-up by the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * target driver is greater than 255 bytes.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_cmd_t *scmd = &spx->txlt_sata_pkt->satapkt_cmd;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown struct buf *bp = spx->txlt_sata_pkt->satapkt_cmd.satacmd_bp;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_hba_inst_t *sata_hba = SATA_TXLT_HBA_INST(spx);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_drive_info_t *sdinfo = sata_get_device_info(sata_hba,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown union scsi_cdb *cdbp = (union scsi_cdb *)scsipkt->pkt_cdbp;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (((rval = sata_txlt_generic_pkt_info(spx)) != TRAN_ACCEPT) ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * ATAPI device executes some ATA commands in addition to MMC command
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * set. These ATA commands may be executed by the regular SATA
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * translation functions. None needs to be captured now.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Other commands belong to MMC command set and are delivered
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * to ATAPI device via Packet Command.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Check the size of cdb */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata: invalid ATAPI cdb length %d",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * For non-read/write commands we need to
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * map buffer
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * scmd->satacmd_flags.sata_data_direction default -
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_DIR_NODATA_XFER - is set by
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_txlt_generic_pkt_info().
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_READ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set up ATAPI packet command.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Copy cdb into sata_cmd */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_acdb_len = sdinfo->satadrv_atapi_cdb_len;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* See note in the command header */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "%02x %02x %02x %02x %02x %02x %02x %02x "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "%2x %02x %02x %02x %02x %02x %02x %02x",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Preset request sense data to NO SENSE.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If there is no way to get error information via Request Sense,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the packet request sense data would not have to be modified by HBA,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * but it could be returned as is.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bzero(scmd->satacmd_rqsense, SATA_ATAPI_RQSENSE_LEN);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (struct scsi_extended_sense *)scmd->satacmd_rqsense);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (!(spx->txlt_sata_pkt->satapkt_op_mode & SATA_OPMODE_SYNCH)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Need callback function */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_sata_pkt->satapkt_comp = sata_txlt_atapi_completion;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Transfer command to HBA */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Pkt not accepted for execution */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If execution is non-synchronous,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * a callback function will handle potential errors, translate
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the response and will do a callback to a target driver.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If it was synchronous, use the same framework callback to check
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * an execution status.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "synchronous execution status %x\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * ATAPI Packet command completion.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Failure of the command passed via Packet command are considered device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * error. SATA HBA driver would have to retrieve error data (via Request
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Sense command delivered via error retrieval sata packet) and copy it
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * to satacmd_rqsense array. From there, it is moved into scsi pkt sense data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sata_pkt_txlate_t *)sata_pkt->satapkt_framework_private;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown uint8_t *rqsp = sata_pkt->satapkt_cmd.satacmd_rqsense;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scsipkt->pkt_state = STATE_GOT_BUS | STATE_GOT_TARGET |
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_pkt->satapkt_reason == SATA_PKT_COMPLETED) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Normal completion */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Temporary buffer was used */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Something went wrong - analyze return
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_pkt->satapkt_reason == SATA_PKT_DEV_ERROR) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We may not have ARQ data if there was a double
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * error. But sense data in sata packet was pre-set
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * with NO SENSE so it is valid even if HBA could
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * not retrieve a real sense data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Just copy this sense data into scsi pkt sense area.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_txlt_atapi_completion: %02x\n"
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "RQSENSE: %02x %02x %02x %02x %02x %02x "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown " %02x %02x %02x %02x %02x %02x "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown " %02x %02x %02x %02x %02x %02x\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We have no device data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* No extended sense key - no info available */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* scsipkt->pkt_reason = CMD_TIMEOUT; */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* No extended sense key */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Need to check if HARDWARE_ERROR/
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * TIMEOUT_ON_LOGICAL_UNIT 4/3E/2 would be more
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * appropriate.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Should we set key COMMAND_ABPRTED? */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * May be we should set Unit Attention /
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Reset. Perhaps the same should be
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * returned for disks....
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_txlt_atapi_completion: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "invalid packet completion reason"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* scsi callback required */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set up error retrieval sata command for ATAPI Packet Command error data
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * recovery.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns SATA_SUCCESS when data buffer is allocated and packet set-up,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * returns SATA_FAILURE otherwise.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_atapi_err_ret_cmd_setup(sata_pkt_txlate_t *spx, sata_drive_info_t *sdinfo)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate dma-able buffer error data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Buffer allocation will take care of buffer alignment and other DMA
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * attributes.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bp = sata_alloc_local_buffer(spx, SATA_ATAPI_MIN_RQSENSE_LEN);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_get_err_retrieval_pkt: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Operation modes are up to the caller */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_op_mode = SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback - may be changed by the caller */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_READ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set-up acdb. Request Sense CDB (packet command content) is
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * not in DMA-able buffer. Its handling is HBA-specific (how
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * it is transfered into packet FIS).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_acdb_len = sdinfo->satadrv_atapi_cdb_len;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bcopy(sata_rqsense_cdb, scmd->satacmd_acdb, SATA_ATAPI_RQSENSE_CDB_LEN);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Following zeroing of pad bytes may not be necessary */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bzero(&scmd->satacmd_acdb[SATA_ATAPI_RQSENSE_CDB_LEN],
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo->satadrv_atapi_cdb_len - SATA_ATAPI_RQSENSE_CDB_LEN);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set-up pointer to the buffer handle, so HBA can sync buffer
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * before accessing it. Handle is in usual place in translate struct.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_err_ret_buf_handle = &spx->txlt_buf_dma_handle;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Preset request sense data to NO SENSE.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Here it is redundant, only for a symetry with scsi-originated
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * packets. It should not be used for anything but debugging.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bzero(scmd->satacmd_rqsense, SATA_ATAPI_RQSENSE_LEN);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (struct scsi_extended_sense *)scmd->satacmd_rqsense);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set-up ATAPI packet command.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Data transfer direction has to be set-up in sata_cmd structure prior to
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * calling this function.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns void
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_atapi_packet_cmd_setup(sata_cmd_t *scmd, sata_drive_info_t *sdinfo)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_lba_mid_lsb = (uint8_t)SATA_ATAPI_MAX_BYTES_PER_DRQ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We want all data to be transfered via DMA.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * But specify it only if drive supports DMA and DMA mode is
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * selected - some drives are sensitive about it.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Hopefully it wil work for all drives....
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Features register requires special care for devices that use
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Serial ATA bridge - they need an explicit specification of
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the data transfer direction for Packet DMA commands.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Setting this bit is harmless if DMA is not used.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Many drives do not implement word 80, specifying what ATA/ATAPI
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * spec they follow.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We are arbitrarily following the latest SerialATA 2.6 spec,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * which uses ATA/ATAPI 6 specification for Identify Data, unless
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * ATA/ATAPI-7 support is explicitly indicated.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_id.ai_majorversion & SATA_MAJVER_7) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Specification of major version is valid and version 7
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * is supported. It does automatically imply that all
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * spec features are supported. For now, we assume that
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * DMADIR setting is valid. ATA/ATAPI7 spec is incomplete.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown/* Display 18 bytes of Inquiry data */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown struct scsi_inquiry *inq = (struct scsi_inquiry *)buf;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(CE_NOTE, "removable media %x", inq->inq_rmb);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(CE_NOTE, "response data format %d, aenc %d",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(CE_NOTE, " additional length %d", inq->inq_len);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(CE_NOTE, "vendor id (binary): %02x %02x %02x %02x "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "%02x %02x %02x %02x",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(CE_NOTE, "vendor id: %c %c %c %c %c %c %c %c",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(CE_NOTE, "product id (binary): %02x %02x %02x %02x "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(CE_NOTE, "product id: %c %c %c %c %c %c %c %c "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "%c %c %c %c %c %c %c %c",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(CE_NOTE, "revision (binary): %02x %02x %02x %02x",
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_save_atapi_trace(sata_pkt_txlate_t *spx, int count)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (count != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* saving cdb */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bzero(sata_atapi_trace[sata_atapi_trace_index].acdb,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_atapi_trace[sata_atapi_trace_index].acdb, count);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bcopy(&((struct scsi_arq_status *)scsi_pkt->pkt_scbp)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_atapi_trace[sata_atapi_trace_index].scsi_pkt_reason =
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_atapi_trace[sata_atapi_trace_index].sata_pkt_reason =
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Fetch inquiry data from ATAPI device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns SATA_SUCCESS if operation was successfull, SATA_FAILURE otherwise.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * inqb pointer does not points to a DMA-able buffer. It is a local buffer
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * where the caller expects to see the inquiry data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_get_atapi_inquiry_data(sata_hba_inst_t *sata_hba,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* address is needed now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* scsi_inquiry size buffer */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bp = sata_alloc_local_buffer(spx, sizeof (struct scsi_inquiry));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_get_atapi_inquiry_data: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot allocate data buffer"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Use synchronous mode */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_op_mode = SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Issue inquiry command - 6 bytes cdb, data transfer, read */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_READ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* we have to be carefull about the disapearing device */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set-up acdb. This works for atapi transport version 2 and later.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_acdb_len = sdinfo->satadrv_atapi_cdb_len;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_acdb[4] = sizeof (struct scsi_inquiry);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (struct scsi_extended_sense *)scmd->satacmd_rqsense);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Transfer command to HBA */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Pkt not accepted for execution */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_get_atapi_inquiry_data: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Packet not accepted for execution - ret: %02x", rval);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_get_atapi_inquiry_data: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Sync buffer. Handle is in usual place in translate struct.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Normal completion - copy data into caller's buffer
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sizeof (struct scsi_inquiry));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Something went wrong - analyze return - check rqsense data
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * ARQ data hopefull show something other than NO SENSE
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "ATAPI packet completion reason: %02x\n"
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "RQSENSE: %02x %02x %02x %02x %02x %02x "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown " %02x %02x %02x %02x %02x %02x "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown " %02x %02x %02x %02x %02x %02x\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_get_atapi_inquiry_data: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "packet reason: port error\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_get_atapi_inquiry_data: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "packet reason: timeout\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_get_atapi_inquiry_data: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "packet reason: aborted\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_get_atapi_inquiry_data: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "packet reason: reset\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_get_atapi_inquiry_data: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "invalid packet reason: %02x\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Test ATAPI packet command.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Single threaded test: send packet command in synch mode, process completion
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_test_atapi_packet_command(sata_hba_inst_t *sata_hba_inst, int cport)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo = sata_get_device_info(sata_hba_inst, &sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_test_atapi_packet_command: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "no device info for cport %d",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* address is needed now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sata_device.satadev_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* 1024k buffer */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_test_atapi_packet_command: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot allocate data buffer");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Use synchronous mode */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_op_mode = SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback - may be changed by the caller */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Issue inquiry command - 6 bytes cdb, data transfer, read */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_READ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Set-up acdb. */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_acdb_len = sdinfo->satadrv_atapi_cdb_len;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_acdb[4] = sizeof (struct scsi_inquiry);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (struct scsi_extended_sense *)scmd->satacmd_rqsense);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Transfer command to HBA */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Pkt not accepted for execution */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_test_atapi_packet_command: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Packet not accepted for execution - ret: %02x", rval);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown &SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Sync buffer. Handle is in usual place in translate struct.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_test_atapi_packet_command: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Packet completed successfully\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Normal completion - show inquiry data
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Something went wrong - analyze return - check rqsense data
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * ARQ data hopefull show something other than NO SENSE
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "ATAPI packet completion reason: %02x\n"
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "RQSENSE: %02x %02x %02x %02x %02x %02x "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown " %02x %02x %02x %02x %02x %02x "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown " %02x %02x %02x %02x %02x %02x\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_test_atapi_packet_command: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "packet reason: port error\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_test_atapi_packet_command: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "packet reason: timeout\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_test_atapi_packet_command: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "packet reason: aborted\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_test_atapi_packet_command: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "packet reason: reset\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_test_atapi_packet_command: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "invalid packet reason: %02x\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown#endif /* SATA_DEBUG */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown#endif /* 1 */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown/* ************************** LOCAL HELPER FUNCTIONS *********************** */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Validate sata_tran info
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_FAILURE returns if structure is inconsistent or structure revision
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * does not match one used by the framework.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns SATA_SUCCESS if sata_hba_tran has matching revision and contains
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * required function pointers.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns SATA_FAILURE otherwise.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_validate_sata_hba_tran(dev_info_t *dip, sata_hba_tran_t *sata_tran)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_TRAN_HBA_REV is the current (highest) revision number
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * of the SATA interface.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_tran->sata_tran_hba_rev > SATA_TRAN_HBA_REV) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata: invalid sata_hba_tran version %d for driver %s",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_tran->sata_tran_hba_rev, ddi_driver_name(dip));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata: inconsistent sata_tran_hba_dip "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_tran->sata_tran_hotplug_ops->sata_tran_port_activate == NULL ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_tran->sata_tran_hotplug_ops->sata_tran_port_deactivate ==
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_LOG_D((NULL, CE_WARN, "sata: sata_hba_tran missing "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "required functions"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Remove HBA instance from sata_hba_list.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_hba_inst == (struct sata_hba_inst *)NULL) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "unknown HBA instance\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Probe all SATA ports of the specified HBA instance.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The assumption is that there are no target and attachment point minor nodes
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * created by the boot subsystems, so we do not need to prune device tree.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function is called only from sata_hba_attach(). It does not have to
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * be protected by controller mutex, because the hba_attached flag is not set
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * yet and no one would be touching this HBA instance other than this thread.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Determines if port is active and what type of the device is attached
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * (if any). Allocates necessary structures for each port.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * An AP (Attachement Point) node is created for each SATA device port even
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * when there is no device attached.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Probe controller ports first, to find port status and
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * any port multiplier attached.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (ncport = 0; ncport < SATA_NUM_CPORTS(sata_hba_inst); ncport++) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* allocate cport structure */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo = kmem_zalloc(sizeof (sata_cport_info_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_init(&cportinfo->cport_mutex, NULL, MUTEX_DRIVER, NULL);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_state &= ~SATA_PORT_STATE_CLEAR_MASK;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Regardless if a port is usable or not, create
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * an attachment point
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_MAKE_AP_MINOR(ddi_get_instance(dip), ncport, 0, 0);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_log(sata_hba_inst, CE_WARN, "sata_hba_attach: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot create SATA attachment point for port %d",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Probe port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_update_port_scr(&cportinfo->cport_scr, &sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Something went wrong? Fail the port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_dev_type = sata_device.satadev_type;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (cportinfo->cport_dev_type != SATA_DTYPE_PMULT) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * There is some device attached.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate device info structure
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_add_device(dip, sata_hba_inst, ncport, 0) !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Plugged device was not correctly identified.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Retry, within a SATA_DEV_IDENTIFY_TIMEOUT
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* sleep for a while */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ASSERT(cportinfo->cport_dev_type == SATA_DTYPE_PMULT);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown pminfo->pmult_addr.cport = cportinfo->cport_addr.cport;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_init(&pminfo->pmult_mutex, NULL, MUTEX_DRIVER,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Probe Port Multiplier ports */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Create an attachment point */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_hba_attach: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot create SATA attachment "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "point for port %d pmult port %d",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* sata_update_port_info() */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Port multipliers cannot be chained */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * There is something attached to Port
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Multiplier device port
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate device info structure
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Plugged device was not correctly
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * identified. Retry, within the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_DEV_IDENTIFY_TIMEOUT
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* sleep for a while */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Add SATA device for specified HBA instance & port (SCSI target
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device nodes).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function is called (indirectly) only from sata_hba_attach().
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * A target node is created when there is a supported type device attached,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * but may be removed if it cannot be put online.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function cannot be called from an interrupt context.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * ONLY DISK TARGET NODES ARE CREATED NOW
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns SATA_SUCCESS when port/device was fully processed, SATA_FAILURE when
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device identification failed - adding a device could be retried.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_add_device(dev_info_t *pdip, sata_hba_inst_t *sata_hba_inst, int cport,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ASSERT(cportinfo->cport_dev_type != SATA_DTYPE_NONE);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Some device is attached to a controller port.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We rely on controllers distinquishing between no-device,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * attached port multiplier and other kind of attached device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We need to get Identify Device data and determine
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * positively the dev type before trying to attach
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the target driver.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (cportinfo->cport_dev_type != SATA_DTYPE_PMULT) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Not port multiplier.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown rval = sata_probe_device(sata_hba_inst, &sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sata_device.satadev_type & SATA_VALID_DEV_TYPE) == 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Could not determine device type or
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * a device is not supported.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Degrade this device to unknown.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_dev_type = sata_device.satadev_type;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Initialize device to the desired state. Even if it
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * fails, the device will still attach but syslog
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * will show the warning.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_CPORTINFO_DRV_INFO(cportinfo)) != SATA_SUCCESS)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Retry */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Attaching target node failed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We retain sata_drive_info structure...
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* This must be Port Multiplier type */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (cportinfo->cport_dev_type != SATA_DTYPE_PMULT) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_add_device: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "unrecognized dev type %x",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown rval = sata_probe_device(sata_hba_inst, &sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sata_device.satadev_type & SATA_VALID_DEV_TYPE) == 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Could not determine device type.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Degrade this device to unknown.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown pmportinfo->pmport_dev_type = sata_device.satadev_type;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Initialize device to the desired state.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Even if it fails, the device will still
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * attach but syslog will show the warning.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Retry */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Attaching target node failed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We retain sata_drive_info structure...
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Create scsi target node for attached device, create node properties and
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * attach the node.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The node could be removed if the device onlining fails.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * A dev_info_t pointer is returned if operation is successful, NULL is
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * returned otherwise.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * No port multiplier support.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_create_target_node(dev_info_t *dip, sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&(SATA_CPORT_MUTEX(sata_hba_inst, sata_addr->cport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo = sata_get_device_info(sata_hba_inst, &sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_create_target_node: no sdinfo for target %x",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * create or get scsi inquiry data, expected by
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * scsi_hba_nodename_compatible_get()
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA hard disks get Identify Data translated into Inguiry Data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * ATAPI devices respond directly to Inquiry request.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown } else { /* Assume supported ATAPI device */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_get_atapi_inquiry_data(sata_hba_inst, sata_addr,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Save supported ATAPI transport version
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* determine the node name and compatible */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown inq.inq_dtype, NULL, &nname, &compatible, &ncompatible);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot determine nodename for target %d\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_create_target_node: no compatible name\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (i = 0; i < ncompatible; i++) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* if nodename can't be determined, log error and exit */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_create_target_node: cannot determine nodename "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scsi_hba_nodename_compatible_free(nname, compatible);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Create scsi target node
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ndi_devi_alloc_sleep(dip, nname, (pnode_t)DEVI_SID_NODEID, &cdip);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_LOG_D((sata_hba_inst, CE_WARN, "sata_create_target_node: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Create target node properties: target & lun
2038334ab26baaa43c9083f35def041511c3cc1fUnknown rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "target", target);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_LOG_D((sata_hba_inst, CE_WARN, "sata_create_target_node: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown rval = ndi_prop_update_int(DDI_DEV_T_NONE, cdip, "lun", 0);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_LOG_D((sata_hba_inst, CE_WARN, "sata_create_target_node: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Add "variant" property
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_create_target_node: variant atapi "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* decorate the node with compatible */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (ndi_prop_update_string_array(DDI_DEV_T_NONE, cdip, "compatible",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_create_target_node: FAIL compatible props cdip 0x%p",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Now, try to attach the driver. If probing of the device fails,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the target node may be removed
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scsi_hba_nodename_compatible_free(nname, compatible);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* target node was removed - are we sure? */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scsi_hba_nodename_compatible_free(nname, compatible);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_LOG_D((sata_hba_inst, CE_WARN, "sata_create_target_node: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_log(sata_hba_inst, CE_WARN, "sata_create_target_node: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot create target node for SATA device at port %d",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Re-probe sata port, check for a device and attach info
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * structures when necessary. Identify Device data is fetched, if possible.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Assumption: sata address is already validated.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_SUCCESS is returned if port is re-probed sucessfully, regardless of
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the presence of a device and its type.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * flag arg specifies that the function should try multiple times to identify
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device type and to initialize it, or it should return immediately on failure.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_DEV_IDENTIFY_RETRY - retry
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_DEV_IDENTIFY_NORETRY - no retry
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_FAILURE is returned if one of the operations failed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function cannot be called in interrupt context - it may sleep.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_reprobe_port(sata_hba_inst_t *sata_hba_inst, sata_device_t *sata_device,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* We only care about host sata cport for now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We are re-probing port with a previously attached device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Save previous device type and settings
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* probe port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_state &= ~SATA_PORT_STATE_CLEAR_MASK;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_LOG_D((sata_hba_inst, CE_WARN, "sata_reprobe_port: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "SATA port %d probing failed",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * update sata port state and set device type
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Sanity check - Port is active? Is the link active?
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Is there any device attached?
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (cportinfo->cport_scr.sstatus & SATA_PORT_DEVLINK_UP_MASK) !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Port in non-usable state or no link active/no device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Free info structure if necessary (direct attached drive
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * only, for now!
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Add here differentiation for device attached or not */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_dev_type = sata_device->satadev_type;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If we are re-probing the port, there may be
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_drive_info structure attached
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * (or sata_pm_info, if PMult is supported).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * There is no device, so remove device info structure,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * if necessary. Direct attached drive only!
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "SATA device detached "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_device->satadev_type != SATA_DTYPE_PMULT) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * There is some device attached, but there is
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * no sata_drive_info structure - allocate one
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Recheck, that the port state did not change when we
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * released mutex.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Port is not in ready state, we
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * cannot attach a device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Since we are adding device, presumably new one,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * indicate that it should be initalized,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * as well as some internal framework states).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_device->satadev_addr.qual = sdinfo->satadrv_addr.qual;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The device is a port multiplier - not handled now.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Figure out what kind of device we are really
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * dealing with.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown rval = sata_probe_device(sata_hba_inst, sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If we are dealing with the same type of a device as before,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * restore its settings flags.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Set initial device features, if necessary */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown rval = sata_initialize_device(sata_hba_inst, sdinfo);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * A device was not successfully identified or initialized.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Track retry time for device identification.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* sleep for a while */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Initialize device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Specified device is initialized to a default state.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns SATA_SUCCESS if all device features are set successfully,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_FAILURE otherwise
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_initialize_device(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown rval = sata_set_drive_features(sata_hba_inst, sdinfo, 0);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Determine current data transfer mode */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sdinfo->satadrv_id.ai_cap & SATA_DMA_SUPPORT) == 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_id.ai_ultradma & SATA_UDMA_SEL_MASK) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* DMA supported, not no DMA transfer mode is selected !? */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Initialize write cache mode.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The default write cache setting for SATA HDD is provided by sata_write_cache
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * static variable. ATAPI CD/DVDs devices have write cache default is
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * determined by sata_atapicdvd_write_cache static variable.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * 1 - enable
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * 0 - disable
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * any other value - current drive setting
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Although there is not reason to disable write cache on CD/DVD devices,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the default setting control is provided for the maximun flexibility.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * In the future, it may be overridden by the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * disk-write-cache-enable property setting, if it is defined.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns SATA_SUCCESS if all device features are set successfully,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_FAILURE otherwise.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_init_write_cache_mode(sata_drive_info_t *sdinfo)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown else if (sata_write_cache == 0)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * When sata_write_cache value is not 0 or 1,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * a current setting of the drive's write cache is used.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown } else { /* Assume ATAPI CD/DVD device */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * When sata_write_cache value is not 0 or 1,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * a current setting of the drive's write cache is used.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Validate sata address.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Specified cport, pmport and qualifier has to match
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * passed sata_scsi configuration info.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The presence of an attached device is not verified.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns 0 when address is valid, -1 otherwise.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_validate_sata_address(sata_hba_inst_t *sata_hba_inst, int cport,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((qual == SATA_ADDR_DPMPORT || qual == SATA_ADDR_PMPORT) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ((SATA_CPORT_DEV_TYPE(sata_hba_inst, cport) != SATA_DTYPE_PMULT) ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (pmport >= SATA_NUM_PMPORTS(sata_hba_inst, cport))))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (0);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Validate scsi address
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SCSI target address is translated into SATA cport/pmport and compared
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * with a controller port/device configuration. LUN has to be 0.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns 0 if a scsi target refers to an attached device,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * returns 1 if address is valid but device is not attached,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * returns -1 if bad address or device is of an unsupported type.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Upon return sata_device argument is set.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_validate_scsi_address(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown struct scsi_address *ap, sata_device_t *sata_device)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (qual != SATA_ADDR_DCPORT && qual != SATA_ADDR_DPMPORT)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_validate_sata_address(sata_hba_inst, cport, pmport, qual) ==
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (cportinfo->cport_dev_type == SATA_DTYPE_PMULT ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (SATA_PMPORT_INFO(sata_hba_inst, cport, pmport) ==
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (0);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_validate_scsi_address: no valid target %x lun %x",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Find dip corresponding to passed device number
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns NULL if invalid device number is passed or device cannot be found,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns dip is device is found.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown while (dip && (ddi_get_instance(dip) != instance)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Probe device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function issues Identify Device command and initializes local
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_drive_info structure if the device can be identified.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The device type is determined by examining Identify Device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * command response.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If the sata_hba_inst has linked drive info structure for this
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device address, the Identify Device data is stored into sata_drive_info
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * structure linked to the port info structure.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_device has to refer to the valid sata port(s) for HBA described
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * by sata_hba_inst structure.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_SUCCESS if device type was successfully probed and port-linked
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * drive info structure was updated;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_FAILURE if there is no device, or device was not probed
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * successully;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_RETRY if device probe can be retried later.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If a device cannot be identified, sata_device's dev_state and dev_type
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * fields are set to unknown.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * There are no retries in this function. Any retries should be managed by
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the caller.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_probe_device(sata_hba_inst_t *sata_hba_inst, sata_device_t *sata_device)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_drive_info_t new_sdinfo; /* local drive info struct */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Get pointer to port-linked sata device info structure */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo = sata_get_device_info(sata_hba_inst, sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* No device to probe */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Need to issue both types of identify device command and
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * determine device type by examining retreived data/status.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * First, ATA Identify Device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown new_sdinfo.satadrv_addr = sata_device->satadev_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown rval = sata_identify_device(sata_hba_inst, &new_sdinfo);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* We may try to check for ATAPI device */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (SATA_FEATURES(sata_hba_inst) & SATA_CTLF_ATAPI) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * HBA supports ATAPI - try to issue Identify Packet
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Device command.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown rval = sata_identify_device(sata_hba_inst, &new_sdinfo);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Got something responding positively to ATA Identify Device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * or to Identify Packet Device cmd.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Save last used device type.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_device->satadev_type = new_sdinfo.satadrv_type;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* save device info, if possible */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo = sata_get_device_info(sata_hba_inst, sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Copy drive info into the port-linked drive info structure.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_device->satadev_addr.qual == SATA_ADDR_DCPORT)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown else /* SATA_ADDR_DPMPORT */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * It may be SATA_RETRY or SATA_FAILURE return.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Looks like we cannot determine the device type at this time.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo = sata_get_device_info(sata_hba_inst, sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_device->satadev_addr.qual == SATA_ADDR_DCPORT)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* SATA_ADDR_DPMPORT */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Get pointer to sata_drive_info structure.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The sata_device has to contain address (cport, pmport and qualifier) for
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * specified sata_scsi structure.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns NULL if device address is not valid for this HBA configuration.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Otherwise, returns a pointer to sata_drive_info structure.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function should be called with a port mutex held.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Port not probed yet */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (SATA_CPORT_DEV_TYPE(sata_hba_inst, cport) == SATA_DTYPE_NONE)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Request for a device on a controller port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Port multiplier attached */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (pmport > SATA_NUM_PMPORTS(sata_hba_inst, cport))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (SATA_PMPORT_DRV_INFO(sata_hba_inst, cport, pmport));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* we should not get here */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_identify_device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Send Identify Device command to SATA HBA driver.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If command executes successfully, update sata_drive_info structure pointed
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * to by sdinfo argument, including Identify Device data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If command fails, invalidate data in sata_drive_info.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Cannot be called from interrupt level.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_SUCCESS if the device was identified as a supported device,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_RETRY if the device was not identified but could be retried,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_FAILURE if the device was not identified and identify attempt
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * should not be retried.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* fetch device identify data */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((rval = sata_fetch_device_identify_data(sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Change device type to reflect Identify Device data */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown } else if (sdinfo->satadrv_type == SATA_DTYPE_ATAPICD &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (((cfg_word & SATA_ATAPI_TYPE_MASK) != SATA_ATAPI_TYPE) ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ((cfg_word & SATA_ATAPI_ID_DEV_TYPE) != SATA_ATAPI_CDROM_DEV))) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Change device type to reflect Identify Device data ! */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sdinfo->satadrv_id.ai_config & SATA_ATA_TYPE_MASK) ==
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Non-LBA disk. Too bad... */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "SATA disk device at port %d does not support LBA",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Left for historical reason */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Some initial version of SATA spec indicated that at least
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * UDMA mode 4 has to be supported. It is not metioned in
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SerialATA 2.6, so this restriction is removed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Check for Ultra DMA modes 6 through 0 being supported */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (i = 6; i >= 0; --i) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * At least UDMA 4 mode has to be supported. If mode 4 or
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * higher are not supported by the device, fail this
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (i < 4) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* No required Ultra DMA mode supported */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "SATA disk device at port %d does not support UDMA "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "mode 4 or higher required, %d supported", i));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Invalidate sata_drive_info ? */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Log/display device information
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Show HBA path */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) ddi_pathname(SATA_DIP(sata_hba_inst), msg_buf);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Unsupported SATA device type (cfg 0x%x) at ",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown swab(msg_buf, msg_buf, sizeof (sdinfo->satadrv_id.ai_model));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown msg_buf[sizeof (sdinfo->satadrv_id.ai_model)] = '\0';
2038334ab26baaa43c9083f35def041511c3cc1fUnknown swab(msg_buf, msg_buf, sizeof (sdinfo->satadrv_id.ai_fw));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown swab(msg_buf, msg_buf, sizeof (sdinfo->satadrv_id.ai_drvser));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown msg_buf[sizeof (sdinfo->satadrv_id.ai_drvser)] = '\0';
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Assuming ATAPI CD/DVD */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SOme drives do not implement serial number and may
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * violate the spec by provinding spaces rather than zeros
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * in serial number field. Scan the buffer to detect it.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (i = 0; i < sizeof (sdinfo->satadrv_id.ai_drvser); i++) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_id.ai_majorversion & (1 << i)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "?\tATA/ATAPI-%d supported, majver 0x%x minver 0x%x\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Log some info */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_features_support & SATA_DEV_F_LBA48)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) strlcat(msg_buf, "48-bit LBA, ", MAXPATHLEN);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown else if (sdinfo->satadrv_features_support & SATA_DEV_F_LBA28)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) strlcat(msg_buf, "28-bit LBA, ", MAXPATHLEN);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_features_support & SATA_DEV_F_DMA)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_features_support & SATA_DEV_F_NCQ)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) strlcat(msg_buf, ", Native Command Queueing",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_features_support & SATA_DEV_F_TCQ)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) strlcat(msg_buf, ", Legacy Tagged Queuing", MAXPATHLEN);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sdinfo->satadrv_id.ai_cmdset82 & SATA_SMART_SUPPORTED) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_id.ai_features85 & SATA_SMART_ENABLED))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sdinfo->satadrv_id.ai_cmdset84 & SATA_SMART_SELF_TEST_SUPPORTED) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_id.ai_features87 & SATA_SMART_SELF_TEST_SUPPORTED))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) strlcat(msg_buf, ", SMART self-test", MAXPATHLEN);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_features_support & SATA_DEV_F_SATA2)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(CE_CONT, "?\tSATA Gen2 signaling speed (3.0Gbps)\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown else if (sdinfo->satadrv_features_support & SATA_DEV_F_SATA1)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(CE_CONT, "?\tSATA Gen1 signaling speed (1.5Gbps)\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) sprintf(msg_buf, "\tcapacity = %llu sectors\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) sprintf(msg_buf, "\tcapacity = %lu sectors\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_save_drive_settings extracts current setting of the device and stores
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * it for future reference, in case the device setup would need to be restored
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * after the device reset.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * For all devices read ahead and write cache settings are saved, if the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device supports these features at all.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * For ATAPI devices the Removable Media Status Notification setting is saved.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sdinfo->satadrv_id.ai_cmdset82 & SATA_LOOK_AHEAD) ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_id.ai_cmdset82 & SATA_WRITE_CACHE)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Current setting of Read Ahead (and Read Cache) */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_id.ai_features85 & SATA_LOOK_AHEAD)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Current setting of Write Cache */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_id.ai_features85 & SATA_WRITE_CACHE)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_id.ai_cmdset83 & SATA_RM_STATUS_NOTIFIC)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_check_capacity function determines a disk capacity
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * and addressing mode (LBA28/LBA48) by examining a disk identify device data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * NOTE: CHS mode is not supported! If a device does not support LBA,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * this function is not called.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns device capacity in number of blocks, i.e. largest addressable LBA+1
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Capacity valid only for LBA-addressable disk devices */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (0);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sdinfo->satadrv_id.ai_validinfo & SATA_VALIDINFO_88) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* LBA48 mode supported and enabled */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo->satadrv_features_support |= SATA_DEV_F_LBA48 |
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (i = 3; i >= 0; --i) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* LBA28 mode */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo->satadrv_features_support |= SATA_DEV_F_LBA28;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate consistent buffer for DMA transfer
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Cannot be called from interrupt level or with mutex held - it may sleep.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns pointer to allocated buffer structure, or NULL if allocation failed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownstatic struct buf *
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_alloc_local_buffer(sata_pkt_txlate_t *spx, int len)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ap.a_hba_tran = spx->txlt_sata_hba_inst->satahba_scsi_tran;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_sata_pkt->satapkt_device.satadev_addr.cport,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_sata_pkt->satapkt_device.satadev_addr.pmport,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_sata_pkt->satapkt_device.satadev_addr.qual);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Allocate DMA resources for this buffer */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We use a local version of the dma_attr, to account
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * for a device addressing limitations.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_adjust_dma_attr() will handle sdinfo == NULL which
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * will cause dma attributes to be adjusted to a lowest
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * acceptable level.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_DMA_ATTR(spx->txlt_sata_hba_inst), &cur_dma_attr);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Release local buffer (consistent buffer for DMA transfer) allocated
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * via sata_alloc_local_buffer().
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ASSERT(spx->txlt_sata_pkt->satapkt_cmd.satacmd_bp != NULL);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_sata_pkt->satapkt_cmd.satacmd_num_dma_cookies = 0;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_sata_pkt->satapkt_cmd.satacmd_dma_cookie_list = NULL;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free DMA resources */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) ddi_dma_unbind_handle(spx->txlt_buf_dma_handle);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (spx->txlt_dma_cookie_list != &spx->txlt_dma_cookie) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_dma_cookie_list_len * sizeof (ddi_dma_cookie_t));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free buffer */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scsi_free_consistent_buf(spx->txlt_sata_pkt->satapkt_cmd.satacmd_bp);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate sata_pkt
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Pkt structure version and embedded strcutures version are initialized.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_pkt and sata_pkt_txlate structures are cross-linked.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Since this may be called in interrupt context by sata_scsi_init_pkt,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * callback argument determines if it can sleep or not.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Hence, it should not be called from interrupt context.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If successful, non-NULL pointer to a sata pkt is returned.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Upon failure, NULL pointer is returned.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_pkt_alloc(sata_pkt_txlate_t *spx, int (*callback)(caddr_t))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown kmsflag = (callback == SLEEP_FUNC) ? KM_SLEEP : KM_NOSLEEP;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_pkt_alloc: failed"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Free sata pkt allocated via sata_pkt_alloc()
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ASSERT(spx->txlt_sata_pkt->satapkt_cmd.satacmd_bp == NULL);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Adjust DMA attributes.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SCSI cmds block count is up to 24 bits, SATA cmd block count vary
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * from 8 bits to 16 bits, depending on a command being used.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Limiting max block count arbitrarily to 256 for all read/write
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * commands may affects performance, so check both the device and
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * controller capability before adjusting dma attributes.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_adjust_dma_attr(sata_drive_info_t *sdinfo, ddi_dma_attr_t *dma_attr,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Copy original attributes */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Things to consider: device addressing capability,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * "excessive" controller DMA capabilities.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If a device is being probed/initialized, there are
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * no device info - use default limits then.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_features_support & (SATA_DEV_F_LBA48)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * 16-bit sector count may be used - we rely on
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the assumption that only read and write cmds
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * will request more than 256 sectors worth of data
2038334ab26baaa43c9083f35def041511c3cc1fUnknown count_max = adj_dma_attr->dma_attr_granular * 0x10000;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * 8-bit sector count will be used - default limits
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * for dma attributes
2038334ab26baaa43c9083f35def041511c3cc1fUnknown count_max = adj_dma_attr->dma_attr_granular * 0x100;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Adjust controler dma attributes, if necessary
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate DMA resources for the buffer
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function handles initial DMA resource allocation as well as
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * DMA window shift and may be called repeatedly for the same DMA window
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * until all DMA cookies in the DMA window are processed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * To guarantee that there is always a coherent set of cookies to process
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * by SATA HBA driver (observing alignment, device granularity, etc.),
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the number of slots for DMA cookies is equal to lesser of a number of
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * cookies in a DMA window and a max number of scatter/gather entries.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns DDI_SUCCESS upon successful operation.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Return failure code of a failing command or DDI_FAILURE when
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * internal cleanup failed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_dma_buf_setup(sata_pkt_txlate_t *spx, int flags,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * No DMA resources allocated so far - this is a first call
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * for this sata pkt.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown rval = ddi_dma_alloc_handle(SATA_DIP(spx->txlt_sata_hba_inst),
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cur_dma_attr, callback, arg, &spx->txlt_buf_dma_handle);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_dma_buf_setup: no buf DMA resources %x",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Check buffer alignment and size against dma attributes
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Consider dma_attr_align only. There may be requests
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * with the size lower than device granularity, but they
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * will not read/write from/to the device, so no adjustment
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * is necessary. The dma_attr_minxfer theoretically should
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * be considered, but no HBA driver is checking it.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown } else { /* Buffer is not aligned */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Check id sleeping is allowed */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATADBG2(SATA_DBG_DMA_SETUP, spx->txlt_sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "mis-aligned buffer: addr=0x%p, cnt=%lu",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * CPU will need to access data in the buffer
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * (for copying) so map it.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Buffer may be padded by ddi_dma_mem_alloc()! */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* DMA mapping failed */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_dma_buf_setup: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This will require special handling, because
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * DMA cookies will be based on the temporary
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * buffer size, not the original buffer
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * b_bcount, so the residue may have to
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * be counted differently.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_dma_buf_setup: bp size %x != "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Write operation - copy data into
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * an aligned temporary buffer. Buffer will be
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * synced for device by ddi_dma_addr_bind_handle
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATADBG1(SATA_DBG_DMA_SETUP, spx->txlt_sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Partial DMA mapping.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Retrieve number of DMA windows for this request.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_dma_buf_setup: numwin failed\n"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_dma_buf_setup: windows: %d, cookies: %d\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* DMA fully mapped */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_dma_buf_setup: windows: 1 "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* DMA mapping failed */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) ddi_dma_free_handle(&spx->txlt_buf_dma_handle);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_dma_buf_setup: buf dma handle binding "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * DMA setup is reused. Check if we need to process more
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * cookies in current window, or to get next window, if any.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * All cookies from current DMA window were processed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Get next DMA window.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (spx->txlt_cur_dma_win < spx->txlt_num_dma_win) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* No more windows! End of request! */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* What to do? - panic for now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* There better be at least one DMA cookie outstanding */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (spx->txlt_dma_cookie_list == &spx->txlt_dma_cookie) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* The default cookie slot was used in previous run */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ASSERT(spx->txlt_curwin_processed_dma_cookies == 0);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Processing a new DMA window - set-up dma cookies list.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We may reuse previously allocated cookie array if it is
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * possible.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * New DMA window contains more cookies than
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the previous one. We need larger cookie list - free
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the old one.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Calculate lesser of number of cookies in this
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * DMA window and number of s/g entries.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Allocate new dma cookie array if necessary */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Only one cookie - no need for a list */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * More than one cookie - try to allocate space.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_dma_buf_setup: cookie list "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We could not allocate space for
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * neccessary number of dma cookies in
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * this window, so we fail this request.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Next invocation would try again to
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * allocate space for cookie list.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Note:Packet residue was not modified.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Fetch DMA cookies into cookie list in sata_pkt_txlate.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * First cookie was already fetched.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown *(&spx->txlt_dma_cookie_list[0]) = spx->txlt_dma_cookie;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_sata_pkt->satapkt_cmd.satacmd_num_dma_cookies = 1;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATADBG2(SATA_DBG_DMA_SETUP, spx->txlt_sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_dma_buf_setup: sliding within DMA window, "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cur cookie %d, total cookies %d\n",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Not all cookies from the current dma window were used because
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * of s/g limitation.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * There is no need to re-size the list - it was set at
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * optimal size, or only default entry is used (s/g = 1).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Since we are processing remaining cookies in a DMA window,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * there may be less of them than the number of entries in the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * current dma cookie list.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fetch the next batch of cookies */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ASSERT(spx->txlt_sata_pkt->satapkt_cmd.satacmd_num_dma_cookies > 0);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Point sata_cmd to the cookie list */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_sata_pkt->satapkt_cmd.satacmd_dma_cookie_list =
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Remember number of DMA cookies passed in sata packet */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_sata_pkt->satapkt_cmd.satacmd_num_dma_cookies;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Temporary DMA buffer has been padded by
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * ddi_dma_mem_alloc()!
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This requires special handling, because DMA cookies are
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * based on the temporary buffer size, not the b_bcount,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * and we have extra bytes to transfer - but the packet
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * residue has to stay correct because we will copy only
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the requested number of bytes.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Fetch Device Identify data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Send DEVICE IDENTIFY or IDENTIFY PACKET DEVICE (depending on a device type)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * command to a device and get the device identify data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The device_info structure has to be set to device type (for selecting proper
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device identify command).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_SUCCESS if cmd succeeded
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_RETRY if cmd was rejected and could be retried,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_FAILURE if cmd failed and should not be retried (port error)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Cannot be called in an interrupt context.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_fetch_device_identify_data(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* address is needed now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate buffer for Identify Data return data
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bp = sata_alloc_local_buffer(spx, sizeof (sata_id_t));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_fetch_device_identify_data: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot allocate buffer for ID"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fill sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_op_mode = SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Timeout 30s */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_READ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Build Identify Device cmd in the sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Identify Packet Device cmd */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Identify Device cmd - mandatory for all other devices */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Send pkt to SATA HBA driver */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown rval = (*SATA_START_FUNC(sata_hba_inst))(SATA_DIP(sata_hba_inst), spkt);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sdinfo->satadrv_id.ai_config & SATA_INCOMPLETE_DATA) ==
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "SATA disk device at port %d - "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "partial Identify Data",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Update sata_drive_info */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Retrieve capacity (disks only) and addressing mode
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo->satadrv_capacity = sata_check_capacity(sdinfo);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * For ATAPI devices one would have to issue
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Get Capacity cmd for media capacity. Not here.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Check what cdb length is supported
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Setup supported features flags */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Check for SATA GEN and NCQ support */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* SATA compliance */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sdinfo->satadrv_id.ai_cmdset83 & SATA_RW_DMA_QUEUED_CMD) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_id.ai_features86 & SATA_RW_DMA_QUEUED_CMD))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo->satadrv_queue_depth = sdinfo->satadrv_id.ai_qdepth;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sdinfo->satadrv_features_support & SATA_DEV_F_NCQ) ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_features_support & SATA_DEV_F_TCQ))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Woops, no Identify Data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (rval == SATA_TRAN_BUSY || rval == SATA_TRAN_QUEUE_FULL) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free allocated resources */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Some devices may not come-up with default DMA mode (UDMA or MWDMA).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * UDMA mode is checked first, followed by MWDMA mode.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * set correctly, so this function is setting it to the highest supported level.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Older SATA spec required that the device supports at least DMA 4 mode and
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * UDMA mode is selected. It is not mentioned in SerialATA 2.6, so this
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * restriction has been removed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns SATA_SUCCESS if proper DMA mode is selected or no DMA is supported.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns SATA_FAILURE if proper DMA mode could not be selected.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * NOTE: This function should be called only if DMA mode is supported.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_set_dma_mode(sata_hba_inst_t *sata_hba_inst, sata_drive_info_t *sdinfo)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sdinfo->satadrv_id.ai_validinfo & SATA_VALIDINFO_88) != 0 &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_id.ai_ultradma & SATA_UDMA_SUP_MASK) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Find highest Ultra DMA mode supported */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Left for historical reasons */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Some initial version of SATA spec indicated that at least
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * UDMA mode 4 has to be supported. It is not mentioned in
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SerialATA 2.6, so this restriction is removed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Find UDMA mode currently selected */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (i = 6; i >= 0; --i) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_id.ai_ultradma & (1 << (i + 8)))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Nothing to do */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown } else if ((sdinfo->satadrv_id.ai_dworddma & SATA_MDMA_SUP_MASK) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Find highest MultiWord DMA mode supported */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Find highest MultiWord DMA mode selected */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (i = 2; i >= 0; --i) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_id.ai_dworddma & (1 << (i + 8)))
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Nothing to do */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set DMA mode via SET FEATURES COMMAND.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Prepare packet for SET FEATURES COMMAND.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_set_dma_mode: could not set DMA mode %", mode));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fill sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Timeout 30s */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback, interrupts */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_op_mode = SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_NODATA_XFER;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_features_reg = SATAC_SF_TRANSFER_MODE;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Transfer command to HBA */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((*SATA_START_FUNC(sata_hba_inst))(SATA_DIP(sata_hba_inst),
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Pkt execution failed */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free allocated resources */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set device caching mode.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * One of the following operations should be specified:
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATAC_SF_ENABLE_READ_AHEAD
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATAC_SF_DISABLE_READ_AHEAD
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATAC_SF_ENABLE_WRITE_CACHE
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATAC_SF_DISABLE_WRITE_CACHE
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If operation fails, system log messgage is emitted.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns SATA_SUCCESS when the operation succeeds, SATA_FAILURE otherwise.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_set_cache_mode(sata_hba_inst_t *sata_hba_inst, sata_drive_info_t *sdinfo,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Prepare packet for SET FEATURES COMMAND */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fill sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Timeout 30s */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback, interrupts */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_NODATA_XFER;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Transfer command to HBA */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_DIP(sata_hba_inst), spkt) != SATA_TRAN_ACCEPTED) ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Pkt execution failed */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free allocated resources */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set Removable Media Status Notification (enable/disable)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * state == 0 , disable
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * state != 0 , enable
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If operation fails, system log messgage is emitted.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns SATA_SUCCESS when the operation succeeds, SATA_FAILURE otherwise.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_set_rmsn(sata_hba_inst_t *sata_hba_inst, sata_drive_info_t *sdinfo,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Prepare packet for SET FEATURES COMMAND */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fill sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Timeout 30s */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback, interrupts */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_NODATA_XFER;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Transfer command to HBA */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_DIP(sata_hba_inst), spkt) != SATA_TRAN_ACCEPTED) ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Pkt execution failed */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Notification failed";
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Notification failed";
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free allocated resources */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Update port SCR block
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_update_port_scr(sata_port_scr_t *port_scr, sata_device_t *device)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Update state and copy port ss* values from passed sata_device structure.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_address is validated - if not valid, nothing is changed in sata_scsi
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * configuration struct.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA_PSTATE_SHUTDOWN in port state is not reset to 0 by this function
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * regardless of the state in device argument.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Port mutex should be held while calling this function.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_update_port_info(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_device->satadev_addr.qual == SATA_ADDR_CPORT ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_device->satadev_addr.qual == SATA_ADDR_DCPORT) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_update_port_scr(&cportinfo->cport_scr, sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Preserve SATA_PSTATE_SHUTDOWN flag */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sata_device->satadev_addr.qual != SATA_ADDR_PMPORT) ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sata_device->satadev_addr.qual != SATA_ADDR_DPMPORT) ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_update_port_scr(&pmportinfo->pmport_scr, sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Preserve SATA_PSTATE_SHUTDOWN flag */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Extract SATA port specification from an IOCTL argument.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function return the port the user land send us as is, unless it
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * cannot retrieve port spec, then -1 is returned.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Note: Only cport - no port multiplier port.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_get_port_num(sata_hba_inst_t *sata_hba_inst, struct devctl_iocdata *dcp)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Extract port number from nvpair in dca structure */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (nvlist_lookup_int32(ndi_dc_get_ap_data(dcp), "port", &port) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_get_port_num: invalid port spec 0x%x in ioctl",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Get dev_info_t pointer to the device node pointed to by port argument.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * NOTE: target argument is a value used in ioctls to identify
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the AP - it is not a sata_address.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * It is a combination of cport, pmport and address qualifier, encodded same
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * way as a scsi target number.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * At this moment it carries only cport number.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * No PMult hotplug support.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns dev_info_t pointer if target device was found, NULL otherwise.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown target = SATA_TO_SCSI_TARGET(ncport, 0, SATA_ADDR_DCPORT);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This is actually an error condition, but not
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * a fatal one. Just continue the search.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_cfgadm_state:
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Use the sata port state and state of the target node to figure out
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the cfgadm_state.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The port argument is a value with encoded cport,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * pmport and address qualifier, in the same manner as a scsi target number.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SCSI_TO_SATA_CPORT macro extracts cport number,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SCSI_TO_SATA_PMPORT extracts pmport number and
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SCSI_TO_SATA_ADDR_QUAL extracts port mulitplier qualifier flag.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * For now, support is for cports only - no port multiplier device ports.
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_cfgadm_state(sata_hba_inst_t *sata_hba_inst, int32_t port,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Cport only */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown port_state = SATA_CPORT_STATE(sata_hba_inst, cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Need to check pmult device port here as well, when supported */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Port is enabled and ready */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown switch (SATA_CPORT_DEV_TYPE(sata_hba_inst, cport)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* No device attached */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown case SATA_DTYPE_PMULT: /* Until PMult is supported */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * There could be the case where previously
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * configured and opened device was removed
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * and unknown device was plugged.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * In such case we want to show a device, and
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * its configured or unconfigured state but
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * indicate unusable condition untill the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * old target node is released and removed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This is actually internal error condition (non fatal),
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * because we have already checked all defined device types.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_cfgadm_state: Internal error: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "unknown device type"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Preset scsi extended sense data (to NO SENSE)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * First 18 bytes of the sense data are preset to current valid sense
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * with a key NO SENSE data.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns void
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlfstatic void
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_fixed_sense_data_preset(struct scsi_extended_sense *sense)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_class = CLASS_EXTENDED_SENSE; /* 0x70 - current err */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sense->es_add_len = 10; /* Additional length - replace with a def */
8d483882aa3390058094b043f3d62187b5d1de03mlf * Register a legacy cmdk-style devid for the target (disk) device.
8d483882aa3390058094b043f3d62187b5d1de03mlf * Note: This function is called only when the HBA devinfo node has the
8d483882aa3390058094b043f3d62187b5d1de03mlf * property "use-cmdk-devid-format" set. This property indicates that
8d483882aa3390058094b043f3d62187b5d1de03mlf * devid compatible with old cmdk (target) driver is to be generated
8d483882aa3390058094b043f3d62187b5d1de03mlf * for any target device attached to this controller. This will take
8d483882aa3390058094b043f3d62187b5d1de03mlf * precedence over the devid generated by sd (target) driver.
8d483882aa3390058094b043f3d62187b5d1de03mlf * This function is derived from cmdk_devid_setup() function in cmdk.c.
8d483882aa3390058094b043f3d62187b5d1de03mlfstatic void
8d483882aa3390058094b043f3d62187b5d1de03mlfsata_target_devid_register(dev_info_t *dip, sata_drive_info_t *sdinfo)
8d483882aa3390058094b043f3d62187b5d1de03mlf * device ID is a concatanation of model number, "=", serial number.
8d483882aa3390058094b043f3d62187b5d1de03mlf modlen = sata_check_modser(hwid, sizeof (sdinfo->satadrv_id.ai_model));
8d483882aa3390058094b043f3d62187b5d1de03mlf hwid[modlen + serlen] = 0; /* terminate the hwid string */
8d483882aa3390058094b043f3d62187b5d1de03mlf (ushort_t)(modlen + serlen), hwid, &devid)) == DDI_SUCCESS)
8d483882aa3390058094b043f3d62187b5d1de03mlf cmn_err(CE_WARN, "sata: failed to create devid for the disk"
8d483882aa3390058094b043f3d62187b5d1de03mlf * valid model/serial string must contain a non-zero non-space characters.
8d483882aa3390058094b043f3d62187b5d1de03mlf * trim trailing spaces/NULLs.
8d483882aa3390058094b043f3d62187b5d1de03mlf for (i = 0; i < buf_len; i++) {
8d483882aa3390058094b043f3d62187b5d1de03mlf return (0); /* invalid string */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_set_drive_features function compares current device features setting
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * with the saved device features settings and, if there is a difference,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * it restores device features setting to the previously saved state.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * It also arbitrarily tries to select the highest supported DMA mode.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Device Identify or Identify Packet Device data has to be current.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * At the moment read ahead and write cache are considered for all devices.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * For atapi devices, Removable Media Status Notification is set in addition
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * to common features.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function cannot be called in the interrupt context (it may sleep).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The input argument sdinfo should point to the drive info structure
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * to be updated after features are set. Note, that only
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device (packet) identify data is updated, not the flags indicating the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * supported features.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns TRUE if successful or there was nothing to do. Device Identify data
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * in the drive info structure pointed to by the sdinfo argumens is updated
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * even when no features were set or changed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns FALSE if device features could not be set.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Note: This function may fail the port, making it inaccessible.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * In such case the explicit port disconnect/connect or physical device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * detach/attach is required to re-evaluate port state again.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_set_drive_features(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_fetch_device_identify_data(sata_hba_inst, &new_sdinfo) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Cannot get device identification - retry later
2038334ab26baaa43c9083f35def041511c3cc1fUnknown finfox = (restore != 0) ? " restore device features" :
2038334ab26baaa43c9083f35def041511c3cc1fUnknown " initialize device features\n";
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Arbitrarily set UDMA mode */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_set_dma_mode(sata_hba_inst, &new_sdinfo) !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown } else { /* Assume SATA ATAPI CD/DVD */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Set Removable Media Status Notification, if necessary */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Current setting does not match saved one */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We have to set Multiword DMA or UDMA, if it is supported, as
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * we want to use DMA transfer mode whenever possible.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Some devices require explicit setting of the DMA mode.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (new_sdinfo.satadrv_id.ai_cap & SATA_DMA_SUPPORT) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Set highest supported DMA mode */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_set_dma_mode(sata_hba_inst, &new_sdinfo) !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (!(new_sdinfo.satadrv_id.ai_cmdset82 & SATA_LOOK_AHEAD) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown !(new_sdinfo.satadrv_id.ai_cmdset82 & SATA_WRITE_CACHE)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* None of the features is supported - do nothing */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (((new_sdinfo.satadrv_id.ai_features85 & SATA_LOOK_AHEAD) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_settings & SATA_DEV_READ_AHEAD)) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ((new_sdinfo.satadrv_id.ai_features85 & SATA_WRITE_CACHE) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_settings & SATA_DEV_WRITE_CACHE))) {
66f9d5cb3cc0652e2d9d1366fb950efbe4ca2f24mlf /* Nothing to do */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (!((new_sdinfo.satadrv_id.ai_features85 & SATA_LOOK_AHEAD) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_settings & SATA_DEV_READ_AHEAD))) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_settings & SATA_DEV_READ_AHEAD) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Enable read ahead / read cache */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Disable read ahead / read cache */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Try to set read cache mode */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Pkt execution failed */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (!((new_sdinfo.satadrv_id.ai_features85 & SATA_WRITE_CACHE) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (sdinfo->satadrv_settings & SATA_DEV_WRITE_CACHE))) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sdinfo->satadrv_settings & SATA_DEV_WRITE_CACHE) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Enable write cache */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Disable write cache */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Try to set write cache mode */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Pkt execution failed */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We need to fetch Device Identify data again
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_fetch_device_identify_data(sata_hba_inst, &new_sdinfo) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Cannot get device identification - retry later
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "%s cannot re-fetch device identify data\n"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Copy device sata info. */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns 1 if threshold exceeded, 0 if threshold not exceeded, -1 if
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * unable to determine.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Cannot be called in an interrupt context.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Called by sata_build_lsense_page_2f()
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_fetch_smart_return_status(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* address is needed now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fill sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_op_mode = SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Timeout 30s */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_NODATA_XFER;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Set up which registers need to be returned */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_copy_out_lba_mid_lsb = B_TRUE;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_copy_out_lba_high_lsb = B_TRUE;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Build SMART_RETURN_STATUS cmd in the sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_features_reg = SATA_SMART_RETURN_STATUS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Send pkt to SATA HBA driver */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((*SATA_START_FUNC(sata_hba_inst))(SATA_DIP(sata_hba_inst), spkt) !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Whoops, no SMART RETURN STATUS
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((scmd->satacmd_lba_mid_lsb == SMART_MAGIC_VAL_1) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown else if ((scmd->satacmd_lba_mid_lsb == SMART_MAGIC_VAL_3) &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free allocated resources */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns 0 if succeeded, -1 otherwise
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Cannot be called in an interrupt context.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown#if ! defined(lint)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* address is needed now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fill sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_op_mode = SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Timeout 30s */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_READ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate buffer for SMART data
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sizeof (struct smart_data));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_fetch_smart_data: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot allocate buffer"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Build SMART_READ_DATA cmd in the sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Send pkt to SATA HBA driver */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((*SATA_START_FUNC(sata_hba_inst))(SATA_DIP(sata_hba_inst), spkt) !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Whoops, no SMART DATA available
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bcopy(scmd->satacmd_bp->b_un.b_addr, (uint8_t *)smart_data,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sizeof (struct smart_data));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free allocated resources */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Used by LOG SENSE page 0x10
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * return 0 for success, -1 otherwise
2038334ab26baaa43c9083f35def041511c3cc1fUnknown#if ! defined(lint)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ASSERT(sizeof (struct smart_ext_selftest_log) == 512);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* address is needed now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fill sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_op_mode = SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Timeout 30s */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_READ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate buffer for SMART extended self-test log
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sizeof (struct smart_ext_selftest_log));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_ext_smart_selftest_log: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot allocate buffer"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Build READ LOG EXT w/ extended self-test log cmd in the sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_sec_count_lsb = 1; /* One sector of selftest log */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_sec_count_msb = 0; /* One sector of selftest log */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_lba_low_lsb = EXT_SMART_SELFTEST_LOG_PAGE;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Send pkt to SATA HBA driver */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((*SATA_START_FUNC(sata_hba_inst))(SATA_DIP(sata_hba_inst), spkt) !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Whoops, no SMART selftest log info available
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sizeof (struct smart_ext_selftest_log));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free allocated resources */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns 0 for success, -1 otherwise
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SMART self-test log data is returned in buffer pointed to by selftest_log
2038334ab26baaa43c9083f35def041511c3cc1fUnknown#if ! defined(lint)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* address is needed now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fill sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_op_mode = SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Timeout 30s */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_READ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate buffer for SMART SELFTEST LOG
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sizeof (struct smart_selftest_log));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_smart_selftest_log: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot allocate buffer"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Build SMART_READ_LOG cmd in the sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_sec_count_lsb = 1; /* One sector of SMART log */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_lba_low_lsb = SMART_SELFTEST_LOG_PAGE;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Send pkt to SATA HBA driver */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((*SATA_START_FUNC(sata_hba_inst))(SATA_DIP(sata_hba_inst), spkt) !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Whoops, no SMART DATA available
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bcopy(scmd->satacmd_bp->b_un.b_addr, (uint8_t *)selftest_log,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sizeof (struct smart_selftest_log));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free allocated resources */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Returns 0 for success, -1 otherwise
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SMART READ LOG data is returned in buffer pointed to by smart_log
2038334ab26baaa43c9083f35def041511c3cc1fUnknown uint8_t *smart_log, /* where the data should be returned */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown uint8_t which_log, /* which log should be returned */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* address is needed now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fill sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_op_mode = SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Timeout 30s */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_READ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate buffer for SMART READ LOG
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_bp = sata_alloc_local_buffer(spx, log_size * 512);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_smart_read_log: " "cannot allocate buffer"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Build SMART_READ_LOG cmd in the sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_sec_count_lsb = log_size; /* what the caller asked for */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_lba_low_lsb = which_log; /* which log page */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Send pkt to SATA HBA driver */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((*SATA_START_FUNC(sata_hba_inst))(SATA_DIP(sata_hba_inst), spkt) !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Whoops, no SMART DATA available
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bcopy(scmd->satacmd_bp->b_un.b_addr, smart_log, log_size * 512);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free allocated resources */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Used by LOG SENSE page 0x10
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * return 0 for success, -1 otherwise
2038334ab26baaa43c9083f35def041511c3cc1fUnknown#if ! defined(lint)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ASSERT(sizeof (struct read_log_ext_directory) == 512);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx = kmem_zalloc(sizeof (sata_pkt_txlate_t), KM_SLEEP);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spx->txlt_scsi_pkt = NULL; /* No scsi pkt involved */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fill sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_device.satadev_addr = sdinfo->satadrv_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown spkt->satapkt_op_mode = SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Synchronous mode, no callback */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Timeout 30s */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_flags.sata_data_direction = SATA_DIR_READ;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Allocate buffer for SMART READ LOG EXTENDED command
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sizeof (struct read_log_ext_directory));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_read_log_ext_directory: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot allocate buffer"));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown return (-1);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Build READ LOG EXT w/ log directory cmd in the sata_pkt */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_sec_count_lsb = 1; /* One sector of directory */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_sec_count_msb = 0; /* One sector of directory */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown scmd->satacmd_lba_low_lsb = READ_LOG_EXT_LOG_DIRECTORY;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Send pkt to SATA HBA driver */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((*SATA_START_FUNC(sata_hba_inst))(SATA_DIP(sata_hba_inst), spkt) !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Whoops, no SMART selftest log info available
2038334ab26baaa43c9083f35def041511c3cc1fUnknown bcopy(scmd->satacmd_bp->b_un.b_addr, (uint8_t *)logdir,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sizeof (struct read_log_ext_directory));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Free allocated resources */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sata_xlate_errors() is used to translate (S)ATA error
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * information to SCSI information returned in the SCSI
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We have no device data. Assume no data transfered.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (spx->txlt_sata_pkt->satapkt_cmd.satacmd_status_reg &
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * determine dev error reason from error
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * reg content
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* No extended sense key - no info available */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * scsipkt->pkt_reason = CMD_TIMEOUT; This causes problems.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* No extended sense key */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* No extended sense key */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * pkt aborted either by an explicit reset request from
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * a host, or due to error recovery
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Log sata message
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * dev pathname msg line preceeds the logged message.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_log(sata_hba_inst_t *sata_hba_inst, uint_t level, char *fmt, ...)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(level, "?%s:\n %s\n", pathname, sata_log_buf);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cmn_err(level, "%s:\n %s\n", pathname, sata_log_buf);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown/* ******** Asynchronous HBA events handling & hotplugging support ******** */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Start or terminate the thread, depending on flag arg and current state
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (startstop == 0 && (sata_event_thread_starting == 1 ||
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (startstop == 1 && sata_event_thread_starting == 1) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (startstop == 1 && sata_event_thread_terminating == 1) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* wait til terminate operation completes */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown i = SATA_EVNT_DAEMON_TERM_WAIT/SATA_EVNT_DAEMON_TERM_TIMEOUT;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (i-- <= 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "timeout waiting for thread to terminate");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If we got here, thread may need to be terminated
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Signal event thread to go away */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Wait til daemon terminates.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown i = SATA_EVNT_DAEMON_TERM_WAIT/SATA_EVNT_DAEMON_TERM_TIMEOUT;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (i-- <= 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Daemon did not go away !!! */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "cannot terminate event daemon thread");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * SATA HBA event notification function.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Events reported by SATA HBA drivers per HBA instance relate to a change in
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * a port and/or device state or a controller itself.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Events for different addresses/addr types cannot be combined.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * A warning message is generated for each event type.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Events are not processed by this function, so only the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * event flag(s)is set for an affected entity and the event thread is
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * waken up. Event daemon thread processes all events.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * NOTE: Since more than one event may be reported at the same time, one
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * cannot determine a sequence of events when opposite event are reported, eg.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * LINK_LOST and LINK_ESTABLISHED. Actual port status during event processing
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * is taking precedence over reported events, i.e. may cause ignoring some
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_hba_event_notify(dev_info_t *dip, sata_device_t *sata_device, int event)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown static char *err_msg_evnt_1 =
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_hba_event_notify: invalid port event 0x%x ";
2038334ab26baaa43c9083f35def041511c3cc1fUnknown static char *err_msg_evnt_2 =
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_hba_event_notify: invalid device event 0x%x ";
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * There is a possibility that an event will be generated on HBA
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * that has not completed attachment or is detaching.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * HBA driver should prevent this, but just in case it does not,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * we need to ignore events for such HBA.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (sata_hba_inst = sata_hba_list; sata_hba_inst != NULL;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* HBA not attached */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Validate address before - do not proceed with invalid address.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Port Multiplier not supported yet */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Events refer to devices, ports and controllers - each has
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * unique address. Events for different addresses cannot be combined.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (saddr->qual & (SATA_ADDR_CPORT | SATA_ADDR_PMPORT)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&(SATA_CPORT_MUTEX(sata_hba_inst, cport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* qualify this event(s) */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Invalid event for the device port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&(SATA_CPORT_MUTEX(sata_hba_inst, cport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Controller's device port event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Port multiplier's device port event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Add to statistics and log the message. We have to do it
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * here rather than in the event daemon, because there may be
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * multiple events occuring before they are processed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* This is likely event combination */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown 0xffffffffffffffffULL)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown 0xffffffffffffffffULL)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (pstats->device_attached < 0xffffffffffffffffULL)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (pstats->device_detached < 0xffffffffffffffffULL)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (pstats->port_pwr_changed < 0xffffffffffffffffULL)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* There should be no other events for this address */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&(SATA_CPORT_MUTEX(sata_hba_inst, cport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown } else if (saddr->qual & (SATA_ADDR_DCPORT | SATA_ADDR_DPMPORT)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&(SATA_CPORT_MUTEX(sata_hba_inst, cport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* qualify this event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Invalid event for a device */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&(SATA_CPORT_MUTEX(sata_hba_inst, cport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* drive event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo = sata_get_device_info(sata_hba_inst, sata_device);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown 0xffffffffffffffffULL)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Invalid event for a device */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&(SATA_CPORT_MUTEX(sata_hba_inst, cport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Wrong address qualifier */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_hba_event_notify: invalid address 0x%x",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Invalid event for the controller */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_hba_event_notify: invalid event 0x%x for "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "controller",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* This may be a frequent and not interesting event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown 0xffffffffffffffffULL)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If we got here, there is something to do with this HBA
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * instance.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_hba_inst->satahba_event_flags |= SATA_EVNT_MAIN;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_event_pending |= SATA_EVNT_MAIN; /* global event indicator */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Tickle event thread */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Event processing thread.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Arg is a pointer to the sata_hba_list pointer.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * It is not really needed, because sata_hba_list is global and static
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Process events here. Walk through all registered HBAs
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (sata_hba_inst = sata_hba_list; sata_hba_inst != NULL;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_hba_inst->satahba_event_flags & SATA_EVNT_MAIN) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_hba_inst->satahba_event_flags |= SATA_EVNT_SKIP;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Got the controller with pending event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Since global mutex was released, there is a
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * possibility that HBA list has changed, so start
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * over from the top. Just processed controller
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * will be passed-over because of the SKIP flag.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Clear SKIP flag in all controllers */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (sata_hba_inst = sata_hba_list; sata_hba_inst != NULL;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_hba_inst->satahba_event_flags &= ~SATA_EVNT_SKIP;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sata_func_enable & SATA_ENABLE_PROCESS_EVENTS) == 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "SATA EVENTS PROCESSING DISABLED\n");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Go to sleep/suspend itself and wake up either because new event or
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * wait timeout. Exit if there is a termination request (driver
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) cv_timedwait(&sata_event_cv, &sata_event_mutex, lbolt);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Check if it is time to go away */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * It is up to the thread setting above flag to make
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * sure that this thread is not killed prematurely.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Specific HBA instance event processing.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * NOTE: At the moment, device event processing is limited to hard disks
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * cports only are supported - no pmports.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_process_controller_events(sata_hba_inst_t *sata_hba_inst)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Processing controller %d event(s)",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_hba_inst->satahba_event_flags &= ~SATA_EVNT_MAIN;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Process controller power change first
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Search through ports/devices to identify affected port/device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We may have to process events for more than one port/device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown for (ncport = 0; ncport < SATA_NUM_CPORTS(sata_hba_inst); ncport++) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&(SATA_CPORT_MUTEX(sata_hba_inst, ncport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown event_flags = (SATA_CPORT_INFO(sata_hba_inst, ncport))->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Check if port was locked by IOCTL processing */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We ignore port events because port is busy
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * with AP control processing. Set again
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * controller and main event flag, so that
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * events may be processed by the next daemon
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&(SATA_CPORT_MUTEX(sata_hba_inst, ncport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_hba_inst->satahba_event_flags |= SATA_EVNT_MAIN;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Event processing postponed until "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "AP control processing completes",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Check other ports */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set BSY flag so that AP control would not
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * interfere with events processing for
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * this port.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&(SATA_CPORT_MUTEX(sata_hba_inst, ncport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown saddr = &(SATA_CPORT_INFO(sata_hba_inst, ncport))->cport_addr;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (SATA_EVNT_PORT_EVENTS | SATA_EVNT_DRIVE_EVENTS)) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Got port event.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We need some hierarchy of event processing as they
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * are affecting each other:
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * 1. port failed
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * 3. link events - link events may trigger device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * detached or device attached events in some
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * circumstances.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * 4. port power level changed
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* May have device event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&(SATA_CPORT_MUTEX(sata_hba_inst, ncport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Release PORT_BUSY flag */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&(SATA_CPORT_MUTEX(sata_hba_inst, ncport)));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown } /* End of loop through the controller SATA ports */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Process HBA power level change reported by HBA driver.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Not implemented at this time - event is ignored.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_process_cntrl_pwr_level_change(sata_hba_inst_t *sata_hba_inst)
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Ignoring it for now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_hba_inst->satahba_event_flags &= ~SATA_EVNT_PWR_LEVEL_CHANGED;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Process port power level change reported by HBA driver.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Not implemented at this time - event is ignored.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_process_port_pwr_change(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo = SATA_CPORT_INFO(sata_hba_inst, saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Reset event flag */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_event_flags &= ~SATA_EVNT_PWR_LEVEL_CHANGED;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Process port failure reported by HBA driver.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * cports support only - no pmports.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_process_port_failed_event(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo = SATA_CPORT_INFO(sata_hba_inst, saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Reset event flag first */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_event_flags &= ~SATA_EVNT_PORT_FAILED;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* If the port is in SHUTDOWN or FAILED state, ignore this event. */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (SATA_PSTATE_SHUTDOWN | SATA_PSTATE_FAILED)) == 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Fail the port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_log(sata_hba_inst, CE_WARN, "SATA port %d failed", saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Device Reset Event processing.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The seqeunce is managed by 3 stage flags:
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * - reset event reported,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * - reset event being processed,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * - request to clear device reset state.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_process_device_reset(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_drive_info_t old_sdinfo; /* local copy of the drive info */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* We only care about host sata cport for now */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo = SATA_CPORT_INFO(sata_hba_inst, saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* If the port is in SHUTDOWN or FAILED state, ignore reset event. */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (SATA_PSTATE_SHUTDOWN | SATA_PSTATE_FAILED)) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((SATA_CPORT_DEV_TYPE(sata_hba_inst, saddr->cport) &
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo = SATA_CPORT_DRV_INFO(sata_hba_inst, saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (SATA_EVNT_DEVICE_RESET | SATA_EVNT_INPROC_DEVICE_RESET)) == 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Nothing to do */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (SATA_EVNT_DEVICE_RESET | SATA_EVNT_INPROC_DEVICE_RESET)) ==
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (SATA_EVNT_DEVICE_RESET | SATA_EVNT_INPROC_DEVICE_RESET)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Something is weird - new device reset event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Clear event flag */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo->satadrv_event_flags &= ~SATA_EVNT_DEVICE_RESET;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* It seems that we always need to check the port state first */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We have to exit mutex, because the HBA probe port function may
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * block on its own mutex.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Something went wrong? Fail the port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "SATA port %d probing failed",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * No device to process, anymore. Some other event processing
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * would or have already performed port info cleanup.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * To be safe (HBA may need it), request clearing device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * reset condition.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo->satadrv_event_flags |= SATA_EVNT_CLEAR_DEVICE_RESET;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Mark device reset processing as active */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo->satadrv_event_flags |= SATA_EVNT_INPROC_DEVICE_RESET;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown old_sdinfo = *sdinfo; /* local copy of the drive info */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (sata_set_drive_features(sata_hba_inst, &old_sdinfo, 1) ==
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Restoring drive setting failed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Probe the port first, to check if the port state has changed
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* probe port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (SATA_PSTATE_SHUTDOWN | SATA_PSTATE_FAILED)) == 0 &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_PORT_DEVLINK_UP_MASK) == SATA_PORT_DEVLINK_UP &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We may retry this a bit later - in-process reset
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * condition should be already set.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * No point of retrying - some other event processing
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * would or already did port info cleanup.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * To be safe (HBA may need it),
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * request clearing device reset condition.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Raise the flag indicating that the next sata command could
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * be sent with SATA_CLEAR_DEV_RESET_STATE flag, if no new device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * reset is reported.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((cportinfo->cport_dev_type & SATA_VALID_DEV_TYPE) != 0 &&
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo->satadrv_event_flags &= ~SATA_EVNT_INPROC_DEVICE_RESET;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sdinfo->satadrv_event_flags |= SATA_EVNT_CLEAR_DEVICE_RESET;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Port Link Events processing.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Every link established event may involve device reset (due to
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * COMRESET signal, equivalent of the hard reset) so arbitrarily
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * set device reset event for an attached device (if any).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If the port is in SHUTDOWN or FAILED state, ignore link events.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The link established event processing varies, depending on the state
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * of the target node, HBA hotplugging capabilities, state of the port.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If the link is not active, the link established event is ignored.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If HBA cannot detect device attachment and there is no target node,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the link established event triggers device attach event processing.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Else, link established event triggers device reset event processing.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * The link lost event processing varies, depending on a HBA hotplugging
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * capability and the state of the port (link active or not active).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If the link is active, the lost link event is ignored.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If HBA cannot detect device removal, the lost link event triggers
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device detached event processing after link lost timeout.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Else, the event is ignored.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * NOTE: Only cports are processed for now, i.e. no port multiplier ports
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_process_port_link_events(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo = SATA_CPORT_INFO(sata_hba_inst, saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Reset event flags first */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown ~(SATA_EVNT_LINK_ESTABLISHED | SATA_EVNT_LINK_LOST);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* If the port is in SHUTDOWN or FAILED state, ignore link events. */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (SATA_PSTATE_SHUTDOWN | SATA_PSTATE_FAILED)) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * For the sanity sake get current port state.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set device address only. Other sata_device fields should be
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * set by HBA driver.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We have to exit mutex, because the HBA probe port function may
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * block on its own mutex.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Something went wrong? Fail the port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "SATA port %d probing failed",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We may want to release device info structure, but
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * it is not necessary.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* port probed successfully */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_state |= SATA_STATE_PROBED | SATA_STATE_READY;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_PORT_DEVLINK_UP_MASK) != SATA_PORT_DEVLINK_UP) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Ignore event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Ignoring port %d link established event - "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "link down",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Processing port %d link established event",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * For the sanity sake check if a device is attached - check
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * return state of a port probing.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * HBA port probe indicated that there is a device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * attached. Check if the framework had device info
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * structure attached for this device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Dev info structure is present.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If dev_type is set to known type in
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the framework's drive info struct
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * then the device existed before and
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the link was probably lost
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * momentarily - in such case
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * we may want to check device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * identity.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Identity check is not supported now.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Link established event
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * triggers device reset event.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We got new device attached! If HBA does not
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * generate device attached events, trigger it
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Reset link lost timeout */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown SATA_PORT_DEVLINK_UP_MASK) == SATA_PORT_DEVLINK_UP) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Ignore event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Ignoring port %d link lost event - link is up",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Processing port %d link lost event",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * When HBA cannot generate device attached/detached events,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * we need to track link lost time and eventually generate
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device detach event.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (!(SATA_FEATURES(sata_hba_inst) & SATA_CTLF_HOTPLUG)) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* We are tracking link lost time */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* save current time (lbolt value) */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* just keep link lost event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* trigger device detach event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Triggering port %d "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "device detached event",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* keep link lost event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We could change port state to disable/delay access to
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the attached device until the link is recovered.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_hba_inst->satahba_event_flags |= SATA_EVNT_MAIN;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Device Detached Event processing.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Port is probed to find if a device is really gone. If so,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the device info structure is detached from the SATA port info structure
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * and released.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Port status is updated.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * NOTE: Process cports event only, no port multiplier ports.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_process_device_detached(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Processing port %d device detached", saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo = SATA_CPORT_INFO(sata_hba_inst, saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Clear event flag */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_event_flags &= ~SATA_EVNT_DEVICE_DETACHED;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* If the port is in SHUTDOWN or FAILED state, ignore detach event. */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (SATA_PSTATE_SHUTDOWN | SATA_PSTATE_FAILED)) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* For sanity, re-probe the port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We have to exit mutex, because the HBA probe port function may
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * block on its own mutex.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Something went wrong? Fail the port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "SATA port %d probing failed",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We may want to release device info structure, but
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * it is not necessary.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* port probed successfully */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_state |= SATA_STATE_PROBED | SATA_STATE_READY;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Check if a device is still attached. For sanity, check also
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * link status - if no link, there is no device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sata_device.satadev_scr.sstatus & SATA_PORT_DEVLINK_UP_MASK) ==
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Device is still attached - ignore detach event.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Ignoring detach - device still attached to port %d",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We need to detach and release device info structure here
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Device cannot be reached anymore, even if the target node may be
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * still present.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_log(sata_hba_inst, CE_WARN, "SATA device detached at port %d",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Try to offline a device and remove target node if it still exists
2038334ab26baaa43c9083f35def041511c3cc1fUnknown tdip = sata_get_target_dip(SATA_DIP(sata_hba_inst), saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Target node exists. Unconfigure device then remove
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the target node (one ndi operation).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (ndi_devi_offline(tdip, NDI_DEVI_REMOVE) != NDI_SUCCESS) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * PROBLEM - no device, but target node remained
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This happens when the file was open or node was
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * waiting for resources.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_process_device_detached: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Failed to remove target node for "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "detached SATA device."));
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Set target node state to DEVI_DEVICE_REMOVED.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * But re-check first that the node still exists.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Instruct event daemon to retry the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * cleanup later.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Generate sysevent - EC_DR / ESC_DR_AP_STATE_CHANGE
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * with the hint: SE_HINT_REMOVE
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_gen_sysevent(sata_hba_inst, saddr, SE_HINT_REMOVE);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Device Attached Event processing.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Port state is checked to verify that a device is really attached. If so,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the device info structure is created and attached to the SATA port info
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * structure.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If attached device cannot be identified or set-up, the retry for the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * attach processing is set-up. Subsequent daemon run would try again to
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * identify the device, until the time limit is reached
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * (SATA_DEV_IDENTIFY_TIMEOUT).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function cannot be called in interrupt context (it may sleep).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * NOTE: Process cports event only, no port multiplier ports.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_process_device_attached(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Processing port %d device attached", saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo = SATA_CPORT_INFO(sata_hba_inst, saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Clear attach event flag first */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_event_flags &= ~SATA_EVNT_DEVICE_ATTACHED;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* If the port is in SHUTDOWN or FAILED state, ignore event. */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (SATA_PSTATE_SHUTDOWN | SATA_PSTATE_FAILED)) != 0) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If the sata_drive_info structure is found attached to the port info,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * despite the fact the device was removed and now it is re-attached,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * the old drive info structure was not removed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Arbitrarily release device info structure.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* For sanity, re-probe the port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * We have to exit mutex, because the HBA probe port function may
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * block on its own mutex.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Something went wrong? Fail the port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "SATA port %d probing failed",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* port probed successfully */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo->cport_state |= SATA_STATE_PROBED | SATA_STATE_READY;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Check if a device is still attached. For sanity, check also
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * link status - if no link, there is no device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if ((sata_device.satadev_scr.sstatus & SATA_PORT_DEVLINK_UP_MASK) !=
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * No device - ignore attach event.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Ignoring attach - no device connected to port %d",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Generate sysevent - EC_DR / ESC_DR_AP_STATE_CHANGE
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * with the hint: SE_HINT_INSERT
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_gen_sysevent(sata_hba_inst, saddr, SE_HINT_INSERT);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Port reprobing will take care of the creation of the device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * info structure and determination of the device type.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown (void) sata_reprobe_port(sata_hba_inst, &sata_device,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Some device is attached to the port */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown if (cportinfo->cport_dev_type == SATA_DTYPE_UNKNOWN) {
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * A device was not successfully attached.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Track retry time for device identification.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If the retry time limit was not exceeded,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * reinstate attach event.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* OK, restore attach event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Timeout - cannot identify device */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Cannot identify SATA device "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "at port %d - device will not be "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "attached.",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Start tracking time for device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * identification.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Save current time (lbolt value).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Restore attach event */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If device was successfully attached, an explicit
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * 'configure' command will be needed to configure it.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Log the message indicating that a device
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * was attached.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown /* Log device info data */
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Make sure that there is no target node for that
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device. If so, release it. It should not happen,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * unless we had problem removing the node when
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device was detached.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_process_device_attached: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "old device target node exists!");
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * target node exists - try to unconfigure
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * device and remove the node.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * PROBLEM - the target node remained
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * and it belongs to a previously
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * attached device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This happens when the file was open
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * or the node was waiting for
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * resources at the time the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * associated device was removed.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Instruct event daemon to retry the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * cleanup later.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Application(s) accessing "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "previously attached SATA "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "device have to release "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "it before newly inserted "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "device can be made accessible.",
2038334ab26baaa43c9083f35def041511c3cc1fUnknown mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, saddr->cport)->cport_mutex);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_hba_inst->satahba_event_flags |= SATA_EVNT_MAIN;
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Device Target Node Cleanup Event processing.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If the target node associated with a sata port device is in
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * DEVI_DEVICE_REMOVED state, an attempt is made to remove it.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * If the target node cannot be removed, the event flag is left intact,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * so that event daemon may re-run this function later.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * This function cannot be called in interrupt context (it may sleep).
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * NOTE: Processes cport events only, not port multiplier ports.
2038334ab26baaa43c9083f35def041511c3cc1fUnknownsata_process_target_node_cleanup(sata_hba_inst_t *sata_hba_inst,
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "Processing port %d device target node cleanup", saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown cportinfo = SATA_CPORT_INFO(sata_hba_inst, saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Check if there is target node for that device and it is in the
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * DEVI_DEVICE_REMOVED state. If so, release it.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown tdip = sata_get_target_dip(SATA_DIP(sata_hba_inst), saddr->cport);
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * target node exists - check if it is target node of
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * a removed device.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown "sata_process_target_node_cleanup: "
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Unconfigure and remove the target node
2038334ab26baaa43c9083f35def041511c3cc1fUnknown * Event daemon will retry the cleanup later.
2038334ab26baaa43c9083f35def041511c3cc1fUnknown sata_hba_inst->satahba_event_flags |= SATA_EVNT_MAIN;
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelwsata_gen_sysevent(sata_hba_inst_t *sata_hba_inst, sata_address_t *saddr,
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw /* Allocate and build sysevent attribute list */
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw err = nvlist_alloc(&ev_attr_list, NV_UNIQUE_NAME_TYPE, DDI_NOSLEEP);
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw if (err != 0) {
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw "sata_gen_sysevent: "
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw "cannot allocate memory for sysevent attributes\n"));
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw /* Add hint attribute */
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw err = nvlist_add_string(ev_attr_list, DR_HINT, SE_HINT2STR(hint));
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw if (err != 0) {
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw "sata_gen_sysevent: "
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw "failed to add DR_HINT attr for sysevent"));
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * Add AP attribute.
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * Get controller pathname and convert it into AP pathname by adding
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw * a target number.
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw (void) ddi_pathname(SATA_DIP(sata_hba_inst), ap + strlen(ap));
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw (void) snprintf(ap + strlen(ap), MAXPATHLEN - strlen(ap), ":%d",
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw SATA_MAKE_AP_NUMBER(saddr->cport, saddr->pmport, saddr->qual));
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw if (err != 0) {
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw "sata_gen_sysevent: "
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw "failed to add DR_AP_ID attr for sysevent"));
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw /* Generate/log sysevent */
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw err = ddi_log_sysevent(SATA_DIP(sata_hba_inst), DDI_VENDOR_SUNW, EC_DR,
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw ESC_DR_AP_STATE_CHANGE, ev_attr_list, NULL, DDI_NOSLEEP);
f76ee27a7c2e4dbe22aec6ce187c04e980f90349pawelw "sata_gen_sysevent: "
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Set DEVI_DEVICE_REMOVED state in the SATA device target node.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Set internal event instructing event daemon to try
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * to perform the target node cleanup.
4360436b3c604bc28d37be269ad152b4c38157c3pawelwsata_set_target_node_cleanup(sata_hba_inst_t *sata_hba_inst, int cport)
4360436b3c604bc28d37be269ad152b4c38157c3pawelw mutex_enter(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
4360436b3c604bc28d37be269ad152b4c38157c3pawelw SATA_CPORT_INFO(sata_hba_inst, cport)->cport_tgtnode_clean = B_FALSE;
4360436b3c604bc28d37be269ad152b4c38157c3pawelw mutex_exit(&SATA_CPORT_INFO(sata_hba_inst, cport)->cport_mutex);
4360436b3c604bc28d37be269ad152b4c38157c3pawelw sata_hba_inst->satahba_event_flags |= SATA_EVNT_MAIN;
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Check if the SATA device target node is in DEVI_DEVICE_REMOVED state,
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * i.e. check if the target node state indicates that it belongs to a removed
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * Returns B_TRUE if the target node is in DEVI_DEVICE_REMOVED state,
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * B_FALSE otherwise.
4360436b3c604bc28d37be269ad152b4c38157c3pawelw * NOTE: No port multiplier support.