177d89b08766c878a2594b15d203e513acf952340wwang/* Driver for Realtek PCI-Express card reader 277d89b08766c878a2594b15d203e513acf952340wwang * 377d89b08766c878a2594b15d203e513acf952340wwang * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. 477d89b08766c878a2594b15d203e513acf952340wwang * 577d89b08766c878a2594b15d203e513acf952340wwang * This program is free software; you can redistribute it and/or modify it 677d89b08766c878a2594b15d203e513acf952340wwang * under the terms of the GNU General Public License as published by the 777d89b08766c878a2594b15d203e513acf952340wwang * Free Software Foundation; either version 2, or (at your option) any 877d89b08766c878a2594b15d203e513acf952340wwang * later version. 977d89b08766c878a2594b15d203e513acf952340wwang * 1077d89b08766c878a2594b15d203e513acf952340wwang * This program is distributed in the hope that it will be useful, but 1177d89b08766c878a2594b15d203e513acf952340wwang * WITHOUT ANY WARRANTY; without even the implied warranty of 1277d89b08766c878a2594b15d203e513acf952340wwang * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1377d89b08766c878a2594b15d203e513acf952340wwang * General Public License for more details. 1477d89b08766c878a2594b15d203e513acf952340wwang * 1577d89b08766c878a2594b15d203e513acf952340wwang * You should have received a copy of the GNU General Public License along 1677d89b08766c878a2594b15d203e513acf952340wwang * with this program; if not, see <http://www.gnu.org/licenses/>. 1777d89b08766c878a2594b15d203e513acf952340wwang * 1877d89b08766c878a2594b15d203e513acf952340wwang * Author: 1977d89b08766c878a2594b15d203e513acf952340wwang * wwang (wei_wang@realsil.com.cn) 2077d89b08766c878a2594b15d203e513acf952340wwang * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China 2177d89b08766c878a2594b15d203e513acf952340wwang */ 2277d89b08766c878a2594b15d203e513acf952340wwang 2377d89b08766c878a2594b15d203e513acf952340wwang#include <linux/blkdev.h> 2477d89b08766c878a2594b15d203e513acf952340wwang#include <linux/kthread.h> 2577d89b08766c878a2594b15d203e513acf952340wwang#include <linux/sched.h> 26c6cdaded146875e2e47e946f6592c1775eaee849Jeff Mahoney#include <linux/vmalloc.h> 2777d89b08766c878a2594b15d203e513acf952340wwang 2877d89b08766c878a2594b15d203e513acf952340wwang#include "rtsx.h" 2977d89b08766c878a2594b15d203e513acf952340wwang#include "rtsx_transport.h" 3077d89b08766c878a2594b15d203e513acf952340wwang#include "rtsx_sys.h" 3177d89b08766c878a2594b15d203e513acf952340wwang#include "rtsx_card.h" 3277d89b08766c878a2594b15d203e513acf952340wwang#include "rtsx_chip.h" 3377d89b08766c878a2594b15d203e513acf952340wwang#include "rtsx_scsi.h" 3477d89b08766c878a2594b15d203e513acf952340wwang#include "sd.h" 3577d89b08766c878a2594b15d203e513acf952340wwang#include "ms.h" 3677d89b08766c878a2594b15d203e513acf952340wwang#include "spi.h" 3777d89b08766c878a2594b15d203e513acf952340wwang 3877d89b08766c878a2594b15d203e513acf952340wwangvoid scsi_show_command(struct scsi_cmnd *srb) 3977d89b08766c878a2594b15d203e513acf952340wwang{ 4077d89b08766c878a2594b15d203e513acf952340wwang char *what = NULL; 4177d89b08766c878a2594b15d203e513acf952340wwang int i, unknown_cmd = 0; 4277d89b08766c878a2594b15d203e513acf952340wwang 4377d89b08766c878a2594b15d203e513acf952340wwang switch (srb->cmnd[0]) { 4477d89b08766c878a2594b15d203e513acf952340wwang case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break; 4577d89b08766c878a2594b15d203e513acf952340wwang case REZERO_UNIT: what = "REZERO_UNIT"; break; 4677d89b08766c878a2594b15d203e513acf952340wwang case REQUEST_SENSE: what = "REQUEST_SENSE"; break; 4777d89b08766c878a2594b15d203e513acf952340wwang case FORMAT_UNIT: what = "FORMAT_UNIT"; break; 4877d89b08766c878a2594b15d203e513acf952340wwang case READ_BLOCK_LIMITS: what = "READ_BLOCK_LIMITS"; break; 4977d89b08766c878a2594b15d203e513acf952340wwang case REASSIGN_BLOCKS: what = "REASSIGN_BLOCKS"; break; 5077d89b08766c878a2594b15d203e513acf952340wwang case READ_6: what = "READ_6"; break; 5177d89b08766c878a2594b15d203e513acf952340wwang case WRITE_6: what = "WRITE_6"; break; 5277d89b08766c878a2594b15d203e513acf952340wwang case SEEK_6: what = "SEEK_6"; break; 5377d89b08766c878a2594b15d203e513acf952340wwang case READ_REVERSE: what = "READ_REVERSE"; break; 5477d89b08766c878a2594b15d203e513acf952340wwang case WRITE_FILEMARKS: what = "WRITE_FILEMARKS"; break; 5577d89b08766c878a2594b15d203e513acf952340wwang case SPACE: what = "SPACE"; break; 5677d89b08766c878a2594b15d203e513acf952340wwang case INQUIRY: what = "INQUIRY"; break; 5777d89b08766c878a2594b15d203e513acf952340wwang case RECOVER_BUFFERED_DATA: what = "RECOVER_BUFFERED_DATA"; break; 5877d89b08766c878a2594b15d203e513acf952340wwang case MODE_SELECT: what = "MODE_SELECT"; break; 5977d89b08766c878a2594b15d203e513acf952340wwang case RESERVE: what = "RESERVE"; break; 6077d89b08766c878a2594b15d203e513acf952340wwang case RELEASE: what = "RELEASE"; break; 6177d89b08766c878a2594b15d203e513acf952340wwang case COPY: what = "COPY"; break; 6277d89b08766c878a2594b15d203e513acf952340wwang case ERASE: what = "ERASE"; break; 6377d89b08766c878a2594b15d203e513acf952340wwang case MODE_SENSE: what = "MODE_SENSE"; break; 6477d89b08766c878a2594b15d203e513acf952340wwang case START_STOP: what = "START_STOP"; break; 6577d89b08766c878a2594b15d203e513acf952340wwang case RECEIVE_DIAGNOSTIC: what = "RECEIVE_DIAGNOSTIC"; break; 6677d89b08766c878a2594b15d203e513acf952340wwang case SEND_DIAGNOSTIC: what = "SEND_DIAGNOSTIC"; break; 6777d89b08766c878a2594b15d203e513acf952340wwang case ALLOW_MEDIUM_REMOVAL: what = "ALLOW_MEDIUM_REMOVAL"; break; 6877d89b08766c878a2594b15d203e513acf952340wwang case SET_WINDOW: what = "SET_WINDOW"; break; 6977d89b08766c878a2594b15d203e513acf952340wwang case READ_CAPACITY: what = "READ_CAPACITY"; break; 7077d89b08766c878a2594b15d203e513acf952340wwang case READ_10: what = "READ_10"; break; 7177d89b08766c878a2594b15d203e513acf952340wwang case WRITE_10: what = "WRITE_10"; break; 7277d89b08766c878a2594b15d203e513acf952340wwang case SEEK_10: what = "SEEK_10"; break; 7377d89b08766c878a2594b15d203e513acf952340wwang case WRITE_VERIFY: what = "WRITE_VERIFY"; break; 7477d89b08766c878a2594b15d203e513acf952340wwang case VERIFY: what = "VERIFY"; break; 7577d89b08766c878a2594b15d203e513acf952340wwang case SEARCH_HIGH: what = "SEARCH_HIGH"; break; 7677d89b08766c878a2594b15d203e513acf952340wwang case SEARCH_EQUAL: what = "SEARCH_EQUAL"; break; 7777d89b08766c878a2594b15d203e513acf952340wwang case SEARCH_LOW: what = "SEARCH_LOW"; break; 7877d89b08766c878a2594b15d203e513acf952340wwang case SET_LIMITS: what = "SET_LIMITS"; break; 7977d89b08766c878a2594b15d203e513acf952340wwang case READ_POSITION: what = "READ_POSITION"; break; 8077d89b08766c878a2594b15d203e513acf952340wwang case SYNCHRONIZE_CACHE: what = "SYNCHRONIZE_CACHE"; break; 8177d89b08766c878a2594b15d203e513acf952340wwang case LOCK_UNLOCK_CACHE: what = "LOCK_UNLOCK_CACHE"; break; 8277d89b08766c878a2594b15d203e513acf952340wwang case READ_DEFECT_DATA: what = "READ_DEFECT_DATA"; break; 8377d89b08766c878a2594b15d203e513acf952340wwang case MEDIUM_SCAN: what = "MEDIUM_SCAN"; break; 8477d89b08766c878a2594b15d203e513acf952340wwang case COMPARE: what = "COMPARE"; break; 8577d89b08766c878a2594b15d203e513acf952340wwang case COPY_VERIFY: what = "COPY_VERIFY"; break; 8677d89b08766c878a2594b15d203e513acf952340wwang case WRITE_BUFFER: what = "WRITE_BUFFER"; break; 8777d89b08766c878a2594b15d203e513acf952340wwang case READ_BUFFER: what = "READ_BUFFER"; break; 8877d89b08766c878a2594b15d203e513acf952340wwang case UPDATE_BLOCK: what = "UPDATE_BLOCK"; break; 8977d89b08766c878a2594b15d203e513acf952340wwang case READ_LONG: what = "READ_LONG"; break; 9077d89b08766c878a2594b15d203e513acf952340wwang case WRITE_LONG: what = "WRITE_LONG"; break; 9177d89b08766c878a2594b15d203e513acf952340wwang case CHANGE_DEFINITION: what = "CHANGE_DEFINITION"; break; 9277d89b08766c878a2594b15d203e513acf952340wwang case WRITE_SAME: what = "WRITE_SAME"; break; 9377d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_READ_SUBCHANNEL: what = "READ SUBCHANNEL"; break; 9477d89b08766c878a2594b15d203e513acf952340wwang case READ_TOC: what = "READ_TOC"; break; 9577d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_READ_HEADER: what = "READ HEADER"; break; 9677d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_PLAY_AUDIO_10: what = "PLAY AUDIO (10)"; break; 9777d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_PLAY_AUDIO_MSF: what = "PLAY AUDIO MSF"; break; 9877d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_GET_EVENT_STATUS_NOTIFICATION: 9977d89b08766c878a2594b15d203e513acf952340wwang what = "GET EVENT/STATUS NOTIFICATION"; break; 10077d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_PAUSE_RESUME: what = "PAUSE/RESUME"; break; 10177d89b08766c878a2594b15d203e513acf952340wwang case LOG_SELECT: what = "LOG_SELECT"; break; 10277d89b08766c878a2594b15d203e513acf952340wwang case LOG_SENSE: what = "LOG_SENSE"; break; 10377d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_STOP_PLAY_SCAN: what = "STOP PLAY/SCAN"; break; 10477d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_READ_DISC_INFO: what = "READ DISC INFORMATION"; break; 10577d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_READ_TRACK_RZONE_INFO: 10677d89b08766c878a2594b15d203e513acf952340wwang what = "READ TRACK INFORMATION"; break; 10777d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_RESERVE_RZONE_TRACK: what = "RESERVE TRACK"; break; 10877d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_SEND_OPC: what = "SEND OPC"; break; 10977d89b08766c878a2594b15d203e513acf952340wwang case MODE_SELECT_10: what = "MODE_SELECT_10"; break; 11077d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_REPAIR_RZONE_TRACK: what = "REPAIR TRACK"; break; 11177d89b08766c878a2594b15d203e513acf952340wwang case 0x59: what = "READ MASTER CUE"; break; 11277d89b08766c878a2594b15d203e513acf952340wwang case MODE_SENSE_10: what = "MODE_SENSE_10"; break; 11377d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_CLOSE_TRACK: what = "CLOSE TRACK/SESSION"; break; 11477d89b08766c878a2594b15d203e513acf952340wwang case 0x5C: what = "READ BUFFER CAPACITY"; break; 11577d89b08766c878a2594b15d203e513acf952340wwang case 0x5D: what = "SEND CUE SHEET"; break; 11677d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_BLANK: what = "BLANK"; break; 11777d89b08766c878a2594b15d203e513acf952340wwang case REPORT_LUNS: what = "REPORT LUNS"; break; 11877d89b08766c878a2594b15d203e513acf952340wwang case MOVE_MEDIUM: what = "MOVE_MEDIUM or PLAY AUDIO (12)"; break; 11977d89b08766c878a2594b15d203e513acf952340wwang case READ_12: what = "READ_12"; break; 12077d89b08766c878a2594b15d203e513acf952340wwang case WRITE_12: what = "WRITE_12"; break; 12177d89b08766c878a2594b15d203e513acf952340wwang case WRITE_VERIFY_12: what = "WRITE_VERIFY_12"; break; 12277d89b08766c878a2594b15d203e513acf952340wwang case SEARCH_HIGH_12: what = "SEARCH_HIGH_12"; break; 12377d89b08766c878a2594b15d203e513acf952340wwang case SEARCH_EQUAL_12: what = "SEARCH_EQUAL_12"; break; 12477d89b08766c878a2594b15d203e513acf952340wwang case SEARCH_LOW_12: what = "SEARCH_LOW_12"; break; 12577d89b08766c878a2594b15d203e513acf952340wwang case SEND_VOLUME_TAG: what = "SEND_VOLUME_TAG"; break; 12677d89b08766c878a2594b15d203e513acf952340wwang case READ_ELEMENT_STATUS: what = "READ_ELEMENT_STATUS"; break; 12777d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_READ_CD_MSF: what = "READ CD MSF"; break; 12877d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_SCAN: what = "SCAN"; break; 12977d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_SET_SPEED: what = "SET CD SPEED"; break; 13077d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_MECHANISM_STATUS: what = "MECHANISM STATUS"; break; 13177d89b08766c878a2594b15d203e513acf952340wwang case GPCMD_READ_CD: what = "READ CD"; break; 13277d89b08766c878a2594b15d203e513acf952340wwang case 0xE1: what = "WRITE CONTINUE"; break; 13377d89b08766c878a2594b15d203e513acf952340wwang case WRITE_LONG_2: what = "WRITE_LONG_2"; break; 13477d89b08766c878a2594b15d203e513acf952340wwang case VENDOR_CMND: what = "Realtek's vendor command"; break; 13577d89b08766c878a2594b15d203e513acf952340wwang default: what = "(unknown command)"; unknown_cmd = 1; break; 13677d89b08766c878a2594b15d203e513acf952340wwang } 13777d89b08766c878a2594b15d203e513acf952340wwang 13877d89b08766c878a2594b15d203e513acf952340wwang if (srb->cmnd[0] != TEST_UNIT_READY) { 13977d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len); 14077d89b08766c878a2594b15d203e513acf952340wwang } 14177d89b08766c878a2594b15d203e513acf952340wwang if (unknown_cmd) { 14277d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP(""); 14377d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < srb->cmd_len && i < 16; i++) 14477d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGPN(" %02x", srb->cmnd[i]); 14577d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGPN("\n"); 14677d89b08766c878a2594b15d203e513acf952340wwang } 14777d89b08766c878a2594b15d203e513acf952340wwang} 14877d89b08766c878a2594b15d203e513acf952340wwang 14977d89b08766c878a2594b15d203e513acf952340wwangvoid set_sense_type(struct rtsx_chip *chip, unsigned int lun, int sense_type) 15077d89b08766c878a2594b15d203e513acf952340wwang{ 15177d89b08766c878a2594b15d203e513acf952340wwang switch (sense_type) { 15277d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MEDIA_CHANGE: 15377d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0); 15477d89b08766c878a2594b15d203e513acf952340wwang break; 15577d89b08766c878a2594b15d203e513acf952340wwang 15677d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MEDIA_NOT_PRESENT: 15777d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0); 15877d89b08766c878a2594b15d203e513acf952340wwang break; 15977d89b08766c878a2594b15d203e513acf952340wwang 16077d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MEDIA_LBA_OVER_RANGE: 16177d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0); 16277d89b08766c878a2594b15d203e513acf952340wwang break; 16377d89b08766c878a2594b15d203e513acf952340wwang 16477d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT: 16577d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0); 16677d89b08766c878a2594b15d203e513acf952340wwang break; 16777d89b08766c878a2594b15d203e513acf952340wwang 16877d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MEDIA_WRITE_PROTECT: 16977d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0); 17077d89b08766c878a2594b15d203e513acf952340wwang break; 17177d89b08766c878a2594b15d203e513acf952340wwang 17277d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR: 17377d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0); 17477d89b08766c878a2594b15d203e513acf952340wwang break; 17577d89b08766c878a2594b15d203e513acf952340wwang 17677d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MEDIA_WRITE_ERR: 17777d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0); 17877d89b08766c878a2594b15d203e513acf952340wwang break; 17977d89b08766c878a2594b15d203e513acf952340wwang 18077d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD: 18177d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0, 18277d89b08766c878a2594b15d203e513acf952340wwang ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1); 18377d89b08766c878a2594b15d203e513acf952340wwang break; 18477d89b08766c878a2594b15d203e513acf952340wwang 18577d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_FORMAT_IN_PROGRESS: 18677d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0); 18777d89b08766c878a2594b15d203e513acf952340wwang break; 18877d89b08766c878a2594b15d203e513acf952340wwang 18977d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_FORMAT_CMD_FAILED: 19077d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0); 19177d89b08766c878a2594b15d203e513acf952340wwang break; 19277d89b08766c878a2594b15d203e513acf952340wwang 19377d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_MAGIC_GATE 19477d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB: 19577d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0); 19677d89b08766c878a2594b15d203e513acf952340wwang break; 19777d89b08766c878a2594b15d203e513acf952340wwang 19877d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN: 19977d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0); 20077d89b08766c878a2594b15d203e513acf952340wwang break; 20177d89b08766c878a2594b15d203e513acf952340wwang 20277d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM: 20377d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0); 20477d89b08766c878a2594b15d203e513acf952340wwang break; 20577d89b08766c878a2594b15d203e513acf952340wwang 20677d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MG_WRITE_ERR: 20777d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0); 20877d89b08766c878a2594b15d203e513acf952340wwang break; 20977d89b08766c878a2594b15d203e513acf952340wwang#endif 21077d89b08766c878a2594b15d203e513acf952340wwang 21177d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_SD_LOCK 21277d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_MEDIA_READ_FORBIDDEN: 21377d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0); 21477d89b08766c878a2594b15d203e513acf952340wwang break; 21577d89b08766c878a2594b15d203e513acf952340wwang#endif 21677d89b08766c878a2594b15d203e513acf952340wwang 21777d89b08766c878a2594b15d203e513acf952340wwang case SENSE_TYPE_NO_SENSE: 21877d89b08766c878a2594b15d203e513acf952340wwang default: 21977d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); 22077d89b08766c878a2594b15d203e513acf952340wwang break; 22177d89b08766c878a2594b15d203e513acf952340wwang } 22277d89b08766c878a2594b15d203e513acf952340wwang} 22377d89b08766c878a2594b15d203e513acf952340wwang 22477d89b08766c878a2594b15d203e513acf952340wwangvoid set_sense_data(struct rtsx_chip *chip, unsigned int lun, u8 err_code, u8 sense_key, 22577d89b08766c878a2594b15d203e513acf952340wwang u32 info, u8 asc, u8 ascq, u8 sns_key_info0, u16 sns_key_info1) 22677d89b08766c878a2594b15d203e513acf952340wwang{ 22777d89b08766c878a2594b15d203e513acf952340wwang struct sense_data_t *sense = &(chip->sense_buffer[lun]); 22877d89b08766c878a2594b15d203e513acf952340wwang 22977d89b08766c878a2594b15d203e513acf952340wwang sense->err_code = err_code; 23077d89b08766c878a2594b15d203e513acf952340wwang sense->sense_key = sense_key; 23177d89b08766c878a2594b15d203e513acf952340wwang sense->info[0] = (u8)(info >> 24); 23277d89b08766c878a2594b15d203e513acf952340wwang sense->info[1] = (u8)(info >> 16); 23377d89b08766c878a2594b15d203e513acf952340wwang sense->info[2] = (u8)(info >> 8); 23477d89b08766c878a2594b15d203e513acf952340wwang sense->info[3] = (u8)info; 23577d89b08766c878a2594b15d203e513acf952340wwang 23677d89b08766c878a2594b15d203e513acf952340wwang sense->ad_sense_len = sizeof(struct sense_data_t) - 8; 23777d89b08766c878a2594b15d203e513acf952340wwang sense->asc = asc; 23877d89b08766c878a2594b15d203e513acf952340wwang sense->ascq = ascq; 23977d89b08766c878a2594b15d203e513acf952340wwang if (sns_key_info0 != 0) { 24077d89b08766c878a2594b15d203e513acf952340wwang sense->sns_key_info[0] = SKSV | sns_key_info0; 24177d89b08766c878a2594b15d203e513acf952340wwang sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 8; 24277d89b08766c878a2594b15d203e513acf952340wwang sense->sns_key_info[2] = sns_key_info1 & 0x0f; 24377d89b08766c878a2594b15d203e513acf952340wwang } 24477d89b08766c878a2594b15d203e513acf952340wwang} 24577d89b08766c878a2594b15d203e513acf952340wwang 24677d89b08766c878a2594b15d203e513acf952340wwangstatic int test_unit_ready(struct scsi_cmnd *srb, struct rtsx_chip *chip) 24777d89b08766c878a2594b15d203e513acf952340wwang{ 24877d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 24977d89b08766c878a2594b15d203e513acf952340wwang 25077d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun)) { 25177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 25277d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_FAILED; 25377d89b08766c878a2594b15d203e513acf952340wwang } 25477d89b08766c878a2594b15d203e513acf952340wwang 25577d89b08766c878a2594b15d203e513acf952340wwang if (!(CHK_BIT(chip->lun_mc, lun))) { 25677d89b08766c878a2594b15d203e513acf952340wwang SET_BIT(chip->lun_mc, lun); 25777d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); 25877d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_FAILED; 25977d89b08766c878a2594b15d203e513acf952340wwang } 26077d89b08766c878a2594b15d203e513acf952340wwang 26177d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_SD_LOCK 26277d89b08766c878a2594b15d203e513acf952340wwang if (get_lun_card(chip, SCSI_LUN(srb)) == SD_CARD) { 26377d89b08766c878a2594b15d203e513acf952340wwang struct sd_info *sd_card = &(chip->sd_card); 26477d89b08766c878a2594b15d203e513acf952340wwang if (sd_card->sd_lock_notify) { 26577d89b08766c878a2594b15d203e513acf952340wwang sd_card->sd_lock_notify = 0; 26677d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); 26777d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_FAILED; 26877d89b08766c878a2594b15d203e513acf952340wwang } else if (sd_card->sd_lock_status & SD_LOCKED) { 26977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); 27077d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_FAILED; 27177d89b08766c878a2594b15d203e513acf952340wwang } 27277d89b08766c878a2594b15d203e513acf952340wwang } 27377d89b08766c878a2594b15d203e513acf952340wwang#endif 27477d89b08766c878a2594b15d203e513acf952340wwang 27577d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 27677d89b08766c878a2594b15d203e513acf952340wwang} 27777d89b08766c878a2594b15d203e513acf952340wwang 2786680d2cab316a0c0e4cea0727e6d63426a77bb12wwangstatic unsigned char formatter_inquiry_str[20] = { 27977d89b08766c878a2594b15d203e513acf952340wwang 'M', 'E', 'M', 'O', 'R', 'Y', 'S', 'T', 'I', 'C', 'K', 28077d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_MAGIC_GATE 28177d89b08766c878a2594b15d203e513acf952340wwang '-', 'M', 'G', /* Byte[47:49] */ 28277d89b08766c878a2594b15d203e513acf952340wwang#else 28377d89b08766c878a2594b15d203e513acf952340wwang 0x20, 0x20, 0x20, /* Byte[47:49] */ 28477d89b08766c878a2594b15d203e513acf952340wwang#endif 28577d89b08766c878a2594b15d203e513acf952340wwang 28677d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_MAGIC_GATE 28777d89b08766c878a2594b15d203e513acf952340wwang 0x0B, /* Byte[50]: MG, MS, MSPro, MSXC */ 28877d89b08766c878a2594b15d203e513acf952340wwang#else 28977d89b08766c878a2594b15d203e513acf952340wwang 0x09, /* Byte[50]: MS, MSPro, MSXC */ 29077d89b08766c878a2594b15d203e513acf952340wwang#endif 29177d89b08766c878a2594b15d203e513acf952340wwang 0x00, /* Byte[51]: Category Specific Commands */ 29277d89b08766c878a2594b15d203e513acf952340wwang 0x00, /* Byte[52]: Access Control and feature */ 29377d89b08766c878a2594b15d203e513acf952340wwang 0x20, 0x20, 0x20, /* Byte[53:55] */ 29477d89b08766c878a2594b15d203e513acf952340wwang}; 29577d89b08766c878a2594b15d203e513acf952340wwang 29677d89b08766c878a2594b15d203e513acf952340wwangstatic int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) 29777d89b08766c878a2594b15d203e513acf952340wwang{ 29877d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 29977d89b08766c878a2594b15d203e513acf952340wwang char *inquiry_default = (char *)"Generic-xD/SD/M.S. 1.00 "; 30077d89b08766c878a2594b15d203e513acf952340wwang char *inquiry_sdms = (char *)"Generic-SD/MemoryStick 1.00 "; 30177d89b08766c878a2594b15d203e513acf952340wwang char *inquiry_sd = (char *)"Generic-SD/MMC 1.00 "; 30277d89b08766c878a2594b15d203e513acf952340wwang char *inquiry_ms = (char *)"Generic-MemoryStick 1.00 "; 30377d89b08766c878a2594b15d203e513acf952340wwang char *inquiry_string; 30477d89b08766c878a2594b15d203e513acf952340wwang unsigned char sendbytes; 30577d89b08766c878a2594b15d203e513acf952340wwang unsigned char *buf; 30677d89b08766c878a2594b15d203e513acf952340wwang u8 card = get_lun_card(chip, lun); 30777d89b08766c878a2594b15d203e513acf952340wwang int pro_formatter_flag = 0; 30877d89b08766c878a2594b15d203e513acf952340wwang unsigned char inquiry_buf[] = { 30977d89b08766c878a2594b15d203e513acf952340wwang QULIFIRE|DRCT_ACCESS_DEV, 31077d89b08766c878a2594b15d203e513acf952340wwang RMB_DISC|0x0D, 31177d89b08766c878a2594b15d203e513acf952340wwang 0x00, 31277d89b08766c878a2594b15d203e513acf952340wwang 0x01, 31377d89b08766c878a2594b15d203e513acf952340wwang 0x1f, 31477d89b08766c878a2594b15d203e513acf952340wwang 0x02, 31577d89b08766c878a2594b15d203e513acf952340wwang 0, 31677d89b08766c878a2594b15d203e513acf952340wwang REL_ADR|WBUS_32|WBUS_16|SYNC|LINKED|CMD_QUE|SFT_RE, 31777d89b08766c878a2594b15d203e513acf952340wwang }; 31877d89b08766c878a2594b15d203e513acf952340wwang 31977d89b08766c878a2594b15d203e513acf952340wwang if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { 32077d89b08766c878a2594b15d203e513acf952340wwang if (chip->lun2card[lun] == SD_CARD) { 32177d89b08766c878a2594b15d203e513acf952340wwang inquiry_string = inquiry_sd; 32277d89b08766c878a2594b15d203e513acf952340wwang } else { 32377d89b08766c878a2594b15d203e513acf952340wwang inquiry_string = inquiry_ms; 32477d89b08766c878a2594b15d203e513acf952340wwang } 32577d89b08766c878a2594b15d203e513acf952340wwang } else if (CHECK_LUN_MODE(chip, SD_MS_1LUN)) { 32677d89b08766c878a2594b15d203e513acf952340wwang inquiry_string = inquiry_sdms; 32777d89b08766c878a2594b15d203e513acf952340wwang } else { 32877d89b08766c878a2594b15d203e513acf952340wwang inquiry_string = inquiry_default; 32977d89b08766c878a2594b15d203e513acf952340wwang } 33077d89b08766c878a2594b15d203e513acf952340wwang 33177d89b08766c878a2594b15d203e513acf952340wwang buf = vmalloc(scsi_bufflen(srb)); 33277d89b08766c878a2594b15d203e513acf952340wwang if (buf == NULL) { 33377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 33477d89b08766c878a2594b15d203e513acf952340wwang } 33577d89b08766c878a2594b15d203e513acf952340wwang 33677d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_MAGIC_GATE 33777d89b08766c878a2594b15d203e513acf952340wwang if ((chip->mspro_formatter_enable) && 33877d89b08766c878a2594b15d203e513acf952340wwang (chip->lun2card[lun] & MS_CARD)) 33977d89b08766c878a2594b15d203e513acf952340wwang#else 34077d89b08766c878a2594b15d203e513acf952340wwang if (chip->mspro_formatter_enable) 34177d89b08766c878a2594b15d203e513acf952340wwang#endif 34277d89b08766c878a2594b15d203e513acf952340wwang { 34377d89b08766c878a2594b15d203e513acf952340wwang if (!card || (card == MS_CARD)) { 34477d89b08766c878a2594b15d203e513acf952340wwang pro_formatter_flag = 1; 34577d89b08766c878a2594b15d203e513acf952340wwang } 34677d89b08766c878a2594b15d203e513acf952340wwang } 34777d89b08766c878a2594b15d203e513acf952340wwang 34877d89b08766c878a2594b15d203e513acf952340wwang if (pro_formatter_flag) { 34977d89b08766c878a2594b15d203e513acf952340wwang if (scsi_bufflen(srb) < 56) { 35077d89b08766c878a2594b15d203e513acf952340wwang sendbytes = (unsigned char)(scsi_bufflen(srb)); 35177d89b08766c878a2594b15d203e513acf952340wwang } else { 35277d89b08766c878a2594b15d203e513acf952340wwang sendbytes = 56; 35377d89b08766c878a2594b15d203e513acf952340wwang } 35477d89b08766c878a2594b15d203e513acf952340wwang } else { 35577d89b08766c878a2594b15d203e513acf952340wwang if (scsi_bufflen(srb) < 36) { 35677d89b08766c878a2594b15d203e513acf952340wwang sendbytes = (unsigned char)(scsi_bufflen(srb)); 35777d89b08766c878a2594b15d203e513acf952340wwang } else { 35877d89b08766c878a2594b15d203e513acf952340wwang sendbytes = 36; 35977d89b08766c878a2594b15d203e513acf952340wwang } 36077d89b08766c878a2594b15d203e513acf952340wwang } 36177d89b08766c878a2594b15d203e513acf952340wwang 36277d89b08766c878a2594b15d203e513acf952340wwang if (sendbytes > 8) { 36377d89b08766c878a2594b15d203e513acf952340wwang memcpy(buf, inquiry_buf, 8); 36477d89b08766c878a2594b15d203e513acf952340wwang memcpy(buf + 8, inquiry_string, sendbytes - 8); 36577d89b08766c878a2594b15d203e513acf952340wwang if (pro_formatter_flag) { 36677d89b08766c878a2594b15d203e513acf952340wwang /* Additional Length */ 36777d89b08766c878a2594b15d203e513acf952340wwang buf[4] = 0x33; 36877d89b08766c878a2594b15d203e513acf952340wwang } 36977d89b08766c878a2594b15d203e513acf952340wwang } else { 37077d89b08766c878a2594b15d203e513acf952340wwang memcpy(buf, inquiry_buf, sendbytes); 37177d89b08766c878a2594b15d203e513acf952340wwang } 37277d89b08766c878a2594b15d203e513acf952340wwang 37377d89b08766c878a2594b15d203e513acf952340wwang if (pro_formatter_flag) { 37477d89b08766c878a2594b15d203e513acf952340wwang if (sendbytes > 36) { 37577d89b08766c878a2594b15d203e513acf952340wwang memcpy(buf + 36, formatter_inquiry_str, sendbytes - 36); 37677d89b08766c878a2594b15d203e513acf952340wwang } 37777d89b08766c878a2594b15d203e513acf952340wwang } 37877d89b08766c878a2594b15d203e513acf952340wwang 37977d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 38077d89b08766c878a2594b15d203e513acf952340wwang 38177d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); 38277d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 38377d89b08766c878a2594b15d203e513acf952340wwang 38477d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 38577d89b08766c878a2594b15d203e513acf952340wwang} 38677d89b08766c878a2594b15d203e513acf952340wwang 38777d89b08766c878a2594b15d203e513acf952340wwang 38877d89b08766c878a2594b15d203e513acf952340wwangstatic int start_stop_unit(struct scsi_cmnd *srb, struct rtsx_chip *chip) 38977d89b08766c878a2594b15d203e513acf952340wwang{ 39077d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 39177d89b08766c878a2594b15d203e513acf952340wwang 39277d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb)); 39377d89b08766c878a2594b15d203e513acf952340wwang 39477d89b08766c878a2594b15d203e513acf952340wwang if (srb->cmnd[1] == 1) 39577d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 39677d89b08766c878a2594b15d203e513acf952340wwang 39777d89b08766c878a2594b15d203e513acf952340wwang switch (srb->cmnd[0x4]) { 39877d89b08766c878a2594b15d203e513acf952340wwang case STOP_MEDIUM: 39977d89b08766c878a2594b15d203e513acf952340wwang /* Media disabled */ 40077d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 40177d89b08766c878a2594b15d203e513acf952340wwang 40277d89b08766c878a2594b15d203e513acf952340wwang case UNLOAD_MEDIUM: 40377d89b08766c878a2594b15d203e513acf952340wwang /* Media shall be unload */ 40477d89b08766c878a2594b15d203e513acf952340wwang if (check_card_ready(chip, lun)) 40577d89b08766c878a2594b15d203e513acf952340wwang eject_card(chip, lun); 40677d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 40777d89b08766c878a2594b15d203e513acf952340wwang 40877d89b08766c878a2594b15d203e513acf952340wwang case MAKE_MEDIUM_READY: 40977d89b08766c878a2594b15d203e513acf952340wwang case LOAD_MEDIUM: 41077d89b08766c878a2594b15d203e513acf952340wwang if (check_card_ready(chip, lun)) { 41177d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 41277d89b08766c878a2594b15d203e513acf952340wwang } else { 41377d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 41477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 41577d89b08766c878a2594b15d203e513acf952340wwang } 41677d89b08766c878a2594b15d203e513acf952340wwang 41777d89b08766c878a2594b15d203e513acf952340wwang break; 41877d89b08766c878a2594b15d203e513acf952340wwang } 41977d89b08766c878a2594b15d203e513acf952340wwang 42077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 42177d89b08766c878a2594b15d203e513acf952340wwang} 42277d89b08766c878a2594b15d203e513acf952340wwang 42377d89b08766c878a2594b15d203e513acf952340wwang 42477d89b08766c878a2594b15d203e513acf952340wwangstatic int allow_medium_removal(struct scsi_cmnd *srb, struct rtsx_chip *chip) 42577d89b08766c878a2594b15d203e513acf952340wwang{ 42677d89b08766c878a2594b15d203e513acf952340wwang int prevent; 42777d89b08766c878a2594b15d203e513acf952340wwang 42877d89b08766c878a2594b15d203e513acf952340wwang prevent = srb->cmnd[4] & 0x1; 42977d89b08766c878a2594b15d203e513acf952340wwang 43077d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 43177d89b08766c878a2594b15d203e513acf952340wwang 43277d89b08766c878a2594b15d203e513acf952340wwang if (prevent) { 43377d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 43477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 43577d89b08766c878a2594b15d203e513acf952340wwang } 43677d89b08766c878a2594b15d203e513acf952340wwang 43777d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 43877d89b08766c878a2594b15d203e513acf952340wwang} 43977d89b08766c878a2594b15d203e513acf952340wwang 44077d89b08766c878a2594b15d203e513acf952340wwang 44177d89b08766c878a2594b15d203e513acf952340wwangstatic int request_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) 44277d89b08766c878a2594b15d203e513acf952340wwang{ 44377d89b08766c878a2594b15d203e513acf952340wwang struct sense_data_t *sense; 44477d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 44577d89b08766c878a2594b15d203e513acf952340wwang struct ms_info *ms_card = &(chip->ms_card); 44677d89b08766c878a2594b15d203e513acf952340wwang unsigned char *tmp, *buf; 44777d89b08766c878a2594b15d203e513acf952340wwang 44877d89b08766c878a2594b15d203e513acf952340wwang sense = &(chip->sense_buffer[lun]); 44977d89b08766c878a2594b15d203e513acf952340wwang 45077d89b08766c878a2594b15d203e513acf952340wwang if ((get_lun_card(chip, lun) == MS_CARD) && ms_card->pro_under_formatting) { 45177d89b08766c878a2594b15d203e513acf952340wwang if (ms_card->format_status == FORMAT_SUCCESS) { 45277d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); 45377d89b08766c878a2594b15d203e513acf952340wwang ms_card->pro_under_formatting = 0; 45477d89b08766c878a2594b15d203e513acf952340wwang ms_card->progress = 0; 45577d89b08766c878a2594b15d203e513acf952340wwang } else if (ms_card->format_status == FORMAT_IN_PROGRESS) { 45677d89b08766c878a2594b15d203e513acf952340wwang /* Logical Unit Not Ready Format in Progress */ 45777d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 45877d89b08766c878a2594b15d203e513acf952340wwang 0, (u16)(ms_card->progress)); 45977d89b08766c878a2594b15d203e513acf952340wwang } else { 46077d89b08766c878a2594b15d203e513acf952340wwang /* Format Command Failed */ 46177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); 46277d89b08766c878a2594b15d203e513acf952340wwang ms_card->pro_under_formatting = 0; 46377d89b08766c878a2594b15d203e513acf952340wwang ms_card->progress = 0; 46477d89b08766c878a2594b15d203e513acf952340wwang } 46577d89b08766c878a2594b15d203e513acf952340wwang 46677d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 46777d89b08766c878a2594b15d203e513acf952340wwang } 46877d89b08766c878a2594b15d203e513acf952340wwang 46977d89b08766c878a2594b15d203e513acf952340wwang buf = vmalloc(scsi_bufflen(srb)); 47077d89b08766c878a2594b15d203e513acf952340wwang if (buf == NULL) { 47177d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 47277d89b08766c878a2594b15d203e513acf952340wwang } 47377d89b08766c878a2594b15d203e513acf952340wwang 47477d89b08766c878a2594b15d203e513acf952340wwang tmp = (unsigned char *)sense; 47577d89b08766c878a2594b15d203e513acf952340wwang memcpy(buf, tmp, scsi_bufflen(srb)); 47677d89b08766c878a2594b15d203e513acf952340wwang 47777d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); 47877d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 47977d89b08766c878a2594b15d203e513acf952340wwang 48077d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 48177d89b08766c878a2594b15d203e513acf952340wwang /* Reset Sense Data */ 48277d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); 48377d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 48477d89b08766c878a2594b15d203e513acf952340wwang} 48577d89b08766c878a2594b15d203e513acf952340wwang 48677d89b08766c878a2594b15d203e513acf952340wwangstatic void ms_mode_sense(struct rtsx_chip *chip, u8 cmd, 48777d89b08766c878a2594b15d203e513acf952340wwang int lun, u8 *buf, int buf_len) 48877d89b08766c878a2594b15d203e513acf952340wwang{ 48977d89b08766c878a2594b15d203e513acf952340wwang struct ms_info *ms_card = &(chip->ms_card); 49077d89b08766c878a2594b15d203e513acf952340wwang int sys_info_offset; 49177d89b08766c878a2594b15d203e513acf952340wwang int data_size = buf_len; 49277d89b08766c878a2594b15d203e513acf952340wwang int support_format = 0; 49377d89b08766c878a2594b15d203e513acf952340wwang int i = 0; 49477d89b08766c878a2594b15d203e513acf952340wwang 49577d89b08766c878a2594b15d203e513acf952340wwang if (cmd == MODE_SENSE) { 49677d89b08766c878a2594b15d203e513acf952340wwang sys_info_offset = 8; 49777d89b08766c878a2594b15d203e513acf952340wwang if (data_size > 0x68) { 49877d89b08766c878a2594b15d203e513acf952340wwang data_size = 0x68; 49977d89b08766c878a2594b15d203e513acf952340wwang } 50077d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x67; /* Mode Data Length */ 50177d89b08766c878a2594b15d203e513acf952340wwang } else { 50277d89b08766c878a2594b15d203e513acf952340wwang sys_info_offset = 12; 50377d89b08766c878a2594b15d203e513acf952340wwang if (data_size > 0x6C) { 50477d89b08766c878a2594b15d203e513acf952340wwang data_size = 0x6C; 50577d89b08766c878a2594b15d203e513acf952340wwang } 50677d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; /* Mode Data Length (MSB) */ 50777d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x6A; /* Mode Data Length (LSB) */ 50877d89b08766c878a2594b15d203e513acf952340wwang } 50977d89b08766c878a2594b15d203e513acf952340wwang 51077d89b08766c878a2594b15d203e513acf952340wwang /* Medium Type Code */ 51177d89b08766c878a2594b15d203e513acf952340wwang if (check_card_ready(chip, lun)) { 51277d89b08766c878a2594b15d203e513acf952340wwang if (CHK_MSXC(ms_card)) { 51377d89b08766c878a2594b15d203e513acf952340wwang support_format = 1; 51477d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x40; 51577d89b08766c878a2594b15d203e513acf952340wwang } else if (CHK_MSPRO(ms_card)) { 51677d89b08766c878a2594b15d203e513acf952340wwang support_format = 1; 51777d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x20; 51877d89b08766c878a2594b15d203e513acf952340wwang } else { 51977d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x10; 52077d89b08766c878a2594b15d203e513acf952340wwang } 52177d89b08766c878a2594b15d203e513acf952340wwang 52277d89b08766c878a2594b15d203e513acf952340wwang /* WP */ 52377d89b08766c878a2594b15d203e513acf952340wwang if (check_card_wp(chip, lun)) { 52477d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x80; 52577d89b08766c878a2594b15d203e513acf952340wwang } else { 52677d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; 52777d89b08766c878a2594b15d203e513acf952340wwang } 52877d89b08766c878a2594b15d203e513acf952340wwang } else { 52977d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; /* MediaType */ 53077d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; /* WP */ 53177d89b08766c878a2594b15d203e513acf952340wwang } 53277d89b08766c878a2594b15d203e513acf952340wwang 53377d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; /* Reserved */ 53477d89b08766c878a2594b15d203e513acf952340wwang 53577d89b08766c878a2594b15d203e513acf952340wwang if (cmd == MODE_SENSE_10) { 53677d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; /* Reserved */ 53777d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; /* Block descriptor length(MSB) */ 53877d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; /* Block descriptor length(LSB) */ 53977d89b08766c878a2594b15d203e513acf952340wwang 54077d89b08766c878a2594b15d203e513acf952340wwang /* The Following Data is the content of "Page 0x20" */ 54177d89b08766c878a2594b15d203e513acf952340wwang if (data_size >= 9) 54277d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x20; /* Page Code */ 54377d89b08766c878a2594b15d203e513acf952340wwang if (data_size >= 10) 54477d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x62; /* Page Length */ 54577d89b08766c878a2594b15d203e513acf952340wwang if (data_size >= 11) 54677d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; /* No Access Control */ 54777d89b08766c878a2594b15d203e513acf952340wwang if (data_size >= 12) { 54877d89b08766c878a2594b15d203e513acf952340wwang if (support_format) { 54977d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0xC0; /* SF, SGM */ 55077d89b08766c878a2594b15d203e513acf952340wwang } else { 55177d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; 55277d89b08766c878a2594b15d203e513acf952340wwang } 55377d89b08766c878a2594b15d203e513acf952340wwang } 55477d89b08766c878a2594b15d203e513acf952340wwang } else { 55577d89b08766c878a2594b15d203e513acf952340wwang /* The Following Data is the content of "Page 0x20" */ 55677d89b08766c878a2594b15d203e513acf952340wwang if (data_size >= 5) 55777d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x20; /* Page Code */ 55877d89b08766c878a2594b15d203e513acf952340wwang if (data_size >= 6) 55977d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x62; /* Page Length */ 56077d89b08766c878a2594b15d203e513acf952340wwang if (data_size >= 7) 56177d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; /* No Access Control */ 56277d89b08766c878a2594b15d203e513acf952340wwang if (data_size >= 8) { 56377d89b08766c878a2594b15d203e513acf952340wwang if (support_format) { 56477d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0xC0; /* SF, SGM */ 56577d89b08766c878a2594b15d203e513acf952340wwang } else { 56677d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; 56777d89b08766c878a2594b15d203e513acf952340wwang } 56877d89b08766c878a2594b15d203e513acf952340wwang } 56977d89b08766c878a2594b15d203e513acf952340wwang } 57077d89b08766c878a2594b15d203e513acf952340wwang 57177d89b08766c878a2594b15d203e513acf952340wwang if (data_size > sys_info_offset) { 57277d89b08766c878a2594b15d203e513acf952340wwang /* 96 Bytes Attribute Data */ 57377d89b08766c878a2594b15d203e513acf952340wwang int len = data_size - sys_info_offset; 57477d89b08766c878a2594b15d203e513acf952340wwang len = (len < 96) ? len : 96; 57577d89b08766c878a2594b15d203e513acf952340wwang 57677d89b08766c878a2594b15d203e513acf952340wwang memcpy(buf + sys_info_offset, ms_card->raw_sys_info, len); 57777d89b08766c878a2594b15d203e513acf952340wwang } 57877d89b08766c878a2594b15d203e513acf952340wwang} 57977d89b08766c878a2594b15d203e513acf952340wwang 58077d89b08766c878a2594b15d203e513acf952340wwangstatic int mode_sense(struct scsi_cmnd *srb, struct rtsx_chip *chip) 58177d89b08766c878a2594b15d203e513acf952340wwang{ 58277d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 58377d89b08766c878a2594b15d203e513acf952340wwang unsigned int dataSize; 58477d89b08766c878a2594b15d203e513acf952340wwang int status; 58577d89b08766c878a2594b15d203e513acf952340wwang int pro_formatter_flag; 58677d89b08766c878a2594b15d203e513acf952340wwang unsigned char pageCode, *buf; 58777d89b08766c878a2594b15d203e513acf952340wwang u8 card = get_lun_card(chip, lun); 58877d89b08766c878a2594b15d203e513acf952340wwang 58977d89b08766c878a2594b15d203e513acf952340wwang#ifndef SUPPORT_MAGIC_GATE 59077d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun)) { 59177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 59277d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb)); 59377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 59477d89b08766c878a2594b15d203e513acf952340wwang } 59577d89b08766c878a2594b15d203e513acf952340wwang#endif 59677d89b08766c878a2594b15d203e513acf952340wwang 59777d89b08766c878a2594b15d203e513acf952340wwang pro_formatter_flag = 0; 59877d89b08766c878a2594b15d203e513acf952340wwang dataSize = 8; 59977d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_MAGIC_GATE 60077d89b08766c878a2594b15d203e513acf952340wwang if ((chip->lun2card[lun] & MS_CARD)) { 60177d89b08766c878a2594b15d203e513acf952340wwang if (!card || (card == MS_CARD)) { 60277d89b08766c878a2594b15d203e513acf952340wwang dataSize = 108; 60377d89b08766c878a2594b15d203e513acf952340wwang if (chip->mspro_formatter_enable) { 60477d89b08766c878a2594b15d203e513acf952340wwang pro_formatter_flag = 1; 60577d89b08766c878a2594b15d203e513acf952340wwang } 60677d89b08766c878a2594b15d203e513acf952340wwang } 60777d89b08766c878a2594b15d203e513acf952340wwang } 60877d89b08766c878a2594b15d203e513acf952340wwang#else 60977d89b08766c878a2594b15d203e513acf952340wwang if (card == MS_CARD) { 61077d89b08766c878a2594b15d203e513acf952340wwang if (chip->mspro_formatter_enable) { 61177d89b08766c878a2594b15d203e513acf952340wwang pro_formatter_flag = 1; 61277d89b08766c878a2594b15d203e513acf952340wwang dataSize = 108; 61377d89b08766c878a2594b15d203e513acf952340wwang } 61477d89b08766c878a2594b15d203e513acf952340wwang } 61577d89b08766c878a2594b15d203e513acf952340wwang#endif 61677d89b08766c878a2594b15d203e513acf952340wwang 61777d89b08766c878a2594b15d203e513acf952340wwang buf = kmalloc(dataSize, GFP_KERNEL); 61877d89b08766c878a2594b15d203e513acf952340wwang if (buf == NULL) { 61977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 62077d89b08766c878a2594b15d203e513acf952340wwang } 62177d89b08766c878a2594b15d203e513acf952340wwang 62277d89b08766c878a2594b15d203e513acf952340wwang pageCode = srb->cmnd[2] & 0x3f; 62377d89b08766c878a2594b15d203e513acf952340wwang 62477d89b08766c878a2594b15d203e513acf952340wwang if ((pageCode == 0x3F) || (pageCode == 0x1C) || 62577d89b08766c878a2594b15d203e513acf952340wwang (pageCode == 0x00) || 62677d89b08766c878a2594b15d203e513acf952340wwang (pro_formatter_flag && (pageCode == 0x20))) { 62777d89b08766c878a2594b15d203e513acf952340wwang if (srb->cmnd[0] == MODE_SENSE) { 62877d89b08766c878a2594b15d203e513acf952340wwang if ((pageCode == 0x3F) || (pageCode == 0x20)) { 62977d89b08766c878a2594b15d203e513acf952340wwang ms_mode_sense(chip, srb->cmnd[0], 63077d89b08766c878a2594b15d203e513acf952340wwang lun, buf, dataSize); 63177d89b08766c878a2594b15d203e513acf952340wwang } else { 63277d89b08766c878a2594b15d203e513acf952340wwang dataSize = 4; 63377d89b08766c878a2594b15d203e513acf952340wwang buf[0] = 0x03; 63477d89b08766c878a2594b15d203e513acf952340wwang buf[1] = 0x00; 63577d89b08766c878a2594b15d203e513acf952340wwang if (check_card_wp(chip, lun)) { 63677d89b08766c878a2594b15d203e513acf952340wwang buf[2] = 0x80; 63777d89b08766c878a2594b15d203e513acf952340wwang } else { 63877d89b08766c878a2594b15d203e513acf952340wwang buf[2] = 0x00; 63977d89b08766c878a2594b15d203e513acf952340wwang } 64077d89b08766c878a2594b15d203e513acf952340wwang buf[3] = 0x00; 64177d89b08766c878a2594b15d203e513acf952340wwang } 64277d89b08766c878a2594b15d203e513acf952340wwang } else { 64377d89b08766c878a2594b15d203e513acf952340wwang if ((pageCode == 0x3F) || (pageCode == 0x20)) { 64477d89b08766c878a2594b15d203e513acf952340wwang ms_mode_sense(chip, srb->cmnd[0], 64577d89b08766c878a2594b15d203e513acf952340wwang lun, buf, dataSize); 64677d89b08766c878a2594b15d203e513acf952340wwang } else { 64777d89b08766c878a2594b15d203e513acf952340wwang dataSize = 8; 64877d89b08766c878a2594b15d203e513acf952340wwang buf[0] = 0x00; 64977d89b08766c878a2594b15d203e513acf952340wwang buf[1] = 0x06; 65077d89b08766c878a2594b15d203e513acf952340wwang buf[2] = 0x00; 65177d89b08766c878a2594b15d203e513acf952340wwang if (check_card_wp(chip, lun)) { 65277d89b08766c878a2594b15d203e513acf952340wwang buf[3] = 0x80; 65377d89b08766c878a2594b15d203e513acf952340wwang } else { 65477d89b08766c878a2594b15d203e513acf952340wwang buf[3] = 0x00; 65577d89b08766c878a2594b15d203e513acf952340wwang } 65677d89b08766c878a2594b15d203e513acf952340wwang buf[4] = 0x00; 65777d89b08766c878a2594b15d203e513acf952340wwang buf[5] = 0x00; 65877d89b08766c878a2594b15d203e513acf952340wwang buf[6] = 0x00; 65977d89b08766c878a2594b15d203e513acf952340wwang buf[7] = 0x00; 66077d89b08766c878a2594b15d203e513acf952340wwang } 66177d89b08766c878a2594b15d203e513acf952340wwang } 66277d89b08766c878a2594b15d203e513acf952340wwang status = TRANSPORT_GOOD; 66377d89b08766c878a2594b15d203e513acf952340wwang } else { 66477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 66577d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb)); 66677d89b08766c878a2594b15d203e513acf952340wwang status = TRANSPORT_FAILED; 66777d89b08766c878a2594b15d203e513acf952340wwang } 66877d89b08766c878a2594b15d203e513acf952340wwang 66977d89b08766c878a2594b15d203e513acf952340wwang if (status == TRANSPORT_GOOD) { 67077d89b08766c878a2594b15d203e513acf952340wwang unsigned int len = min(scsi_bufflen(srb), dataSize); 67177d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, len, srb); 67277d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 67377d89b08766c878a2594b15d203e513acf952340wwang } 67477d89b08766c878a2594b15d203e513acf952340wwang kfree(buf); 67577d89b08766c878a2594b15d203e513acf952340wwang 67677d89b08766c878a2594b15d203e513acf952340wwang return status; 67777d89b08766c878a2594b15d203e513acf952340wwang} 67877d89b08766c878a2594b15d203e513acf952340wwang 67977d89b08766c878a2594b15d203e513acf952340wwangstatic int read_write(struct scsi_cmnd *srb, struct rtsx_chip *chip) 68077d89b08766c878a2594b15d203e513acf952340wwang{ 68177d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_SD_LOCK 68277d89b08766c878a2594b15d203e513acf952340wwang struct sd_info *sd_card = &(chip->sd_card); 68377d89b08766c878a2594b15d203e513acf952340wwang#endif 68477d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 68577d89b08766c878a2594b15d203e513acf952340wwang int retval; 68677d89b08766c878a2594b15d203e513acf952340wwang u32 start_sec; 68777d89b08766c878a2594b15d203e513acf952340wwang u16 sec_cnt; 68877d89b08766c878a2594b15d203e513acf952340wwang 68977d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 69077d89b08766c878a2594b15d203e513acf952340wwang 69177d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 69277d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 69377d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 69477d89b08766c878a2594b15d203e513acf952340wwang } 69577d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 69677d89b08766c878a2594b15d203e513acf952340wwang 69777d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun) || (get_card_size(chip, lun) == 0)) { 69877d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 69977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 70077d89b08766c878a2594b15d203e513acf952340wwang } 70177d89b08766c878a2594b15d203e513acf952340wwang 70277d89b08766c878a2594b15d203e513acf952340wwang if (!(CHK_BIT(chip->lun_mc, lun))) { 70377d89b08766c878a2594b15d203e513acf952340wwang SET_BIT(chip->lun_mc, lun); 70477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); 70577d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_FAILED; 70677d89b08766c878a2594b15d203e513acf952340wwang } 70777d89b08766c878a2594b15d203e513acf952340wwang 70877d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_SD_LOCK 70977d89b08766c878a2594b15d203e513acf952340wwang if (sd_card->sd_erase_status) { 71077d89b08766c878a2594b15d203e513acf952340wwang /* Accessing to any card is forbidden 71177d89b08766c878a2594b15d203e513acf952340wwang * until the erase procedure of SD is completed 71277d89b08766c878a2594b15d203e513acf952340wwang */ 71377d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("SD card being erased!\n"); 71477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); 71577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 71677d89b08766c878a2594b15d203e513acf952340wwang } 71777d89b08766c878a2594b15d203e513acf952340wwang 71877d89b08766c878a2594b15d203e513acf952340wwang if (get_lun_card(chip, lun) == SD_CARD) { 71977d89b08766c878a2594b15d203e513acf952340wwang if (sd_card->sd_lock_status & SD_LOCKED) { 72077d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("SD card locked!\n"); 72177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); 72277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 72377d89b08766c878a2594b15d203e513acf952340wwang } 72477d89b08766c878a2594b15d203e513acf952340wwang } 72577d89b08766c878a2594b15d203e513acf952340wwang#endif 72677d89b08766c878a2594b15d203e513acf952340wwang 72777d89b08766c878a2594b15d203e513acf952340wwang if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) { 72877d89b08766c878a2594b15d203e513acf952340wwang start_sec = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | 72977d89b08766c878a2594b15d203e513acf952340wwang ((u32)srb->cmnd[4] << 8) | ((u32)srb->cmnd[5]); 73077d89b08766c878a2594b15d203e513acf952340wwang sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; 73177d89b08766c878a2594b15d203e513acf952340wwang } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { 73277d89b08766c878a2594b15d203e513acf952340wwang start_sec = ((u32)(srb->cmnd[1] & 0x1F) << 16) | 73377d89b08766c878a2594b15d203e513acf952340wwang ((u32)srb->cmnd[2] << 8) | ((u32)srb->cmnd[3]); 73477d89b08766c878a2594b15d203e513acf952340wwang sec_cnt = srb->cmnd[4]; 73577d89b08766c878a2594b15d203e513acf952340wwang } else if ((srb->cmnd[0] == VENDOR_CMND) && (srb->cmnd[1] == SCSI_APP_CMD) && 73677d89b08766c878a2594b15d203e513acf952340wwang ((srb->cmnd[2] == PP_READ10) || (srb->cmnd[2] == PP_WRITE10))) { 73777d89b08766c878a2594b15d203e513acf952340wwang start_sec = ((u32)srb->cmnd[4] << 24) | ((u32)srb->cmnd[5] << 16) | 73877d89b08766c878a2594b15d203e513acf952340wwang ((u32)srb->cmnd[6] << 8) | ((u32)srb->cmnd[7]); 73977d89b08766c878a2594b15d203e513acf952340wwang sec_cnt = ((u16)(srb->cmnd[9]) << 8) | srb->cmnd[10]; 74077d89b08766c878a2594b15d203e513acf952340wwang } else { 74177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 74277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 74377d89b08766c878a2594b15d203e513acf952340wwang } 74477d89b08766c878a2594b15d203e513acf952340wwang 74577d89b08766c878a2594b15d203e513acf952340wwang /* In some test, we will receive a start_sec like 0xFFFFFFFF. 74677d89b08766c878a2594b15d203e513acf952340wwang * In this situation, start_sec + sec_cnt will overflow, so we 74777d89b08766c878a2594b15d203e513acf952340wwang * need to judge start_sec at first 74877d89b08766c878a2594b15d203e513acf952340wwang */ 74977d89b08766c878a2594b15d203e513acf952340wwang if ((start_sec > get_card_size(chip, lun)) || 75077d89b08766c878a2594b15d203e513acf952340wwang ((start_sec + sec_cnt) > get_card_size(chip, lun))) { 75177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE); 75277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 75377d89b08766c878a2594b15d203e513acf952340wwang } 75477d89b08766c878a2594b15d203e513acf952340wwang 75577d89b08766c878a2594b15d203e513acf952340wwang if (sec_cnt == 0) { 75677d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 75777d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 75877d89b08766c878a2594b15d203e513acf952340wwang } 75977d89b08766c878a2594b15d203e513acf952340wwang 76077d89b08766c878a2594b15d203e513acf952340wwang if (chip->rw_fail_cnt[lun] == 3) { 76177d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("read/write fail three times in succession\n"); 76277d89b08766c878a2594b15d203e513acf952340wwang if (srb->sc_data_direction == DMA_FROM_DEVICE) { 76377d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 76477d89b08766c878a2594b15d203e513acf952340wwang } else { 76577d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); 76677d89b08766c878a2594b15d203e513acf952340wwang } 76777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 76877d89b08766c878a2594b15d203e513acf952340wwang } 76977d89b08766c878a2594b15d203e513acf952340wwang 77077d89b08766c878a2594b15d203e513acf952340wwang if (srb->sc_data_direction == DMA_TO_DEVICE) { 77177d89b08766c878a2594b15d203e513acf952340wwang if (check_card_wp(chip, lun)) { 77277d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("Write protected card!\n"); 77377d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); 77477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 77577d89b08766c878a2594b15d203e513acf952340wwang } 77677d89b08766c878a2594b15d203e513acf952340wwang if (CHECK_PID(chip, 0x5209) && chip->max_payload) { 77777d89b08766c878a2594b15d203e513acf952340wwang u8 val = 0x10 | (chip->max_payload << 5); 77877d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_cfg_dw(chip, 0, 0x78, 0xFF, val); 77977d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 78077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 78177d89b08766c878a2594b15d203e513acf952340wwang } 78277d89b08766c878a2594b15d203e513acf952340wwang } 78377d89b08766c878a2594b15d203e513acf952340wwang } 78477d89b08766c878a2594b15d203e513acf952340wwang 78577d89b08766c878a2594b15d203e513acf952340wwang retval = card_rw(srb, chip, start_sec, sec_cnt); 78677d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 78777d89b08766c878a2594b15d203e513acf952340wwang if (chip->need_release & chip->lun2card[lun]) { 78877d89b08766c878a2594b15d203e513acf952340wwang chip->rw_fail_cnt[lun] = 0; 78977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 79077d89b08766c878a2594b15d203e513acf952340wwang } else { 79177d89b08766c878a2594b15d203e513acf952340wwang chip->rw_fail_cnt[lun]++; 79277d89b08766c878a2594b15d203e513acf952340wwang if (srb->sc_data_direction == DMA_FROM_DEVICE) { 79377d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 79477d89b08766c878a2594b15d203e513acf952340wwang } else { 79577d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); 79677d89b08766c878a2594b15d203e513acf952340wwang } 79777d89b08766c878a2594b15d203e513acf952340wwang } 79877d89b08766c878a2594b15d203e513acf952340wwang retval = TRANSPORT_FAILED; 79977d89b08766c878a2594b15d203e513acf952340wwang TRACE_GOTO(chip, Exit); 80077d89b08766c878a2594b15d203e513acf952340wwang } else { 80177d89b08766c878a2594b15d203e513acf952340wwang chip->rw_fail_cnt[lun] = 0; 80277d89b08766c878a2594b15d203e513acf952340wwang retval = TRANSPORT_GOOD; 80377d89b08766c878a2594b15d203e513acf952340wwang } 80477d89b08766c878a2594b15d203e513acf952340wwang 80577d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 80677d89b08766c878a2594b15d203e513acf952340wwang 80777d89b08766c878a2594b15d203e513acf952340wwangExit: 80877d89b08766c878a2594b15d203e513acf952340wwang if (srb->sc_data_direction == DMA_TO_DEVICE) { 80977d89b08766c878a2594b15d203e513acf952340wwang if (CHECK_PID(chip, 0x5209) && chip->max_payload) { 81077d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_cfg_dw(chip, 0, 0x78, 0xFF, 0x10); 81177d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 81277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 81377d89b08766c878a2594b15d203e513acf952340wwang } 81477d89b08766c878a2594b15d203e513acf952340wwang } 81577d89b08766c878a2594b15d203e513acf952340wwang } 81677d89b08766c878a2594b15d203e513acf952340wwang 81777d89b08766c878a2594b15d203e513acf952340wwang return retval; 81877d89b08766c878a2594b15d203e513acf952340wwang} 81977d89b08766c878a2594b15d203e513acf952340wwang 82077d89b08766c878a2594b15d203e513acf952340wwangstatic int read_format_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) 82177d89b08766c878a2594b15d203e513acf952340wwang{ 82277d89b08766c878a2594b15d203e513acf952340wwang unsigned char *buf; 82377d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 82477d89b08766c878a2594b15d203e513acf952340wwang unsigned int buf_len; 82577d89b08766c878a2594b15d203e513acf952340wwang u8 card = get_lun_card(chip, lun); 82677d89b08766c878a2594b15d203e513acf952340wwang u32 card_size; 82777d89b08766c878a2594b15d203e513acf952340wwang int desc_cnt; 82877d89b08766c878a2594b15d203e513acf952340wwang int i = 0; 82977d89b08766c878a2594b15d203e513acf952340wwang 83077d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun)) { 83177d89b08766c878a2594b15d203e513acf952340wwang if (!chip->mspro_formatter_enable) { 83277d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 83377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 83477d89b08766c878a2594b15d203e513acf952340wwang } 83577d89b08766c878a2594b15d203e513acf952340wwang } 83677d89b08766c878a2594b15d203e513acf952340wwang 83777d89b08766c878a2594b15d203e513acf952340wwang buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12; 83877d89b08766c878a2594b15d203e513acf952340wwang 83977d89b08766c878a2594b15d203e513acf952340wwang buf = kmalloc(buf_len, GFP_KERNEL); 84077d89b08766c878a2594b15d203e513acf952340wwang if (buf == NULL) { 84177d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 84277d89b08766c878a2594b15d203e513acf952340wwang } 84377d89b08766c878a2594b15d203e513acf952340wwang 84477d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0; 84577d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0; 84677d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0; 84777d89b08766c878a2594b15d203e513acf952340wwang 84877d89b08766c878a2594b15d203e513acf952340wwang /* Capacity List Length */ 84977d89b08766c878a2594b15d203e513acf952340wwang if ((buf_len > 12) && chip->mspro_formatter_enable && 85077d89b08766c878a2594b15d203e513acf952340wwang (chip->lun2card[lun] & MS_CARD) && 85177d89b08766c878a2594b15d203e513acf952340wwang (!card || (card == MS_CARD))) { 85277d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x10; 85377d89b08766c878a2594b15d203e513acf952340wwang desc_cnt = 2; 85477d89b08766c878a2594b15d203e513acf952340wwang } else { 85577d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x08; 85677d89b08766c878a2594b15d203e513acf952340wwang desc_cnt = 1; 85777d89b08766c878a2594b15d203e513acf952340wwang } 85877d89b08766c878a2594b15d203e513acf952340wwang 85977d89b08766c878a2594b15d203e513acf952340wwang while (desc_cnt) { 86077d89b08766c878a2594b15d203e513acf952340wwang if (check_card_ready(chip, lun)) { 86177d89b08766c878a2594b15d203e513acf952340wwang card_size = get_card_size(chip, lun); 86277d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = (unsigned char)(card_size >> 24); 86377d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = (unsigned char)(card_size >> 16); 86477d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = (unsigned char)(card_size >> 8); 86577d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = (unsigned char)card_size; 86677d89b08766c878a2594b15d203e513acf952340wwang 86777d89b08766c878a2594b15d203e513acf952340wwang if (desc_cnt == 2) { 86877d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 2; 86977d89b08766c878a2594b15d203e513acf952340wwang } else { 87077d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0; 87177d89b08766c878a2594b15d203e513acf952340wwang } 87277d89b08766c878a2594b15d203e513acf952340wwang } else { 87377d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0xFF; 87477d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0xFF; 87577d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0xFF; 87677d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0xFF; 87777d89b08766c878a2594b15d203e513acf952340wwang 87877d89b08766c878a2594b15d203e513acf952340wwang if (desc_cnt == 2) { 87977d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 3; 88077d89b08766c878a2594b15d203e513acf952340wwang } else { 88177d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0; 88277d89b08766c878a2594b15d203e513acf952340wwang } 88377d89b08766c878a2594b15d203e513acf952340wwang } 88477d89b08766c878a2594b15d203e513acf952340wwang 88577d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; 88677d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x02; 88777d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; 88877d89b08766c878a2594b15d203e513acf952340wwang 88977d89b08766c878a2594b15d203e513acf952340wwang desc_cnt--; 89077d89b08766c878a2594b15d203e513acf952340wwang } 89177d89b08766c878a2594b15d203e513acf952340wwang 89277d89b08766c878a2594b15d203e513acf952340wwang buf_len = min(scsi_bufflen(srb), buf_len); 89377d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, buf_len, srb); 89477d89b08766c878a2594b15d203e513acf952340wwang kfree(buf); 89577d89b08766c878a2594b15d203e513acf952340wwang 89677d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); 89777d89b08766c878a2594b15d203e513acf952340wwang 89877d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 89977d89b08766c878a2594b15d203e513acf952340wwang} 90077d89b08766c878a2594b15d203e513acf952340wwang 90177d89b08766c878a2594b15d203e513acf952340wwangstatic int read_capacity(struct scsi_cmnd *srb, struct rtsx_chip *chip) 90277d89b08766c878a2594b15d203e513acf952340wwang{ 90377d89b08766c878a2594b15d203e513acf952340wwang unsigned char *buf; 90477d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 90577d89b08766c878a2594b15d203e513acf952340wwang u32 card_size; 90677d89b08766c878a2594b15d203e513acf952340wwang 90777d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun)) { 90877d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 90977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 91077d89b08766c878a2594b15d203e513acf952340wwang } 91177d89b08766c878a2594b15d203e513acf952340wwang 91277d89b08766c878a2594b15d203e513acf952340wwang if (!(CHK_BIT(chip->lun_mc, lun))) { 91377d89b08766c878a2594b15d203e513acf952340wwang SET_BIT(chip->lun_mc, lun); 91477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); 91577d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_FAILED; 91677d89b08766c878a2594b15d203e513acf952340wwang } 91777d89b08766c878a2594b15d203e513acf952340wwang 91877d89b08766c878a2594b15d203e513acf952340wwang buf = kmalloc(8, GFP_KERNEL); 91977d89b08766c878a2594b15d203e513acf952340wwang if (buf == NULL) { 92077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 92177d89b08766c878a2594b15d203e513acf952340wwang } 92277d89b08766c878a2594b15d203e513acf952340wwang 92377d89b08766c878a2594b15d203e513acf952340wwang card_size = get_card_size(chip, lun); 92477d89b08766c878a2594b15d203e513acf952340wwang buf[0] = (unsigned char)((card_size - 1) >> 24); 92577d89b08766c878a2594b15d203e513acf952340wwang buf[1] = (unsigned char)((card_size - 1) >> 16); 92677d89b08766c878a2594b15d203e513acf952340wwang buf[2] = (unsigned char)((card_size - 1) >> 8); 92777d89b08766c878a2594b15d203e513acf952340wwang buf[3] = (unsigned char)(card_size - 1); 92877d89b08766c878a2594b15d203e513acf952340wwang 92977d89b08766c878a2594b15d203e513acf952340wwang buf[4] = 0x00; 93077d89b08766c878a2594b15d203e513acf952340wwang buf[5] = 0x00; 93177d89b08766c878a2594b15d203e513acf952340wwang buf[6] = 0x02; 93277d89b08766c878a2594b15d203e513acf952340wwang buf[7] = 0x00; 93377d89b08766c878a2594b15d203e513acf952340wwang 93477d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); 93577d89b08766c878a2594b15d203e513acf952340wwang kfree(buf); 93677d89b08766c878a2594b15d203e513acf952340wwang 93777d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 93877d89b08766c878a2594b15d203e513acf952340wwang 93977d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 94077d89b08766c878a2594b15d203e513acf952340wwang} 94177d89b08766c878a2594b15d203e513acf952340wwang 94277d89b08766c878a2594b15d203e513acf952340wwangstatic int read_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) 94377d89b08766c878a2594b15d203e513acf952340wwang{ 94477d89b08766c878a2594b15d203e513acf952340wwang unsigned short len, i; 94577d89b08766c878a2594b15d203e513acf952340wwang int retval; 94677d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 94777d89b08766c878a2594b15d203e513acf952340wwang 94877d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 94977d89b08766c878a2594b15d203e513acf952340wwang 95077d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 95177d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 95277d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 95377d89b08766c878a2594b15d203e513acf952340wwang } 95477d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 95577d89b08766c878a2594b15d203e513acf952340wwang 95677d89b08766c878a2594b15d203e513acf952340wwang len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; 95777d89b08766c878a2594b15d203e513acf952340wwang 95877d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 95977d89b08766c878a2594b15d203e513acf952340wwang if (!buf) { 96077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 96177d89b08766c878a2594b15d203e513acf952340wwang } 96277d89b08766c878a2594b15d203e513acf952340wwang 96377d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 96477d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 96577d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 96677d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 96777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 96877d89b08766c878a2594b15d203e513acf952340wwang } 96977d89b08766c878a2594b15d203e513acf952340wwang 97077d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < len; i++) { 97177d89b08766c878a2594b15d203e513acf952340wwang retval = spi_read_eeprom(chip, i, buf + i); 97277d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 97377d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 97477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 97577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 97677d89b08766c878a2594b15d203e513acf952340wwang } 97777d89b08766c878a2594b15d203e513acf952340wwang } 97877d89b08766c878a2594b15d203e513acf952340wwang 97977d89b08766c878a2594b15d203e513acf952340wwang len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); 98077d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, len, srb); 98177d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 98277d89b08766c878a2594b15d203e513acf952340wwang 98377d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 98477d89b08766c878a2594b15d203e513acf952340wwang 98577d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 98677d89b08766c878a2594b15d203e513acf952340wwang} 98777d89b08766c878a2594b15d203e513acf952340wwang 98877d89b08766c878a2594b15d203e513acf952340wwangstatic int write_eeprom(struct scsi_cmnd *srb, struct rtsx_chip *chip) 98977d89b08766c878a2594b15d203e513acf952340wwang{ 99077d89b08766c878a2594b15d203e513acf952340wwang unsigned short len, i; 99177d89b08766c878a2594b15d203e513acf952340wwang int retval; 99277d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 99377d89b08766c878a2594b15d203e513acf952340wwang 99477d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 99577d89b08766c878a2594b15d203e513acf952340wwang 99677d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 99777d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 99877d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 99977d89b08766c878a2594b15d203e513acf952340wwang } 100077d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 100177d89b08766c878a2594b15d203e513acf952340wwang 100277d89b08766c878a2594b15d203e513acf952340wwang len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; 100377d89b08766c878a2594b15d203e513acf952340wwang 100477d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 100577d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 100677d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 100777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 100877d89b08766c878a2594b15d203e513acf952340wwang } 100977d89b08766c878a2594b15d203e513acf952340wwang 101077d89b08766c878a2594b15d203e513acf952340wwang if (len == 511) { 101177d89b08766c878a2594b15d203e513acf952340wwang retval = spi_erase_eeprom_chip(chip); 101277d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 101377d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 101477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 101577d89b08766c878a2594b15d203e513acf952340wwang } 101677d89b08766c878a2594b15d203e513acf952340wwang } else { 101777d89b08766c878a2594b15d203e513acf952340wwang len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); 101877d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 101977d89b08766c878a2594b15d203e513acf952340wwang if (buf == NULL) { 102077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 102177d89b08766c878a2594b15d203e513acf952340wwang } 102277d89b08766c878a2594b15d203e513acf952340wwang 102377d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_get_xfer_buf(buf, len, srb); 102477d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 102577d89b08766c878a2594b15d203e513acf952340wwang 102677d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < len; i++) { 102777d89b08766c878a2594b15d203e513acf952340wwang retval = spi_write_eeprom(chip, i, buf[i]); 102877d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 102977d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 103077d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 103177d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 103277d89b08766c878a2594b15d203e513acf952340wwang } 103377d89b08766c878a2594b15d203e513acf952340wwang } 103477d89b08766c878a2594b15d203e513acf952340wwang 103577d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 103677d89b08766c878a2594b15d203e513acf952340wwang } 103777d89b08766c878a2594b15d203e513acf952340wwang 103877d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 103977d89b08766c878a2594b15d203e513acf952340wwang} 104077d89b08766c878a2594b15d203e513acf952340wwang 104177d89b08766c878a2594b15d203e513acf952340wwangstatic int read_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) 104277d89b08766c878a2594b15d203e513acf952340wwang{ 104377d89b08766c878a2594b15d203e513acf952340wwang unsigned short addr, len, i; 104477d89b08766c878a2594b15d203e513acf952340wwang int retval; 104577d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 104677d89b08766c878a2594b15d203e513acf952340wwang 104777d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 104877d89b08766c878a2594b15d203e513acf952340wwang 104977d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 105077d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 105177d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 105277d89b08766c878a2594b15d203e513acf952340wwang } 105377d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 105477d89b08766c878a2594b15d203e513acf952340wwang 105577d89b08766c878a2594b15d203e513acf952340wwang addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; 105677d89b08766c878a2594b15d203e513acf952340wwang len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; 105777d89b08766c878a2594b15d203e513acf952340wwang 105877d89b08766c878a2594b15d203e513acf952340wwang if (addr < 0xFC00) { 105977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 106077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 106177d89b08766c878a2594b15d203e513acf952340wwang } 106277d89b08766c878a2594b15d203e513acf952340wwang 106377d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 106477d89b08766c878a2594b15d203e513acf952340wwang if (!buf) { 106577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 106677d89b08766c878a2594b15d203e513acf952340wwang } 106777d89b08766c878a2594b15d203e513acf952340wwang 106877d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 106977d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 107077d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 107177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 107277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 107377d89b08766c878a2594b15d203e513acf952340wwang } 107477d89b08766c878a2594b15d203e513acf952340wwang 107577d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < len; i++) { 107677d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_read_register(chip, addr + i, buf + i); 107777d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 107877d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 107977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 108077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 108177d89b08766c878a2594b15d203e513acf952340wwang } 108277d89b08766c878a2594b15d203e513acf952340wwang } 108377d89b08766c878a2594b15d203e513acf952340wwang 108477d89b08766c878a2594b15d203e513acf952340wwang len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); 108577d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, len, srb); 108677d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 108777d89b08766c878a2594b15d203e513acf952340wwang 108877d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 108977d89b08766c878a2594b15d203e513acf952340wwang 109077d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 109177d89b08766c878a2594b15d203e513acf952340wwang} 109277d89b08766c878a2594b15d203e513acf952340wwang 109377d89b08766c878a2594b15d203e513acf952340wwangstatic int write_mem(struct scsi_cmnd *srb, struct rtsx_chip *chip) 109477d89b08766c878a2594b15d203e513acf952340wwang{ 109577d89b08766c878a2594b15d203e513acf952340wwang unsigned short addr, len, i; 109677d89b08766c878a2594b15d203e513acf952340wwang int retval; 109777d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 109877d89b08766c878a2594b15d203e513acf952340wwang 109977d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 110077d89b08766c878a2594b15d203e513acf952340wwang 110177d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 110277d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 110377d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 110477d89b08766c878a2594b15d203e513acf952340wwang } 110577d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 110677d89b08766c878a2594b15d203e513acf952340wwang 110777d89b08766c878a2594b15d203e513acf952340wwang addr = ((u16)srb->cmnd[2] << 8) | srb->cmnd[3]; 110877d89b08766c878a2594b15d203e513acf952340wwang len = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; 110977d89b08766c878a2594b15d203e513acf952340wwang 111077d89b08766c878a2594b15d203e513acf952340wwang if (addr < 0xFC00) { 111177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 111277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 111377d89b08766c878a2594b15d203e513acf952340wwang } 111477d89b08766c878a2594b15d203e513acf952340wwang 111577d89b08766c878a2594b15d203e513acf952340wwang len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); 111677d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 111777d89b08766c878a2594b15d203e513acf952340wwang if (buf == NULL) { 111877d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 111977d89b08766c878a2594b15d203e513acf952340wwang } 112077d89b08766c878a2594b15d203e513acf952340wwang 112177d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_get_xfer_buf(buf, len, srb); 112277d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 112377d89b08766c878a2594b15d203e513acf952340wwang 112477d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 112577d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 112677d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 112777d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 112877d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 112977d89b08766c878a2594b15d203e513acf952340wwang } 113077d89b08766c878a2594b15d203e513acf952340wwang 113177d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < len; i++) { 113277d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_register(chip, addr + i, 0xFF, buf[i]); 113377d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 113477d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 113577d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 113677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 113777d89b08766c878a2594b15d203e513acf952340wwang } 113877d89b08766c878a2594b15d203e513acf952340wwang } 113977d89b08766c878a2594b15d203e513acf952340wwang 114077d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 114177d89b08766c878a2594b15d203e513acf952340wwang 114277d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 114377d89b08766c878a2594b15d203e513acf952340wwang} 114477d89b08766c878a2594b15d203e513acf952340wwang 114577d89b08766c878a2594b15d203e513acf952340wwangstatic int get_sd_csd(struct scsi_cmnd *srb, struct rtsx_chip *chip) 114677d89b08766c878a2594b15d203e513acf952340wwang{ 114777d89b08766c878a2594b15d203e513acf952340wwang struct sd_info *sd_card = &(chip->sd_card); 114877d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 114977d89b08766c878a2594b15d203e513acf952340wwang 115077d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun)) { 115177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 115277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 115377d89b08766c878a2594b15d203e513acf952340wwang } 115477d89b08766c878a2594b15d203e513acf952340wwang 115577d89b08766c878a2594b15d203e513acf952340wwang if (get_lun_card(chip, lun) != SD_CARD) { 115677d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 115777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 115877d89b08766c878a2594b15d203e513acf952340wwang } 115977d89b08766c878a2594b15d203e513acf952340wwang 116077d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 116177d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(sd_card->raw_csd, scsi_bufflen(srb), srb); 116277d89b08766c878a2594b15d203e513acf952340wwang 116377d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 116477d89b08766c878a2594b15d203e513acf952340wwang} 116577d89b08766c878a2594b15d203e513acf952340wwang 116677d89b08766c878a2594b15d203e513acf952340wwangstatic int toggle_gpio_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) 116777d89b08766c878a2594b15d203e513acf952340wwang{ 116877d89b08766c878a2594b15d203e513acf952340wwang u8 gpio = srb->cmnd[2]; 116977d89b08766c878a2594b15d203e513acf952340wwang 117077d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 117177d89b08766c878a2594b15d203e513acf952340wwang 117277d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 117377d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 117477d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 117577d89b08766c878a2594b15d203e513acf952340wwang } 117677d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 117777d89b08766c878a2594b15d203e513acf952340wwang 117877d89b08766c878a2594b15d203e513acf952340wwang if (gpio > 3) 117977d89b08766c878a2594b15d203e513acf952340wwang gpio = 1; 118077d89b08766c878a2594b15d203e513acf952340wwang toggle_gpio(chip, gpio); 118177d89b08766c878a2594b15d203e513acf952340wwang 118277d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 118377d89b08766c878a2594b15d203e513acf952340wwang} 118477d89b08766c878a2594b15d203e513acf952340wwang 118577d89b08766c878a2594b15d203e513acf952340wwang#ifdef _MSG_TRACE 118677d89b08766c878a2594b15d203e513acf952340wwangstatic int trace_msg_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) 118777d89b08766c878a2594b15d203e513acf952340wwang{ 118877d89b08766c878a2594b15d203e513acf952340wwang unsigned char *ptr, *buf = NULL; 118977d89b08766c878a2594b15d203e513acf952340wwang int i, msg_cnt; 119077d89b08766c878a2594b15d203e513acf952340wwang u8 clear; 119177d89b08766c878a2594b15d203e513acf952340wwang unsigned int buf_len; 119277d89b08766c878a2594b15d203e513acf952340wwang 119377d89b08766c878a2594b15d203e513acf952340wwang buf_len = 4 + ((2 + MSG_FUNC_LEN + MSG_FILE_LEN + TIME_VAL_LEN) * TRACE_ITEM_CNT); 119477d89b08766c878a2594b15d203e513acf952340wwang 119577d89b08766c878a2594b15d203e513acf952340wwang if ((scsi_bufflen(srb) < buf_len) || (scsi_sglist(srb) == NULL)) { 119677d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 119777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 119877d89b08766c878a2594b15d203e513acf952340wwang } 119977d89b08766c878a2594b15d203e513acf952340wwang 120077d89b08766c878a2594b15d203e513acf952340wwang clear = srb->cmnd[2]; 120177d89b08766c878a2594b15d203e513acf952340wwang 120277d89b08766c878a2594b15d203e513acf952340wwang buf = (unsigned char *)vmalloc(scsi_bufflen(srb)); 120377d89b08766c878a2594b15d203e513acf952340wwang if (buf == NULL) { 120477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 120577d89b08766c878a2594b15d203e513acf952340wwang } 120677d89b08766c878a2594b15d203e513acf952340wwang ptr = buf; 120777d89b08766c878a2594b15d203e513acf952340wwang 120877d89b08766c878a2594b15d203e513acf952340wwang if (chip->trace_msg[chip->msg_idx].valid) { 120977d89b08766c878a2594b15d203e513acf952340wwang msg_cnt = TRACE_ITEM_CNT; 121077d89b08766c878a2594b15d203e513acf952340wwang } else { 121177d89b08766c878a2594b15d203e513acf952340wwang msg_cnt = chip->msg_idx; 121277d89b08766c878a2594b15d203e513acf952340wwang } 121377d89b08766c878a2594b15d203e513acf952340wwang *(ptr++) = (u8)(msg_cnt >> 24); 121477d89b08766c878a2594b15d203e513acf952340wwang *(ptr++) = (u8)(msg_cnt >> 16); 121577d89b08766c878a2594b15d203e513acf952340wwang *(ptr++) = (u8)(msg_cnt >> 8); 121677d89b08766c878a2594b15d203e513acf952340wwang *(ptr++) = (u8)msg_cnt; 121777d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("Trace message count is %d\n", msg_cnt); 121877d89b08766c878a2594b15d203e513acf952340wwang 121977d89b08766c878a2594b15d203e513acf952340wwang for (i = 1; i <= msg_cnt; i++) { 122077d89b08766c878a2594b15d203e513acf952340wwang int j, idx; 122177d89b08766c878a2594b15d203e513acf952340wwang 122277d89b08766c878a2594b15d203e513acf952340wwang idx = chip->msg_idx - i; 122377d89b08766c878a2594b15d203e513acf952340wwang if (idx < 0) 122477d89b08766c878a2594b15d203e513acf952340wwang idx += TRACE_ITEM_CNT; 122577d89b08766c878a2594b15d203e513acf952340wwang 122677d89b08766c878a2594b15d203e513acf952340wwang *(ptr++) = (u8)(chip->trace_msg[idx].line >> 8); 122777d89b08766c878a2594b15d203e513acf952340wwang *(ptr++) = (u8)(chip->trace_msg[idx].line); 122877d89b08766c878a2594b15d203e513acf952340wwang for (j = 0; j < MSG_FUNC_LEN; j++) { 122977d89b08766c878a2594b15d203e513acf952340wwang *(ptr++) = chip->trace_msg[idx].func[j]; 123077d89b08766c878a2594b15d203e513acf952340wwang } 123177d89b08766c878a2594b15d203e513acf952340wwang for (j = 0; j < MSG_FILE_LEN; j++) { 123277d89b08766c878a2594b15d203e513acf952340wwang *(ptr++) = chip->trace_msg[idx].file[j]; 123377d89b08766c878a2594b15d203e513acf952340wwang } 123477d89b08766c878a2594b15d203e513acf952340wwang for (j = 0; j < TIME_VAL_LEN; j++) { 123577d89b08766c878a2594b15d203e513acf952340wwang *(ptr++) = chip->trace_msg[idx].timeval_buf[j]; 123677d89b08766c878a2594b15d203e513acf952340wwang } 123777d89b08766c878a2594b15d203e513acf952340wwang } 123877d89b08766c878a2594b15d203e513acf952340wwang 123977d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb); 124077d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 124177d89b08766c878a2594b15d203e513acf952340wwang 124277d89b08766c878a2594b15d203e513acf952340wwang if (clear) { 124377d89b08766c878a2594b15d203e513acf952340wwang chip->msg_idx = 0; 124477d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < TRACE_ITEM_CNT; i++) 124577d89b08766c878a2594b15d203e513acf952340wwang chip->trace_msg[i].valid = 0; 124677d89b08766c878a2594b15d203e513acf952340wwang } 124777d89b08766c878a2594b15d203e513acf952340wwang 124877d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 124977d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 125077d89b08766c878a2594b15d203e513acf952340wwang} 125177d89b08766c878a2594b15d203e513acf952340wwang#endif 125277d89b08766c878a2594b15d203e513acf952340wwang 125377d89b08766c878a2594b15d203e513acf952340wwangstatic int read_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) 125477d89b08766c878a2594b15d203e513acf952340wwang{ 125577d89b08766c878a2594b15d203e513acf952340wwang u8 addr, buf[4]; 125677d89b08766c878a2594b15d203e513acf952340wwang u32 val; 125777d89b08766c878a2594b15d203e513acf952340wwang unsigned int len; 125877d89b08766c878a2594b15d203e513acf952340wwang 125977d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 126077d89b08766c878a2594b15d203e513acf952340wwang 126177d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 126277d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 126377d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 126477d89b08766c878a2594b15d203e513acf952340wwang } 126577d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 126677d89b08766c878a2594b15d203e513acf952340wwang 126777d89b08766c878a2594b15d203e513acf952340wwang addr = srb->cmnd[4]; 126877d89b08766c878a2594b15d203e513acf952340wwang 126977d89b08766c878a2594b15d203e513acf952340wwang val = rtsx_readl(chip, addr); 127077d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("Host register (0x%x): 0x%x\n", addr, val); 127177d89b08766c878a2594b15d203e513acf952340wwang 127277d89b08766c878a2594b15d203e513acf952340wwang buf[0] = (u8)(val >> 24); 127377d89b08766c878a2594b15d203e513acf952340wwang buf[1] = (u8)(val >> 16); 127477d89b08766c878a2594b15d203e513acf952340wwang buf[2] = (u8)(val >> 8); 127577d89b08766c878a2594b15d203e513acf952340wwang buf[3] = (u8)val; 127677d89b08766c878a2594b15d203e513acf952340wwang 127777d89b08766c878a2594b15d203e513acf952340wwang len = min(scsi_bufflen(srb), (unsigned int)4); 127877d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, len, srb); 127977d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 128077d89b08766c878a2594b15d203e513acf952340wwang 128177d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 128277d89b08766c878a2594b15d203e513acf952340wwang} 128377d89b08766c878a2594b15d203e513acf952340wwang 128477d89b08766c878a2594b15d203e513acf952340wwangstatic int write_host_reg(struct scsi_cmnd *srb, struct rtsx_chip *chip) 128577d89b08766c878a2594b15d203e513acf952340wwang{ 128677d89b08766c878a2594b15d203e513acf952340wwang u8 addr, buf[4]; 128777d89b08766c878a2594b15d203e513acf952340wwang u32 val; 128877d89b08766c878a2594b15d203e513acf952340wwang unsigned int len; 128977d89b08766c878a2594b15d203e513acf952340wwang 129077d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 129177d89b08766c878a2594b15d203e513acf952340wwang 129277d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 129377d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 129477d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 129577d89b08766c878a2594b15d203e513acf952340wwang } 129677d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 129777d89b08766c878a2594b15d203e513acf952340wwang 129877d89b08766c878a2594b15d203e513acf952340wwang addr = srb->cmnd[4]; 129977d89b08766c878a2594b15d203e513acf952340wwang 130077d89b08766c878a2594b15d203e513acf952340wwang len = min(scsi_bufflen(srb), (unsigned int)4); 130177d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_get_xfer_buf(buf, len, srb); 130277d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 130377d89b08766c878a2594b15d203e513acf952340wwang 130477d89b08766c878a2594b15d203e513acf952340wwang val = ((u32)buf[0] << 24) | ((u32)buf[1] << 16) | ((u32)buf[2] << 8) | buf[3]; 130577d89b08766c878a2594b15d203e513acf952340wwang 130677d89b08766c878a2594b15d203e513acf952340wwang rtsx_writel(chip, addr, val); 130777d89b08766c878a2594b15d203e513acf952340wwang 130877d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 130977d89b08766c878a2594b15d203e513acf952340wwang} 131077d89b08766c878a2594b15d203e513acf952340wwang 131177d89b08766c878a2594b15d203e513acf952340wwangstatic int set_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) 131277d89b08766c878a2594b15d203e513acf952340wwang{ 131377d89b08766c878a2594b15d203e513acf952340wwang unsigned lun = SCSI_LUN(srb); 131477d89b08766c878a2594b15d203e513acf952340wwang 131577d89b08766c878a2594b15d203e513acf952340wwang if (srb->cmnd[3] == 1) { 131677d89b08766c878a2594b15d203e513acf952340wwang /* Variable Clock */ 131777d89b08766c878a2594b15d203e513acf952340wwang struct xd_info *xd_card = &(chip->xd_card); 131877d89b08766c878a2594b15d203e513acf952340wwang struct sd_info *sd_card = &(chip->sd_card); 131977d89b08766c878a2594b15d203e513acf952340wwang struct ms_info *ms_card = &(chip->ms_card); 132077d89b08766c878a2594b15d203e513acf952340wwang 132177d89b08766c878a2594b15d203e513acf952340wwang switch (srb->cmnd[4]) { 132277d89b08766c878a2594b15d203e513acf952340wwang case XD_CARD: 132377d89b08766c878a2594b15d203e513acf952340wwang xd_card->xd_clock = srb->cmnd[5]; 132477d89b08766c878a2594b15d203e513acf952340wwang break; 132577d89b08766c878a2594b15d203e513acf952340wwang 132677d89b08766c878a2594b15d203e513acf952340wwang case SD_CARD: 132777d89b08766c878a2594b15d203e513acf952340wwang sd_card->sd_clock = srb->cmnd[5]; 132877d89b08766c878a2594b15d203e513acf952340wwang break; 132977d89b08766c878a2594b15d203e513acf952340wwang 133077d89b08766c878a2594b15d203e513acf952340wwang case MS_CARD: 133177d89b08766c878a2594b15d203e513acf952340wwang ms_card->ms_clock = srb->cmnd[5]; 133277d89b08766c878a2594b15d203e513acf952340wwang break; 133377d89b08766c878a2594b15d203e513acf952340wwang 133477d89b08766c878a2594b15d203e513acf952340wwang default: 133577d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 133677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 133777d89b08766c878a2594b15d203e513acf952340wwang } 133877d89b08766c878a2594b15d203e513acf952340wwang } else if (srb->cmnd[3] == 2) { 133977d89b08766c878a2594b15d203e513acf952340wwang if (srb->cmnd[4]) { 134077d89b08766c878a2594b15d203e513acf952340wwang chip->blink_led = 1; 134177d89b08766c878a2594b15d203e513acf952340wwang } else { 134277d89b08766c878a2594b15d203e513acf952340wwang int retval; 134377d89b08766c878a2594b15d203e513acf952340wwang 134477d89b08766c878a2594b15d203e513acf952340wwang chip->blink_led = 0; 134577d89b08766c878a2594b15d203e513acf952340wwang 134677d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 134777d89b08766c878a2594b15d203e513acf952340wwang 134877d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 134977d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 135077d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 135177d89b08766c878a2594b15d203e513acf952340wwang } 135277d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 135377d89b08766c878a2594b15d203e513acf952340wwang 135477d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 135577d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 135677d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 135777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 135877d89b08766c878a2594b15d203e513acf952340wwang } 135977d89b08766c878a2594b15d203e513acf952340wwang 136077d89b08766c878a2594b15d203e513acf952340wwang turn_off_led(chip, LED_GPIO); 136177d89b08766c878a2594b15d203e513acf952340wwang } 136277d89b08766c878a2594b15d203e513acf952340wwang } else { 136377d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 136477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 136577d89b08766c878a2594b15d203e513acf952340wwang } 136677d89b08766c878a2594b15d203e513acf952340wwang 136777d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 136877d89b08766c878a2594b15d203e513acf952340wwang} 136977d89b08766c878a2594b15d203e513acf952340wwang 137077d89b08766c878a2594b15d203e513acf952340wwangstatic int get_variable(struct scsi_cmnd *srb, struct rtsx_chip *chip) 137177d89b08766c878a2594b15d203e513acf952340wwang{ 137277d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 137377d89b08766c878a2594b15d203e513acf952340wwang 137477d89b08766c878a2594b15d203e513acf952340wwang if (srb->cmnd[3] == 1) { 137577d89b08766c878a2594b15d203e513acf952340wwang struct xd_info *xd_card = &(chip->xd_card); 137677d89b08766c878a2594b15d203e513acf952340wwang struct sd_info *sd_card = &(chip->sd_card); 137777d89b08766c878a2594b15d203e513acf952340wwang struct ms_info *ms_card = &(chip->ms_card); 137877d89b08766c878a2594b15d203e513acf952340wwang u8 tmp; 137977d89b08766c878a2594b15d203e513acf952340wwang 138077d89b08766c878a2594b15d203e513acf952340wwang switch (srb->cmnd[4]) { 138177d89b08766c878a2594b15d203e513acf952340wwang case XD_CARD: 138277d89b08766c878a2594b15d203e513acf952340wwang tmp = (u8)(xd_card->xd_clock); 138377d89b08766c878a2594b15d203e513acf952340wwang break; 138477d89b08766c878a2594b15d203e513acf952340wwang 138577d89b08766c878a2594b15d203e513acf952340wwang case SD_CARD: 138677d89b08766c878a2594b15d203e513acf952340wwang tmp = (u8)(sd_card->sd_clock); 138777d89b08766c878a2594b15d203e513acf952340wwang break; 138877d89b08766c878a2594b15d203e513acf952340wwang 138977d89b08766c878a2594b15d203e513acf952340wwang case MS_CARD: 139077d89b08766c878a2594b15d203e513acf952340wwang tmp = (u8)(ms_card->ms_clock); 139177d89b08766c878a2594b15d203e513acf952340wwang break; 139277d89b08766c878a2594b15d203e513acf952340wwang 139377d89b08766c878a2594b15d203e513acf952340wwang default: 139477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 139577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 139677d89b08766c878a2594b15d203e513acf952340wwang } 139777d89b08766c878a2594b15d203e513acf952340wwang 139877d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(&tmp, 1, srb); 139977d89b08766c878a2594b15d203e513acf952340wwang } else if (srb->cmnd[3] == 2) { 140077d89b08766c878a2594b15d203e513acf952340wwang u8 tmp = chip->blink_led; 140177d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(&tmp, 1, srb); 140277d89b08766c878a2594b15d203e513acf952340wwang } else { 140377d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 140477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 140577d89b08766c878a2594b15d203e513acf952340wwang } 140677d89b08766c878a2594b15d203e513acf952340wwang 140777d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 140877d89b08766c878a2594b15d203e513acf952340wwang} 140977d89b08766c878a2594b15d203e513acf952340wwang 141077d89b08766c878a2594b15d203e513acf952340wwangstatic int dma_access_ring_buffer(struct scsi_cmnd *srb, struct rtsx_chip *chip) 141177d89b08766c878a2594b15d203e513acf952340wwang{ 141277d89b08766c878a2594b15d203e513acf952340wwang int retval; 141377d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 141477d89b08766c878a2594b15d203e513acf952340wwang u16 len; 141577d89b08766c878a2594b15d203e513acf952340wwang 141677d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 141777d89b08766c878a2594b15d203e513acf952340wwang 141877d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 141977d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 142077d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 142177d89b08766c878a2594b15d203e513acf952340wwang } 142277d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 142377d89b08766c878a2594b15d203e513acf952340wwang 142477d89b08766c878a2594b15d203e513acf952340wwang len = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; 142577d89b08766c878a2594b15d203e513acf952340wwang len = min(len, (u16)scsi_bufflen(srb)); 142677d89b08766c878a2594b15d203e513acf952340wwang 142777d89b08766c878a2594b15d203e513acf952340wwang if (srb->sc_data_direction == DMA_FROM_DEVICE) { 142877d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("Read from device\n"); 142977d89b08766c878a2594b15d203e513acf952340wwang } else { 143077d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("Write to device\n"); 143177d89b08766c878a2594b15d203e513acf952340wwang } 143277d89b08766c878a2594b15d203e513acf952340wwang 143377d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_transfer_data(chip, 0, scsi_sglist(srb), len, 143477d89b08766c878a2594b15d203e513acf952340wwang scsi_sg_count(srb), srb->sc_data_direction, 1000); 143577d89b08766c878a2594b15d203e513acf952340wwang if (retval < 0) { 143677d89b08766c878a2594b15d203e513acf952340wwang if (srb->sc_data_direction == DMA_FROM_DEVICE) { 143777d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 143877d89b08766c878a2594b15d203e513acf952340wwang } else { 143977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); 144077d89b08766c878a2594b15d203e513acf952340wwang } 144177d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 144277d89b08766c878a2594b15d203e513acf952340wwang } 144377d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 144477d89b08766c878a2594b15d203e513acf952340wwang 144577d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 144677d89b08766c878a2594b15d203e513acf952340wwang} 144777d89b08766c878a2594b15d203e513acf952340wwang 144877d89b08766c878a2594b15d203e513acf952340wwangstatic int get_dev_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) 144977d89b08766c878a2594b15d203e513acf952340wwang{ 145077d89b08766c878a2594b15d203e513acf952340wwang struct sd_info *sd_card = &(chip->sd_card); 145177d89b08766c878a2594b15d203e513acf952340wwang struct ms_info *ms_card = &(chip->ms_card); 145277d89b08766c878a2594b15d203e513acf952340wwang int buf_len; 145377d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 145477d89b08766c878a2594b15d203e513acf952340wwang u8 card = get_lun_card(chip, lun); 145577d89b08766c878a2594b15d203e513acf952340wwang u8 status[32]; 145677d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_OCP 145777d89b08766c878a2594b15d203e513acf952340wwang u8 oc_now_mask = 0, oc_ever_mask = 0; 145877d89b08766c878a2594b15d203e513acf952340wwang#endif 145977d89b08766c878a2594b15d203e513acf952340wwang 146077d89b08766c878a2594b15d203e513acf952340wwang memset(status, 0, 32); 146177d89b08766c878a2594b15d203e513acf952340wwang 146277d89b08766c878a2594b15d203e513acf952340wwang status[0] = (u8)(chip->product_id); 146377d89b08766c878a2594b15d203e513acf952340wwang status[1] = chip->ic_version; 146477d89b08766c878a2594b15d203e513acf952340wwang 146577d89b08766c878a2594b15d203e513acf952340wwang if (chip->auto_delink_en) { 146677d89b08766c878a2594b15d203e513acf952340wwang status[2] = 0x10; 146777d89b08766c878a2594b15d203e513acf952340wwang } else { 146877d89b08766c878a2594b15d203e513acf952340wwang status[2] = 0x00; 146977d89b08766c878a2594b15d203e513acf952340wwang } 147077d89b08766c878a2594b15d203e513acf952340wwang 147177d89b08766c878a2594b15d203e513acf952340wwang status[3] = 20; 147277d89b08766c878a2594b15d203e513acf952340wwang status[4] = 10; 147377d89b08766c878a2594b15d203e513acf952340wwang status[5] = 05; 147477d89b08766c878a2594b15d203e513acf952340wwang status[6] = 21; 147577d89b08766c878a2594b15d203e513acf952340wwang 147677d89b08766c878a2594b15d203e513acf952340wwang if (chip->card_wp) { 147777d89b08766c878a2594b15d203e513acf952340wwang status[7] = 0x20; 147877d89b08766c878a2594b15d203e513acf952340wwang } else { 147977d89b08766c878a2594b15d203e513acf952340wwang status[7] = 0x00; 148077d89b08766c878a2594b15d203e513acf952340wwang } 148177d89b08766c878a2594b15d203e513acf952340wwang 148277d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_OCP 148377d89b08766c878a2594b15d203e513acf952340wwang status[8] = 0; 148477d89b08766c878a2594b15d203e513acf952340wwang if (CHECK_LUN_MODE(chip, SD_MS_2LUN) && (chip->lun2card[lun] == MS_CARD)) { 148577d89b08766c878a2594b15d203e513acf952340wwang oc_now_mask = MS_OC_NOW; 148677d89b08766c878a2594b15d203e513acf952340wwang oc_ever_mask = MS_OC_EVER; 148777d89b08766c878a2594b15d203e513acf952340wwang } else { 148877d89b08766c878a2594b15d203e513acf952340wwang oc_now_mask = SD_OC_NOW; 148977d89b08766c878a2594b15d203e513acf952340wwang oc_ever_mask = SD_OC_EVER; 149077d89b08766c878a2594b15d203e513acf952340wwang } 149177d89b08766c878a2594b15d203e513acf952340wwang 149277d89b08766c878a2594b15d203e513acf952340wwang if (chip->ocp_stat & oc_now_mask) { 149377d89b08766c878a2594b15d203e513acf952340wwang status[8] |= 0x02; 149477d89b08766c878a2594b15d203e513acf952340wwang } 149577d89b08766c878a2594b15d203e513acf952340wwang if (chip->ocp_stat & oc_ever_mask) { 149677d89b08766c878a2594b15d203e513acf952340wwang status[8] |= 0x01; 149777d89b08766c878a2594b15d203e513acf952340wwang } 149877d89b08766c878a2594b15d203e513acf952340wwang#endif 149977d89b08766c878a2594b15d203e513acf952340wwang 150077d89b08766c878a2594b15d203e513acf952340wwang if (card == SD_CARD) { 150177d89b08766c878a2594b15d203e513acf952340wwang if (CHK_SD(sd_card)) { 150277d89b08766c878a2594b15d203e513acf952340wwang if (CHK_SD_HCXC(sd_card)) { 150377d89b08766c878a2594b15d203e513acf952340wwang if (sd_card->capacity > 0x4000000) { 150477d89b08766c878a2594b15d203e513acf952340wwang status[0x0E] = 0x02; 150577d89b08766c878a2594b15d203e513acf952340wwang } else { 150677d89b08766c878a2594b15d203e513acf952340wwang status[0x0E] = 0x01; 150777d89b08766c878a2594b15d203e513acf952340wwang } 150877d89b08766c878a2594b15d203e513acf952340wwang } else { 150977d89b08766c878a2594b15d203e513acf952340wwang status[0x0E] = 0x00; 151077d89b08766c878a2594b15d203e513acf952340wwang } 151177d89b08766c878a2594b15d203e513acf952340wwang 151277d89b08766c878a2594b15d203e513acf952340wwang if (CHK_SD_SDR104(sd_card)) { 151377d89b08766c878a2594b15d203e513acf952340wwang status[0x0F] = 0x03; 151477d89b08766c878a2594b15d203e513acf952340wwang } else if (CHK_SD_DDR50(sd_card)) { 151577d89b08766c878a2594b15d203e513acf952340wwang status[0x0F] = 0x04; 151677d89b08766c878a2594b15d203e513acf952340wwang } else if (CHK_SD_SDR50(sd_card)) { 151777d89b08766c878a2594b15d203e513acf952340wwang status[0x0F] = 0x02; 151877d89b08766c878a2594b15d203e513acf952340wwang } else if (CHK_SD_HS(sd_card)) { 151977d89b08766c878a2594b15d203e513acf952340wwang status[0x0F] = 0x01; 152077d89b08766c878a2594b15d203e513acf952340wwang } else { 152177d89b08766c878a2594b15d203e513acf952340wwang status[0x0F] = 0x00; 152277d89b08766c878a2594b15d203e513acf952340wwang } 152377d89b08766c878a2594b15d203e513acf952340wwang } else { 152477d89b08766c878a2594b15d203e513acf952340wwang if (CHK_MMC_SECTOR_MODE(sd_card)) { 152577d89b08766c878a2594b15d203e513acf952340wwang status[0x0E] = 0x01; 152677d89b08766c878a2594b15d203e513acf952340wwang } else { 152777d89b08766c878a2594b15d203e513acf952340wwang status[0x0E] = 0x00; 152877d89b08766c878a2594b15d203e513acf952340wwang } 152977d89b08766c878a2594b15d203e513acf952340wwang 153077d89b08766c878a2594b15d203e513acf952340wwang if (CHK_MMC_DDR52(sd_card)) { 153177d89b08766c878a2594b15d203e513acf952340wwang status[0x0F] = 0x03; 153277d89b08766c878a2594b15d203e513acf952340wwang } else if (CHK_MMC_52M(sd_card)) { 153377d89b08766c878a2594b15d203e513acf952340wwang status[0x0F] = 0x02; 153477d89b08766c878a2594b15d203e513acf952340wwang } else if (CHK_MMC_26M(sd_card)) { 153577d89b08766c878a2594b15d203e513acf952340wwang status[0x0F] = 0x01; 153677d89b08766c878a2594b15d203e513acf952340wwang } else { 153777d89b08766c878a2594b15d203e513acf952340wwang status[0x0F] = 0x00; 153877d89b08766c878a2594b15d203e513acf952340wwang } 153977d89b08766c878a2594b15d203e513acf952340wwang } 154077d89b08766c878a2594b15d203e513acf952340wwang } else if (card == MS_CARD) { 154177d89b08766c878a2594b15d203e513acf952340wwang if (CHK_MSPRO(ms_card)) { 154277d89b08766c878a2594b15d203e513acf952340wwang if (CHK_MSXC(ms_card)) { 154377d89b08766c878a2594b15d203e513acf952340wwang status[0x0E] = 0x01; 154477d89b08766c878a2594b15d203e513acf952340wwang } else { 154577d89b08766c878a2594b15d203e513acf952340wwang status[0x0E] = 0x00; 154677d89b08766c878a2594b15d203e513acf952340wwang } 154777d89b08766c878a2594b15d203e513acf952340wwang 154877d89b08766c878a2594b15d203e513acf952340wwang if (CHK_HG8BIT(ms_card)) { 154977d89b08766c878a2594b15d203e513acf952340wwang status[0x0F] = 0x01; 155077d89b08766c878a2594b15d203e513acf952340wwang } else { 155177d89b08766c878a2594b15d203e513acf952340wwang status[0x0F] = 0x00; 155277d89b08766c878a2594b15d203e513acf952340wwang } 155377d89b08766c878a2594b15d203e513acf952340wwang } 155477d89b08766c878a2594b15d203e513acf952340wwang } 155577d89b08766c878a2594b15d203e513acf952340wwang 155677d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_SD_LOCK 155777d89b08766c878a2594b15d203e513acf952340wwang if (card == SD_CARD) { 155877d89b08766c878a2594b15d203e513acf952340wwang status[0x17] = 0x80; 155977d89b08766c878a2594b15d203e513acf952340wwang if (sd_card->sd_erase_status) 156077d89b08766c878a2594b15d203e513acf952340wwang status[0x17] |= 0x01; 156177d89b08766c878a2594b15d203e513acf952340wwang if (sd_card->sd_lock_status & SD_LOCKED) { 156277d89b08766c878a2594b15d203e513acf952340wwang status[0x17] |= 0x02; 156377d89b08766c878a2594b15d203e513acf952340wwang status[0x07] |= 0x40; 156477d89b08766c878a2594b15d203e513acf952340wwang } 156577d89b08766c878a2594b15d203e513acf952340wwang if (sd_card->sd_lock_status & SD_PWD_EXIST) 156677d89b08766c878a2594b15d203e513acf952340wwang status[0x17] |= 0x04; 156777d89b08766c878a2594b15d203e513acf952340wwang } else { 156877d89b08766c878a2594b15d203e513acf952340wwang status[0x17] = 0x00; 156977d89b08766c878a2594b15d203e513acf952340wwang } 157077d89b08766c878a2594b15d203e513acf952340wwang 157177d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("status[0x17] = 0x%x\n", status[0x17]); 157277d89b08766c878a2594b15d203e513acf952340wwang#endif 157377d89b08766c878a2594b15d203e513acf952340wwang 157477d89b08766c878a2594b15d203e513acf952340wwang status[0x18] = 0x8A; 157577d89b08766c878a2594b15d203e513acf952340wwang status[0x1A] = 0x28; 157677d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_SD_LOCK 157777d89b08766c878a2594b15d203e513acf952340wwang status[0x1F] = 0x01; 157877d89b08766c878a2594b15d203e513acf952340wwang#endif 157977d89b08766c878a2594b15d203e513acf952340wwang 158077d89b08766c878a2594b15d203e513acf952340wwang buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(status)); 158177d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(status, buf_len, srb); 158277d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); 158377d89b08766c878a2594b15d203e513acf952340wwang 158477d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 158577d89b08766c878a2594b15d203e513acf952340wwang} 158677d89b08766c878a2594b15d203e513acf952340wwang 158777d89b08766c878a2594b15d203e513acf952340wwangstatic int set_chip_mode(struct scsi_cmnd *srb, struct rtsx_chip *chip) 158877d89b08766c878a2594b15d203e513acf952340wwang{ 158977d89b08766c878a2594b15d203e513acf952340wwang int phy_debug_mode; 159077d89b08766c878a2594b15d203e513acf952340wwang int retval; 159177d89b08766c878a2594b15d203e513acf952340wwang u16 reg; 159277d89b08766c878a2594b15d203e513acf952340wwang 159377d89b08766c878a2594b15d203e513acf952340wwang if (!CHECK_PID(chip, 0x5208)) { 159477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 159577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 159677d89b08766c878a2594b15d203e513acf952340wwang } 159777d89b08766c878a2594b15d203e513acf952340wwang 159877d89b08766c878a2594b15d203e513acf952340wwang phy_debug_mode = (int)(srb->cmnd[3]); 159977d89b08766c878a2594b15d203e513acf952340wwang 160077d89b08766c878a2594b15d203e513acf952340wwang if (phy_debug_mode) { 160177d89b08766c878a2594b15d203e513acf952340wwang chip->phy_debug_mode = 1; 160277d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0); 160377d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 160477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 160577d89b08766c878a2594b15d203e513acf952340wwang } 160677d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_bus_int(chip); 160777d89b08766c878a2594b15d203e513acf952340wwang 160877d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_read_phy_register(chip, 0x1C, ®); 160977d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 161077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 161177d89b08766c878a2594b15d203e513acf952340wwang } 161277d89b08766c878a2594b15d203e513acf952340wwang reg |= 0x0001; 161377d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_phy_register(chip, 0x1C, reg); 161477d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 161577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 161677d89b08766c878a2594b15d203e513acf952340wwang } 161777d89b08766c878a2594b15d203e513acf952340wwang } else { 161877d89b08766c878a2594b15d203e513acf952340wwang chip->phy_debug_mode = 0; 161977d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_register(chip, CDRESUMECTL, 0x77, 0x77); 162077d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 162177d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 162277d89b08766c878a2594b15d203e513acf952340wwang } 162377d89b08766c878a2594b15d203e513acf952340wwang rtsx_enable_bus_int(chip); 162477d89b08766c878a2594b15d203e513acf952340wwang 162577d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_read_phy_register(chip, 0x1C, ®); 162677d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 162777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 162877d89b08766c878a2594b15d203e513acf952340wwang } 162977d89b08766c878a2594b15d203e513acf952340wwang reg &= 0xFFFE; 163077d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_phy_register(chip, 0x1C, reg); 163177d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 163277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 163377d89b08766c878a2594b15d203e513acf952340wwang } 163477d89b08766c878a2594b15d203e513acf952340wwang } 163577d89b08766c878a2594b15d203e513acf952340wwang 163677d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 163777d89b08766c878a2594b15d203e513acf952340wwang} 163877d89b08766c878a2594b15d203e513acf952340wwang 163977d89b08766c878a2594b15d203e513acf952340wwangstatic int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rtsx_chip *chip) 164077d89b08766c878a2594b15d203e513acf952340wwang{ 164177d89b08766c878a2594b15d203e513acf952340wwang int retval = STATUS_SUCCESS; 164277d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 164377d89b08766c878a2594b15d203e513acf952340wwang u8 cmd_type, mask, value, idx; 164477d89b08766c878a2594b15d203e513acf952340wwang u16 addr; 164577d89b08766c878a2594b15d203e513acf952340wwang 164677d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 164777d89b08766c878a2594b15d203e513acf952340wwang 164877d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 164977d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 165077d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 165177d89b08766c878a2594b15d203e513acf952340wwang } 165277d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 165377d89b08766c878a2594b15d203e513acf952340wwang 165477d89b08766c878a2594b15d203e513acf952340wwang switch (srb->cmnd[3]) { 165577d89b08766c878a2594b15d203e513acf952340wwang case INIT_BATCHCMD: 165677d89b08766c878a2594b15d203e513acf952340wwang rtsx_init_cmd(chip); 165777d89b08766c878a2594b15d203e513acf952340wwang break; 165877d89b08766c878a2594b15d203e513acf952340wwang 165977d89b08766c878a2594b15d203e513acf952340wwang case ADD_BATCHCMD: 166077d89b08766c878a2594b15d203e513acf952340wwang cmd_type = srb->cmnd[4]; 166177d89b08766c878a2594b15d203e513acf952340wwang if (cmd_type > 2) { 166277d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 166377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 166477d89b08766c878a2594b15d203e513acf952340wwang } 166577d89b08766c878a2594b15d203e513acf952340wwang addr = (srb->cmnd[5] << 8) | srb->cmnd[6]; 166677d89b08766c878a2594b15d203e513acf952340wwang mask = srb->cmnd[7]; 166777d89b08766c878a2594b15d203e513acf952340wwang value = srb->cmnd[8]; 166877d89b08766c878a2594b15d203e513acf952340wwang rtsx_add_cmd(chip, cmd_type, addr, mask, value); 166977d89b08766c878a2594b15d203e513acf952340wwang break; 167077d89b08766c878a2594b15d203e513acf952340wwang 167177d89b08766c878a2594b15d203e513acf952340wwang case SEND_BATCHCMD: 167277d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_send_cmd(chip, 0, 1000); 167377d89b08766c878a2594b15d203e513acf952340wwang break; 167477d89b08766c878a2594b15d203e513acf952340wwang 167577d89b08766c878a2594b15d203e513acf952340wwang case GET_BATCHRSP: 167677d89b08766c878a2594b15d203e513acf952340wwang idx = srb->cmnd[4]; 167777d89b08766c878a2594b15d203e513acf952340wwang value = *(rtsx_get_cmd_data(chip) + idx); 167877d89b08766c878a2594b15d203e513acf952340wwang if (scsi_bufflen(srb) < 1) { 167977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 168077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 168177d89b08766c878a2594b15d203e513acf952340wwang } 168277d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(&value, 1, srb); 168377d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 168477d89b08766c878a2594b15d203e513acf952340wwang break; 168577d89b08766c878a2594b15d203e513acf952340wwang 168677d89b08766c878a2594b15d203e513acf952340wwang default: 168777d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 168877d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 168977d89b08766c878a2594b15d203e513acf952340wwang } 169077d89b08766c878a2594b15d203e513acf952340wwang 169177d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 169277d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); 169377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 169477d89b08766c878a2594b15d203e513acf952340wwang } 169577d89b08766c878a2594b15d203e513acf952340wwang 169677d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 169777d89b08766c878a2594b15d203e513acf952340wwang} 169877d89b08766c878a2594b15d203e513acf952340wwang 169977d89b08766c878a2594b15d203e513acf952340wwangstatic int suit_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) 170077d89b08766c878a2594b15d203e513acf952340wwang{ 170177d89b08766c878a2594b15d203e513acf952340wwang int result; 170277d89b08766c878a2594b15d203e513acf952340wwang 170377d89b08766c878a2594b15d203e513acf952340wwang switch (srb->cmnd[3]) { 170477d89b08766c878a2594b15d203e513acf952340wwang case INIT_BATCHCMD: 170577d89b08766c878a2594b15d203e513acf952340wwang case ADD_BATCHCMD: 170677d89b08766c878a2594b15d203e513acf952340wwang case SEND_BATCHCMD: 170777d89b08766c878a2594b15d203e513acf952340wwang case GET_BATCHRSP: 170877d89b08766c878a2594b15d203e513acf952340wwang result = rw_mem_cmd_buf(srb, chip); 170977d89b08766c878a2594b15d203e513acf952340wwang break; 171077d89b08766c878a2594b15d203e513acf952340wwang default: 171177d89b08766c878a2594b15d203e513acf952340wwang result = TRANSPORT_ERROR; 171277d89b08766c878a2594b15d203e513acf952340wwang } 171377d89b08766c878a2594b15d203e513acf952340wwang 171477d89b08766c878a2594b15d203e513acf952340wwang return result; 171577d89b08766c878a2594b15d203e513acf952340wwang} 171677d89b08766c878a2594b15d203e513acf952340wwang 171777d89b08766c878a2594b15d203e513acf952340wwangstatic int read_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) 171877d89b08766c878a2594b15d203e513acf952340wwang{ 171977d89b08766c878a2594b15d203e513acf952340wwang unsigned short addr, len, i; 172077d89b08766c878a2594b15d203e513acf952340wwang int retval; 172177d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 172277d89b08766c878a2594b15d203e513acf952340wwang u16 val; 172377d89b08766c878a2594b15d203e513acf952340wwang 172477d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 172577d89b08766c878a2594b15d203e513acf952340wwang 172677d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 172777d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 172877d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 172977d89b08766c878a2594b15d203e513acf952340wwang } 173077d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 173177d89b08766c878a2594b15d203e513acf952340wwang 173277d89b08766c878a2594b15d203e513acf952340wwang addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; 173377d89b08766c878a2594b15d203e513acf952340wwang len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; 173477d89b08766c878a2594b15d203e513acf952340wwang 173577d89b08766c878a2594b15d203e513acf952340wwang if (len % 2) 173677d89b08766c878a2594b15d203e513acf952340wwang len -= len % 2; 173777d89b08766c878a2594b15d203e513acf952340wwang 173877d89b08766c878a2594b15d203e513acf952340wwang if (len) { 173977d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 174077d89b08766c878a2594b15d203e513acf952340wwang if (!buf) { 174177d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 174277d89b08766c878a2594b15d203e513acf952340wwang } 174377d89b08766c878a2594b15d203e513acf952340wwang 174477d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 174577d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 174677d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 174777d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 174877d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 174977d89b08766c878a2594b15d203e513acf952340wwang } 175077d89b08766c878a2594b15d203e513acf952340wwang 175177d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < len / 2; i++) { 175277d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_read_phy_register(chip, addr + i, &val); 175377d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 175477d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 175577d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 175677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 175777d89b08766c878a2594b15d203e513acf952340wwang } 175877d89b08766c878a2594b15d203e513acf952340wwang 175977d89b08766c878a2594b15d203e513acf952340wwang buf[2*i] = (u8)(val >> 8); 176077d89b08766c878a2594b15d203e513acf952340wwang buf[2*i+1] = (u8)val; 176177d89b08766c878a2594b15d203e513acf952340wwang } 176277d89b08766c878a2594b15d203e513acf952340wwang 176377d89b08766c878a2594b15d203e513acf952340wwang len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); 176477d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, len, srb); 176577d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 176677d89b08766c878a2594b15d203e513acf952340wwang 176777d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 176877d89b08766c878a2594b15d203e513acf952340wwang } 176977d89b08766c878a2594b15d203e513acf952340wwang 177077d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 177177d89b08766c878a2594b15d203e513acf952340wwang} 177277d89b08766c878a2594b15d203e513acf952340wwang 177377d89b08766c878a2594b15d203e513acf952340wwangstatic int write_phy_register(struct scsi_cmnd *srb, struct rtsx_chip *chip) 177477d89b08766c878a2594b15d203e513acf952340wwang{ 177577d89b08766c878a2594b15d203e513acf952340wwang unsigned short addr, len, i; 177677d89b08766c878a2594b15d203e513acf952340wwang int retval; 177777d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 177877d89b08766c878a2594b15d203e513acf952340wwang u16 val; 177977d89b08766c878a2594b15d203e513acf952340wwang 178077d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 178177d89b08766c878a2594b15d203e513acf952340wwang 178277d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 178377d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 178477d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 178577d89b08766c878a2594b15d203e513acf952340wwang } 178677d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 178777d89b08766c878a2594b15d203e513acf952340wwang 178877d89b08766c878a2594b15d203e513acf952340wwang addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; 178977d89b08766c878a2594b15d203e513acf952340wwang len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; 179077d89b08766c878a2594b15d203e513acf952340wwang 179177d89b08766c878a2594b15d203e513acf952340wwang if (len % 2) 179277d89b08766c878a2594b15d203e513acf952340wwang len -= len % 2; 179377d89b08766c878a2594b15d203e513acf952340wwang 179477d89b08766c878a2594b15d203e513acf952340wwang if (len) { 179577d89b08766c878a2594b15d203e513acf952340wwang len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); 179677d89b08766c878a2594b15d203e513acf952340wwang 179777d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 179877d89b08766c878a2594b15d203e513acf952340wwang if (buf == NULL) { 179977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 180077d89b08766c878a2594b15d203e513acf952340wwang } 180177d89b08766c878a2594b15d203e513acf952340wwang 180277d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_get_xfer_buf(buf, len, srb); 180377d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 180477d89b08766c878a2594b15d203e513acf952340wwang 180577d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 180677d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 180777d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 180877d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 180977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 181077d89b08766c878a2594b15d203e513acf952340wwang } 181177d89b08766c878a2594b15d203e513acf952340wwang 181277d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < len / 2; i++) { 181377d89b08766c878a2594b15d203e513acf952340wwang val = ((u16)buf[2*i] << 8) | buf[2*i+1]; 181477d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_phy_register(chip, addr + i, val); 181577d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 181677d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 181777d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 181877d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 181977d89b08766c878a2594b15d203e513acf952340wwang } 182077d89b08766c878a2594b15d203e513acf952340wwang } 182177d89b08766c878a2594b15d203e513acf952340wwang 182277d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 182377d89b08766c878a2594b15d203e513acf952340wwang } 182477d89b08766c878a2594b15d203e513acf952340wwang 182577d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 182677d89b08766c878a2594b15d203e513acf952340wwang} 182777d89b08766c878a2594b15d203e513acf952340wwang 182877d89b08766c878a2594b15d203e513acf952340wwangstatic int erase_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) 182977d89b08766c878a2594b15d203e513acf952340wwang{ 183077d89b08766c878a2594b15d203e513acf952340wwang unsigned short addr; 183177d89b08766c878a2594b15d203e513acf952340wwang int retval; 183277d89b08766c878a2594b15d203e513acf952340wwang u8 mode; 183377d89b08766c878a2594b15d203e513acf952340wwang 183477d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 183577d89b08766c878a2594b15d203e513acf952340wwang 183677d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 183777d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 183877d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 183977d89b08766c878a2594b15d203e513acf952340wwang } 184077d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 184177d89b08766c878a2594b15d203e513acf952340wwang 184277d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 184377d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 184477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 184577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 184677d89b08766c878a2594b15d203e513acf952340wwang } 184777d89b08766c878a2594b15d203e513acf952340wwang 184877d89b08766c878a2594b15d203e513acf952340wwang mode = srb->cmnd[3]; 184977d89b08766c878a2594b15d203e513acf952340wwang addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; 185077d89b08766c878a2594b15d203e513acf952340wwang 185177d89b08766c878a2594b15d203e513acf952340wwang if (mode == 0) { 185277d89b08766c878a2594b15d203e513acf952340wwang retval = spi_erase_eeprom_chip(chip); 185377d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 185477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 185577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 185677d89b08766c878a2594b15d203e513acf952340wwang } 185777d89b08766c878a2594b15d203e513acf952340wwang } else if (mode == 1) { 185877d89b08766c878a2594b15d203e513acf952340wwang retval = spi_erase_eeprom_byte(chip, addr); 185977d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 186077d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 186177d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 186277d89b08766c878a2594b15d203e513acf952340wwang } 186377d89b08766c878a2594b15d203e513acf952340wwang } else { 186477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 186577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 186677d89b08766c878a2594b15d203e513acf952340wwang } 186777d89b08766c878a2594b15d203e513acf952340wwang 186877d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 186977d89b08766c878a2594b15d203e513acf952340wwang} 187077d89b08766c878a2594b15d203e513acf952340wwang 187177d89b08766c878a2594b15d203e513acf952340wwangstatic int read_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) 187277d89b08766c878a2594b15d203e513acf952340wwang{ 187377d89b08766c878a2594b15d203e513acf952340wwang unsigned short addr, len, i; 187477d89b08766c878a2594b15d203e513acf952340wwang int retval; 187577d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 187677d89b08766c878a2594b15d203e513acf952340wwang 187777d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 187877d89b08766c878a2594b15d203e513acf952340wwang 187977d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 188077d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 188177d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 188277d89b08766c878a2594b15d203e513acf952340wwang } 188377d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 188477d89b08766c878a2594b15d203e513acf952340wwang 188577d89b08766c878a2594b15d203e513acf952340wwang addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; 188677d89b08766c878a2594b15d203e513acf952340wwang len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; 188777d89b08766c878a2594b15d203e513acf952340wwang 188877d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 188977d89b08766c878a2594b15d203e513acf952340wwang if (!buf) { 189077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 189177d89b08766c878a2594b15d203e513acf952340wwang } 189277d89b08766c878a2594b15d203e513acf952340wwang 189377d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 189477d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 189577d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 189677d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 189777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 189877d89b08766c878a2594b15d203e513acf952340wwang } 189977d89b08766c878a2594b15d203e513acf952340wwang 190077d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < len; i++) { 190177d89b08766c878a2594b15d203e513acf952340wwang retval = spi_read_eeprom(chip, addr + i, buf + i); 190277d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 190377d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 190477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 190577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 190677d89b08766c878a2594b15d203e513acf952340wwang } 190777d89b08766c878a2594b15d203e513acf952340wwang } 190877d89b08766c878a2594b15d203e513acf952340wwang 190977d89b08766c878a2594b15d203e513acf952340wwang len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); 191077d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, len, srb); 191177d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 191277d89b08766c878a2594b15d203e513acf952340wwang 191377d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 191477d89b08766c878a2594b15d203e513acf952340wwang 191577d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 191677d89b08766c878a2594b15d203e513acf952340wwang} 191777d89b08766c878a2594b15d203e513acf952340wwang 191877d89b08766c878a2594b15d203e513acf952340wwangstatic int write_eeprom2(struct scsi_cmnd *srb, struct rtsx_chip *chip) 191977d89b08766c878a2594b15d203e513acf952340wwang{ 192077d89b08766c878a2594b15d203e513acf952340wwang unsigned short addr, len, i; 192177d89b08766c878a2594b15d203e513acf952340wwang int retval; 192277d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 192377d89b08766c878a2594b15d203e513acf952340wwang 192477d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 192577d89b08766c878a2594b15d203e513acf952340wwang 192677d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 192777d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 192877d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 192977d89b08766c878a2594b15d203e513acf952340wwang } 193077d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 193177d89b08766c878a2594b15d203e513acf952340wwang 193277d89b08766c878a2594b15d203e513acf952340wwang addr = ((u16)srb->cmnd[4] << 8) | srb->cmnd[5]; 193377d89b08766c878a2594b15d203e513acf952340wwang len = ((u16)srb->cmnd[6] << 8) | srb->cmnd[7]; 193477d89b08766c878a2594b15d203e513acf952340wwang 193577d89b08766c878a2594b15d203e513acf952340wwang len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); 193677d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 193777d89b08766c878a2594b15d203e513acf952340wwang if (buf == NULL) { 193877d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 193977d89b08766c878a2594b15d203e513acf952340wwang } 194077d89b08766c878a2594b15d203e513acf952340wwang 194177d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_get_xfer_buf(buf, len, srb); 194277d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 194377d89b08766c878a2594b15d203e513acf952340wwang 194477d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 194577d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 194677d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 194777d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 194877d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 194977d89b08766c878a2594b15d203e513acf952340wwang } 195077d89b08766c878a2594b15d203e513acf952340wwang 195177d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < len; i++) { 195277d89b08766c878a2594b15d203e513acf952340wwang retval = spi_write_eeprom(chip, addr + i, buf[i]); 195377d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 195477d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 195577d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 195677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 195777d89b08766c878a2594b15d203e513acf952340wwang } 195877d89b08766c878a2594b15d203e513acf952340wwang } 195977d89b08766c878a2594b15d203e513acf952340wwang 196077d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 196177d89b08766c878a2594b15d203e513acf952340wwang 196277d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 196377d89b08766c878a2594b15d203e513acf952340wwang} 196477d89b08766c878a2594b15d203e513acf952340wwang 196577d89b08766c878a2594b15d203e513acf952340wwangstatic int read_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) 196677d89b08766c878a2594b15d203e513acf952340wwang{ 196777d89b08766c878a2594b15d203e513acf952340wwang int retval; 196877d89b08766c878a2594b15d203e513acf952340wwang u8 addr, len, i; 196977d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 197077d89b08766c878a2594b15d203e513acf952340wwang 197177d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 197277d89b08766c878a2594b15d203e513acf952340wwang 197377d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 197477d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 197577d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 197677d89b08766c878a2594b15d203e513acf952340wwang } 197777d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 197877d89b08766c878a2594b15d203e513acf952340wwang 197977d89b08766c878a2594b15d203e513acf952340wwang addr = srb->cmnd[4]; 198077d89b08766c878a2594b15d203e513acf952340wwang len = srb->cmnd[5]; 198177d89b08766c878a2594b15d203e513acf952340wwang 198277d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 198377d89b08766c878a2594b15d203e513acf952340wwang if (!buf) { 198477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 198577d89b08766c878a2594b15d203e513acf952340wwang } 198677d89b08766c878a2594b15d203e513acf952340wwang 198777d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 198877d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 198977d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 199077d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 199177d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 199277d89b08766c878a2594b15d203e513acf952340wwang } 199377d89b08766c878a2594b15d203e513acf952340wwang 199477d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < len; i++) { 199577d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_read_efuse(chip, addr + i, buf + i); 199677d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 199777d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 199877d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 199977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 200077d89b08766c878a2594b15d203e513acf952340wwang } 200177d89b08766c878a2594b15d203e513acf952340wwang } 200277d89b08766c878a2594b15d203e513acf952340wwang 200377d89b08766c878a2594b15d203e513acf952340wwang len = (u8)min(scsi_bufflen(srb), (unsigned int)len); 200477d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, len, srb); 200577d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 200677d89b08766c878a2594b15d203e513acf952340wwang 200777d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 200877d89b08766c878a2594b15d203e513acf952340wwang 200977d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 201077d89b08766c878a2594b15d203e513acf952340wwang} 201177d89b08766c878a2594b15d203e513acf952340wwang 201277d89b08766c878a2594b15d203e513acf952340wwangstatic int write_efuse(struct scsi_cmnd *srb, struct rtsx_chip *chip) 201377d89b08766c878a2594b15d203e513acf952340wwang{ 201477d89b08766c878a2594b15d203e513acf952340wwang int retval, result = TRANSPORT_GOOD; 201577d89b08766c878a2594b15d203e513acf952340wwang u16 val; 201677d89b08766c878a2594b15d203e513acf952340wwang u8 addr, len, i; 201777d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 201877d89b08766c878a2594b15d203e513acf952340wwang 201977d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 202077d89b08766c878a2594b15d203e513acf952340wwang 202177d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 202277d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 202377d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 202477d89b08766c878a2594b15d203e513acf952340wwang } 202577d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 202677d89b08766c878a2594b15d203e513acf952340wwang 202777d89b08766c878a2594b15d203e513acf952340wwang addr = srb->cmnd[4]; 202877d89b08766c878a2594b15d203e513acf952340wwang len = srb->cmnd[5]; 202977d89b08766c878a2594b15d203e513acf952340wwang 203077d89b08766c878a2594b15d203e513acf952340wwang len = (u8)min(scsi_bufflen(srb), (unsigned int)len); 203177d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 203277d89b08766c878a2594b15d203e513acf952340wwang if (buf == NULL) { 203377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 203477d89b08766c878a2594b15d203e513acf952340wwang } 203577d89b08766c878a2594b15d203e513acf952340wwang 203677d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_get_xfer_buf(buf, len, srb); 203777d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 203877d89b08766c878a2594b15d203e513acf952340wwang 203977d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_force_power_on(chip, SSC_PDCTL); 204077d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 204177d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 204277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 204377d89b08766c878a2594b15d203e513acf952340wwang } 204477d89b08766c878a2594b15d203e513acf952340wwang 204577d89b08766c878a2594b15d203e513acf952340wwang if (chip->asic_code) { 204677d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_read_phy_register(chip, 0x08, &val); 204777d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 204877d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 204977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 205077d89b08766c878a2594b15d203e513acf952340wwang } 205177d89b08766c878a2594b15d203e513acf952340wwang 205277d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); 205377d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 205477d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 205577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 205677d89b08766c878a2594b15d203e513acf952340wwang } 205777d89b08766c878a2594b15d203e513acf952340wwang 205877d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(600); 205977d89b08766c878a2594b15d203e513acf952340wwang 206077d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_phy_register(chip, 0x08, 0x4C00 | chip->phy_voltage); 206177d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 206277d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 206377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 206477d89b08766c878a2594b15d203e513acf952340wwang } 206577d89b08766c878a2594b15d203e513acf952340wwang 206677d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); 206777d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 206877d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 206977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 207077d89b08766c878a2594b15d203e513acf952340wwang } 207177d89b08766c878a2594b15d203e513acf952340wwang 207277d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(600); 207377d89b08766c878a2594b15d203e513acf952340wwang } 207477d89b08766c878a2594b15d203e513acf952340wwang 207577d89b08766c878a2594b15d203e513acf952340wwang retval = card_power_on(chip, SPI_CARD); 207677d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 207777d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 207877d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 207977d89b08766c878a2594b15d203e513acf952340wwang } 208077d89b08766c878a2594b15d203e513acf952340wwang 208177d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(50); 208277d89b08766c878a2594b15d203e513acf952340wwang 208377d89b08766c878a2594b15d203e513acf952340wwang for (i = 0; i < len; i++) { 208477d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_efuse(chip, addr + i, buf[i]); 208577d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 208677d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 208777d89b08766c878a2594b15d203e513acf952340wwang result = TRANSPORT_FAILED; 208877d89b08766c878a2594b15d203e513acf952340wwang TRACE_GOTO(chip, Exit); 208977d89b08766c878a2594b15d203e513acf952340wwang } 209077d89b08766c878a2594b15d203e513acf952340wwang } 209177d89b08766c878a2594b15d203e513acf952340wwang 209277d89b08766c878a2594b15d203e513acf952340wwangExit: 209377d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 209477d89b08766c878a2594b15d203e513acf952340wwang 209577d89b08766c878a2594b15d203e513acf952340wwang retval = card_power_off(chip, SPI_CARD); 209677d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 209777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 209877d89b08766c878a2594b15d203e513acf952340wwang } 209977d89b08766c878a2594b15d203e513acf952340wwang 210077d89b08766c878a2594b15d203e513acf952340wwang if (chip->asic_code) { 210177d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_OFF); 210277d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 210377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 210477d89b08766c878a2594b15d203e513acf952340wwang } 210577d89b08766c878a2594b15d203e513acf952340wwang 210677d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(600); 210777d89b08766c878a2594b15d203e513acf952340wwang 210877d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_phy_register(chip, 0x08, val); 210977d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 211077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 211177d89b08766c878a2594b15d203e513acf952340wwang } 211277d89b08766c878a2594b15d203e513acf952340wwang 211377d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_register(chip, PWR_GATE_CTRL, LDO3318_PWR_MASK, LDO_ON); 211477d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 211577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 211677d89b08766c878a2594b15d203e513acf952340wwang } 211777d89b08766c878a2594b15d203e513acf952340wwang } 211877d89b08766c878a2594b15d203e513acf952340wwang 211977d89b08766c878a2594b15d203e513acf952340wwang return result; 212077d89b08766c878a2594b15d203e513acf952340wwang} 212177d89b08766c878a2594b15d203e513acf952340wwang 212277d89b08766c878a2594b15d203e513acf952340wwangstatic int read_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) 212377d89b08766c878a2594b15d203e513acf952340wwang{ 212477d89b08766c878a2594b15d203e513acf952340wwang int retval; 212577d89b08766c878a2594b15d203e513acf952340wwang u8 func, func_max; 212677d89b08766c878a2594b15d203e513acf952340wwang u16 addr, len; 212777d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 212877d89b08766c878a2594b15d203e513acf952340wwang 212977d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 213077d89b08766c878a2594b15d203e513acf952340wwang 213177d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 213277d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 213377d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 213477d89b08766c878a2594b15d203e513acf952340wwang } 213577d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 213677d89b08766c878a2594b15d203e513acf952340wwang 213777d89b08766c878a2594b15d203e513acf952340wwang func = srb->cmnd[3]; 213877d89b08766c878a2594b15d203e513acf952340wwang addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; 213977d89b08766c878a2594b15d203e513acf952340wwang len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; 214077d89b08766c878a2594b15d203e513acf952340wwang 214177d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("%s: func = %d, addr = 0x%x, len = %d\n", __func__, func, addr, len); 214277d89b08766c878a2594b15d203e513acf952340wwang 214377d89b08766c878a2594b15d203e513acf952340wwang if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { 214477d89b08766c878a2594b15d203e513acf952340wwang func_max = 1; 214577d89b08766c878a2594b15d203e513acf952340wwang } else { 214677d89b08766c878a2594b15d203e513acf952340wwang func_max = 0; 214777d89b08766c878a2594b15d203e513acf952340wwang } 214877d89b08766c878a2594b15d203e513acf952340wwang 214977d89b08766c878a2594b15d203e513acf952340wwang if (func > func_max) { 215077d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 215177d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 215277d89b08766c878a2594b15d203e513acf952340wwang } 215377d89b08766c878a2594b15d203e513acf952340wwang 215477d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 215577d89b08766c878a2594b15d203e513acf952340wwang if (!buf) { 215677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 215777d89b08766c878a2594b15d203e513acf952340wwang } 215877d89b08766c878a2594b15d203e513acf952340wwang 215977d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_read_cfg_seq(chip, func, addr, buf, len); 216077d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 216177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 216277d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 216377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 216477d89b08766c878a2594b15d203e513acf952340wwang } 216577d89b08766c878a2594b15d203e513acf952340wwang 216677d89b08766c878a2594b15d203e513acf952340wwang len = (u16)min(scsi_bufflen(srb), (unsigned int)len); 216777d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, len, srb); 216877d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 216977d89b08766c878a2594b15d203e513acf952340wwang 217077d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 217177d89b08766c878a2594b15d203e513acf952340wwang 217277d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 217377d89b08766c878a2594b15d203e513acf952340wwang} 217477d89b08766c878a2594b15d203e513acf952340wwang 217577d89b08766c878a2594b15d203e513acf952340wwangstatic int write_cfg_byte(struct scsi_cmnd *srb, struct rtsx_chip *chip) 217677d89b08766c878a2594b15d203e513acf952340wwang{ 217777d89b08766c878a2594b15d203e513acf952340wwang int retval; 217877d89b08766c878a2594b15d203e513acf952340wwang u8 func, func_max; 217977d89b08766c878a2594b15d203e513acf952340wwang u16 addr, len; 218077d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 218177d89b08766c878a2594b15d203e513acf952340wwang 218277d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 218377d89b08766c878a2594b15d203e513acf952340wwang 218477d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 218577d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 218677d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 218777d89b08766c878a2594b15d203e513acf952340wwang } 218877d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 218977d89b08766c878a2594b15d203e513acf952340wwang 219077d89b08766c878a2594b15d203e513acf952340wwang func = srb->cmnd[3]; 219177d89b08766c878a2594b15d203e513acf952340wwang addr = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5]; 219277d89b08766c878a2594b15d203e513acf952340wwang len = ((u16)(srb->cmnd[6]) << 8) | srb->cmnd[7]; 219377d89b08766c878a2594b15d203e513acf952340wwang 219477d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("%s: func = %d, addr = 0x%x\n", __func__, func, addr); 219577d89b08766c878a2594b15d203e513acf952340wwang 219677d89b08766c878a2594b15d203e513acf952340wwang if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { 219777d89b08766c878a2594b15d203e513acf952340wwang func_max = 1; 219877d89b08766c878a2594b15d203e513acf952340wwang } else { 219977d89b08766c878a2594b15d203e513acf952340wwang func_max = 0; 220077d89b08766c878a2594b15d203e513acf952340wwang } 220177d89b08766c878a2594b15d203e513acf952340wwang 220277d89b08766c878a2594b15d203e513acf952340wwang if (func > func_max) { 220377d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 220477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 220577d89b08766c878a2594b15d203e513acf952340wwang } 220677d89b08766c878a2594b15d203e513acf952340wwang 220777d89b08766c878a2594b15d203e513acf952340wwang len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); 220877d89b08766c878a2594b15d203e513acf952340wwang buf = (u8 *)vmalloc(len); 220977d89b08766c878a2594b15d203e513acf952340wwang if (!buf) { 221077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 221177d89b08766c878a2594b15d203e513acf952340wwang } 221277d89b08766c878a2594b15d203e513acf952340wwang 221377d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_get_xfer_buf(buf, len, srb); 221477d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - len); 221577d89b08766c878a2594b15d203e513acf952340wwang 221677d89b08766c878a2594b15d203e513acf952340wwang retval = rtsx_write_cfg_seq(chip, func, addr, buf, len); 221777d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 221877d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); 221977d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 222077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 222177d89b08766c878a2594b15d203e513acf952340wwang } 222277d89b08766c878a2594b15d203e513acf952340wwang 222377d89b08766c878a2594b15d203e513acf952340wwang vfree(buf); 222477d89b08766c878a2594b15d203e513acf952340wwang 222577d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 222677d89b08766c878a2594b15d203e513acf952340wwang} 222777d89b08766c878a2594b15d203e513acf952340wwang 222877d89b08766c878a2594b15d203e513acf952340wwangstatic int app_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) 222977d89b08766c878a2594b15d203e513acf952340wwang{ 223077d89b08766c878a2594b15d203e513acf952340wwang int result; 223177d89b08766c878a2594b15d203e513acf952340wwang 223277d89b08766c878a2594b15d203e513acf952340wwang switch (srb->cmnd[2]) { 223377d89b08766c878a2594b15d203e513acf952340wwang case PP_READ10: 223477d89b08766c878a2594b15d203e513acf952340wwang case PP_WRITE10: 223577d89b08766c878a2594b15d203e513acf952340wwang result = read_write(srb, chip); 223677d89b08766c878a2594b15d203e513acf952340wwang break; 223777d89b08766c878a2594b15d203e513acf952340wwang 223877d89b08766c878a2594b15d203e513acf952340wwang case READ_HOST_REG: 223977d89b08766c878a2594b15d203e513acf952340wwang result = read_host_reg(srb, chip); 224077d89b08766c878a2594b15d203e513acf952340wwang break; 224177d89b08766c878a2594b15d203e513acf952340wwang 224277d89b08766c878a2594b15d203e513acf952340wwang case WRITE_HOST_REG: 224377d89b08766c878a2594b15d203e513acf952340wwang result = write_host_reg(srb, chip); 224477d89b08766c878a2594b15d203e513acf952340wwang break; 224577d89b08766c878a2594b15d203e513acf952340wwang 224677d89b08766c878a2594b15d203e513acf952340wwang case GET_VAR: 224777d89b08766c878a2594b15d203e513acf952340wwang result = get_variable(srb, chip); 224877d89b08766c878a2594b15d203e513acf952340wwang break; 224977d89b08766c878a2594b15d203e513acf952340wwang 225077d89b08766c878a2594b15d203e513acf952340wwang case SET_VAR: 225177d89b08766c878a2594b15d203e513acf952340wwang result = set_variable(srb, chip); 225277d89b08766c878a2594b15d203e513acf952340wwang break; 225377d89b08766c878a2594b15d203e513acf952340wwang 225477d89b08766c878a2594b15d203e513acf952340wwang case DMA_READ: 225577d89b08766c878a2594b15d203e513acf952340wwang case DMA_WRITE: 225677d89b08766c878a2594b15d203e513acf952340wwang result = dma_access_ring_buffer(srb, chip); 225777d89b08766c878a2594b15d203e513acf952340wwang break; 225877d89b08766c878a2594b15d203e513acf952340wwang 225977d89b08766c878a2594b15d203e513acf952340wwang case READ_PHY: 226077d89b08766c878a2594b15d203e513acf952340wwang result = read_phy_register(srb, chip); 226177d89b08766c878a2594b15d203e513acf952340wwang break; 226277d89b08766c878a2594b15d203e513acf952340wwang 226377d89b08766c878a2594b15d203e513acf952340wwang case WRITE_PHY: 226477d89b08766c878a2594b15d203e513acf952340wwang result = write_phy_register(srb, chip); 226577d89b08766c878a2594b15d203e513acf952340wwang break; 226677d89b08766c878a2594b15d203e513acf952340wwang 226777d89b08766c878a2594b15d203e513acf952340wwang case ERASE_EEPROM2: 226877d89b08766c878a2594b15d203e513acf952340wwang result = erase_eeprom2(srb, chip); 226977d89b08766c878a2594b15d203e513acf952340wwang break; 227077d89b08766c878a2594b15d203e513acf952340wwang 227177d89b08766c878a2594b15d203e513acf952340wwang case READ_EEPROM2: 227277d89b08766c878a2594b15d203e513acf952340wwang result = read_eeprom2(srb, chip); 227377d89b08766c878a2594b15d203e513acf952340wwang break; 227477d89b08766c878a2594b15d203e513acf952340wwang 227577d89b08766c878a2594b15d203e513acf952340wwang case WRITE_EEPROM2: 227677d89b08766c878a2594b15d203e513acf952340wwang result = write_eeprom2(srb, chip); 227777d89b08766c878a2594b15d203e513acf952340wwang break; 227877d89b08766c878a2594b15d203e513acf952340wwang 227977d89b08766c878a2594b15d203e513acf952340wwang case READ_EFUSE: 228077d89b08766c878a2594b15d203e513acf952340wwang result = read_efuse(srb, chip); 228177d89b08766c878a2594b15d203e513acf952340wwang break; 228277d89b08766c878a2594b15d203e513acf952340wwang 228377d89b08766c878a2594b15d203e513acf952340wwang case WRITE_EFUSE: 228477d89b08766c878a2594b15d203e513acf952340wwang result = write_efuse(srb, chip); 228577d89b08766c878a2594b15d203e513acf952340wwang break; 228677d89b08766c878a2594b15d203e513acf952340wwang 228777d89b08766c878a2594b15d203e513acf952340wwang case READ_CFG: 228877d89b08766c878a2594b15d203e513acf952340wwang result = read_cfg_byte(srb, chip); 228977d89b08766c878a2594b15d203e513acf952340wwang break; 229077d89b08766c878a2594b15d203e513acf952340wwang 229177d89b08766c878a2594b15d203e513acf952340wwang case WRITE_CFG: 229277d89b08766c878a2594b15d203e513acf952340wwang result = write_cfg_byte(srb, chip); 229377d89b08766c878a2594b15d203e513acf952340wwang break; 229477d89b08766c878a2594b15d203e513acf952340wwang 229577d89b08766c878a2594b15d203e513acf952340wwang case SET_CHIP_MODE: 229677d89b08766c878a2594b15d203e513acf952340wwang result = set_chip_mode(srb, chip); 229777d89b08766c878a2594b15d203e513acf952340wwang break; 229877d89b08766c878a2594b15d203e513acf952340wwang 229977d89b08766c878a2594b15d203e513acf952340wwang case SUIT_CMD: 230077d89b08766c878a2594b15d203e513acf952340wwang result = suit_cmd(srb, chip); 230177d89b08766c878a2594b15d203e513acf952340wwang break; 230277d89b08766c878a2594b15d203e513acf952340wwang 230377d89b08766c878a2594b15d203e513acf952340wwang case GET_DEV_STATUS: 230477d89b08766c878a2594b15d203e513acf952340wwang result = get_dev_status(srb, chip); 230577d89b08766c878a2594b15d203e513acf952340wwang break; 230677d89b08766c878a2594b15d203e513acf952340wwang 230777d89b08766c878a2594b15d203e513acf952340wwang default: 230877d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 230977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 231077d89b08766c878a2594b15d203e513acf952340wwang } 231177d89b08766c878a2594b15d203e513acf952340wwang 231277d89b08766c878a2594b15d203e513acf952340wwang return result; 231377d89b08766c878a2594b15d203e513acf952340wwang} 231477d89b08766c878a2594b15d203e513acf952340wwang 231577d89b08766c878a2594b15d203e513acf952340wwang 231677d89b08766c878a2594b15d203e513acf952340wwangstatic int read_status(struct scsi_cmnd *srb, struct rtsx_chip *chip) 231777d89b08766c878a2594b15d203e513acf952340wwang{ 231877d89b08766c878a2594b15d203e513acf952340wwang u8 rtsx_status[16]; 231977d89b08766c878a2594b15d203e513acf952340wwang int buf_len; 232077d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 232177d89b08766c878a2594b15d203e513acf952340wwang 232277d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[0] = (u8)(chip->vendor_id >> 8); 232377d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[1] = (u8)(chip->vendor_id); 232477d89b08766c878a2594b15d203e513acf952340wwang 232577d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[2] = (u8)(chip->product_id >> 8); 232677d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[3] = (u8)(chip->product_id); 232777d89b08766c878a2594b15d203e513acf952340wwang 232877d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[4] = (u8)lun; 232977d89b08766c878a2594b15d203e513acf952340wwang 233077d89b08766c878a2594b15d203e513acf952340wwang if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { 233177d89b08766c878a2594b15d203e513acf952340wwang if (chip->lun2card[lun] == SD_CARD) { 233277d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[5] = 2; 233377d89b08766c878a2594b15d203e513acf952340wwang } else { 233477d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[5] = 3; 233577d89b08766c878a2594b15d203e513acf952340wwang } 233677d89b08766c878a2594b15d203e513acf952340wwang } else { 233777d89b08766c878a2594b15d203e513acf952340wwang if (chip->card_exist) { 233877d89b08766c878a2594b15d203e513acf952340wwang if (chip->card_exist & XD_CARD) { 233977d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[5] = 4; 234077d89b08766c878a2594b15d203e513acf952340wwang } else if (chip->card_exist & SD_CARD) { 234177d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[5] = 2; 234277d89b08766c878a2594b15d203e513acf952340wwang } else if (chip->card_exist & MS_CARD) { 234377d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[5] = 3; 234477d89b08766c878a2594b15d203e513acf952340wwang } else { 234577d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[5] = 7; 234677d89b08766c878a2594b15d203e513acf952340wwang } 234777d89b08766c878a2594b15d203e513acf952340wwang } else { 234877d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[5] = 7; 234977d89b08766c878a2594b15d203e513acf952340wwang } 235077d89b08766c878a2594b15d203e513acf952340wwang } 235177d89b08766c878a2594b15d203e513acf952340wwang 235277d89b08766c878a2594b15d203e513acf952340wwang if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { 235377d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[6] = 2; 235477d89b08766c878a2594b15d203e513acf952340wwang } else { 235577d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[6] = 1; 235677d89b08766c878a2594b15d203e513acf952340wwang } 235777d89b08766c878a2594b15d203e513acf952340wwang 235877d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[7] = (u8)(chip->product_id); 235977d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[8] = chip->ic_version; 236077d89b08766c878a2594b15d203e513acf952340wwang 236177d89b08766c878a2594b15d203e513acf952340wwang if (check_card_exist(chip, lun)) { 236277d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[9] = 1; 236377d89b08766c878a2594b15d203e513acf952340wwang } else { 236477d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[9] = 0; 236577d89b08766c878a2594b15d203e513acf952340wwang } 236677d89b08766c878a2594b15d203e513acf952340wwang 236777d89b08766c878a2594b15d203e513acf952340wwang if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { 236877d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[10] = 0; 236977d89b08766c878a2594b15d203e513acf952340wwang } else { 237077d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[10] = 1; 237177d89b08766c878a2594b15d203e513acf952340wwang } 237277d89b08766c878a2594b15d203e513acf952340wwang 237377d89b08766c878a2594b15d203e513acf952340wwang if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { 237477d89b08766c878a2594b15d203e513acf952340wwang if (chip->lun2card[lun] == SD_CARD) { 237577d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[11] = SD_CARD; 237677d89b08766c878a2594b15d203e513acf952340wwang } else { 237777d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[11] = MS_CARD; 237877d89b08766c878a2594b15d203e513acf952340wwang } 237977d89b08766c878a2594b15d203e513acf952340wwang } else { 238077d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[11] = XD_CARD | SD_CARD | MS_CARD; 238177d89b08766c878a2594b15d203e513acf952340wwang } 238277d89b08766c878a2594b15d203e513acf952340wwang 238377d89b08766c878a2594b15d203e513acf952340wwang if (check_card_ready(chip, lun)) { 238477d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[12] = 1; 238577d89b08766c878a2594b15d203e513acf952340wwang } else { 238677d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[12] = 0; 238777d89b08766c878a2594b15d203e513acf952340wwang } 238877d89b08766c878a2594b15d203e513acf952340wwang 238977d89b08766c878a2594b15d203e513acf952340wwang if (get_lun_card(chip, lun) == XD_CARD) { 239077d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] = 0x40; 239177d89b08766c878a2594b15d203e513acf952340wwang } else if (get_lun_card(chip, lun) == SD_CARD) { 239277d89b08766c878a2594b15d203e513acf952340wwang struct sd_info *sd_card = &(chip->sd_card); 239377d89b08766c878a2594b15d203e513acf952340wwang 239477d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] = 0x20; 239577d89b08766c878a2594b15d203e513acf952340wwang if (CHK_SD(sd_card)) { 239677d89b08766c878a2594b15d203e513acf952340wwang if (CHK_SD_HCXC(sd_card)) 239777d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] |= 0x04; 239877d89b08766c878a2594b15d203e513acf952340wwang if (CHK_SD_HS(sd_card)) 239977d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] |= 0x02; 240077d89b08766c878a2594b15d203e513acf952340wwang } else { 240177d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] |= 0x08; 240277d89b08766c878a2594b15d203e513acf952340wwang if (CHK_MMC_52M(sd_card)) 240377d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] |= 0x02; 240477d89b08766c878a2594b15d203e513acf952340wwang if (CHK_MMC_SECTOR_MODE(sd_card)) 240577d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] |= 0x04; 240677d89b08766c878a2594b15d203e513acf952340wwang } 240777d89b08766c878a2594b15d203e513acf952340wwang } else if (get_lun_card(chip, lun) == MS_CARD) { 240877d89b08766c878a2594b15d203e513acf952340wwang struct ms_info *ms_card = &(chip->ms_card); 240977d89b08766c878a2594b15d203e513acf952340wwang 241077d89b08766c878a2594b15d203e513acf952340wwang if (CHK_MSPRO(ms_card)) { 241177d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] = 0x38; 241277d89b08766c878a2594b15d203e513acf952340wwang if (CHK_HG8BIT(ms_card)) 241377d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] |= 0x04; 241477d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_MSXC 241577d89b08766c878a2594b15d203e513acf952340wwang if (CHK_MSXC(ms_card)) 241677d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] |= 0x01; 241777d89b08766c878a2594b15d203e513acf952340wwang#endif 241877d89b08766c878a2594b15d203e513acf952340wwang } else { 241977d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] = 0x30; 242077d89b08766c878a2594b15d203e513acf952340wwang } 242177d89b08766c878a2594b15d203e513acf952340wwang } else { 242277d89b08766c878a2594b15d203e513acf952340wwang if (CHECK_LUN_MODE(chip, DEFAULT_SINGLE)) { 242377d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_SDIO 242477d89b08766c878a2594b15d203e513acf952340wwang if (chip->sd_io && chip->sd_int) { 242577d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] = 0x60; 242677d89b08766c878a2594b15d203e513acf952340wwang } else { 242777d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] = 0x70; 242877d89b08766c878a2594b15d203e513acf952340wwang } 242977d89b08766c878a2594b15d203e513acf952340wwang#else 243077d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] = 0x70; 243177d89b08766c878a2594b15d203e513acf952340wwang#endif 243277d89b08766c878a2594b15d203e513acf952340wwang } else { 243377d89b08766c878a2594b15d203e513acf952340wwang if (chip->lun2card[lun] == SD_CARD) { 243477d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] = 0x20; 243577d89b08766c878a2594b15d203e513acf952340wwang } else { 243677d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[13] = 0x30; 243777d89b08766c878a2594b15d203e513acf952340wwang } 243877d89b08766c878a2594b15d203e513acf952340wwang } 243977d89b08766c878a2594b15d203e513acf952340wwang } 244077d89b08766c878a2594b15d203e513acf952340wwang 244177d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[14] = 0x78; 244277d89b08766c878a2594b15d203e513acf952340wwang if (CHK_SDIO_EXIST(chip) && !CHK_SDIO_IGNORED(chip)) { 244377d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[15] = 0x83; 244477d89b08766c878a2594b15d203e513acf952340wwang } else { 244577d89b08766c878a2594b15d203e513acf952340wwang rtsx_status[15] = 0x82; 244677d89b08766c878a2594b15d203e513acf952340wwang } 244777d89b08766c878a2594b15d203e513acf952340wwang 244877d89b08766c878a2594b15d203e513acf952340wwang buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(rtsx_status)); 244977d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(rtsx_status, buf_len, srb); 245077d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); 245177d89b08766c878a2594b15d203e513acf952340wwang 245277d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 245377d89b08766c878a2594b15d203e513acf952340wwang} 245477d89b08766c878a2594b15d203e513acf952340wwang 245577d89b08766c878a2594b15d203e513acf952340wwangstatic int get_card_bus_width(struct scsi_cmnd *srb, struct rtsx_chip *chip) 245677d89b08766c878a2594b15d203e513acf952340wwang{ 245777d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 245877d89b08766c878a2594b15d203e513acf952340wwang u8 card, bus_width; 245977d89b08766c878a2594b15d203e513acf952340wwang 246077d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun)) { 246177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 246277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 246377d89b08766c878a2594b15d203e513acf952340wwang } 246477d89b08766c878a2594b15d203e513acf952340wwang 246577d89b08766c878a2594b15d203e513acf952340wwang card = get_lun_card(chip, lun); 246677d89b08766c878a2594b15d203e513acf952340wwang if ((card == SD_CARD) || (card == MS_CARD)) { 246777d89b08766c878a2594b15d203e513acf952340wwang bus_width = chip->card_bus_width[lun]; 246877d89b08766c878a2594b15d203e513acf952340wwang } else { 246977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); 247077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 247177d89b08766c878a2594b15d203e513acf952340wwang } 247277d89b08766c878a2594b15d203e513acf952340wwang 247377d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 247477d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(&bus_width, scsi_bufflen(srb), srb); 247577d89b08766c878a2594b15d203e513acf952340wwang 247677d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 247777d89b08766c878a2594b15d203e513acf952340wwang} 247877d89b08766c878a2594b15d203e513acf952340wwang 247977d89b08766c878a2594b15d203e513acf952340wwangstatic int spi_vendor_cmd(struct scsi_cmnd *srb, struct rtsx_chip *chip) 248077d89b08766c878a2594b15d203e513acf952340wwang{ 248177d89b08766c878a2594b15d203e513acf952340wwang int result; 248277d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 248377d89b08766c878a2594b15d203e513acf952340wwang u8 gpio_dir; 248477d89b08766c878a2594b15d203e513acf952340wwang 248577d89b08766c878a2594b15d203e513acf952340wwang if (CHECK_PID(chip, 0x5208) && CHECK_PID(chip, 0x5288)) { 248677d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 248777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 248877d89b08766c878a2594b15d203e513acf952340wwang } 248977d89b08766c878a2594b15d203e513acf952340wwang 249077d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 249177d89b08766c878a2594b15d203e513acf952340wwang 249277d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 249377d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 249477d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 249577d89b08766c878a2594b15d203e513acf952340wwang } 249677d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 249777d89b08766c878a2594b15d203e513acf952340wwang 249877d89b08766c878a2594b15d203e513acf952340wwang rtsx_force_power_on(chip, SSC_PDCTL); 249977d89b08766c878a2594b15d203e513acf952340wwang 250077d89b08766c878a2594b15d203e513acf952340wwang rtsx_read_register(chip, CARD_GPIO_DIR, &gpio_dir); 250177d89b08766c878a2594b15d203e513acf952340wwang rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir & 0x06); 250277d89b08766c878a2594b15d203e513acf952340wwang 250377d89b08766c878a2594b15d203e513acf952340wwang switch (srb->cmnd[2]) { 250477d89b08766c878a2594b15d203e513acf952340wwang case SCSI_SPI_GETSTATUS: 250577d89b08766c878a2594b15d203e513acf952340wwang result = spi_get_status(srb, chip); 250677d89b08766c878a2594b15d203e513acf952340wwang break; 250777d89b08766c878a2594b15d203e513acf952340wwang 250877d89b08766c878a2594b15d203e513acf952340wwang case SCSI_SPI_SETPARAMETER: 250977d89b08766c878a2594b15d203e513acf952340wwang result = spi_set_parameter(srb, chip); 251077d89b08766c878a2594b15d203e513acf952340wwang break; 251177d89b08766c878a2594b15d203e513acf952340wwang 251277d89b08766c878a2594b15d203e513acf952340wwang case SCSI_SPI_READFALSHID: 251377d89b08766c878a2594b15d203e513acf952340wwang result = spi_read_flash_id(srb, chip); 251477d89b08766c878a2594b15d203e513acf952340wwang break; 251577d89b08766c878a2594b15d203e513acf952340wwang 251677d89b08766c878a2594b15d203e513acf952340wwang case SCSI_SPI_READFLASH: 251777d89b08766c878a2594b15d203e513acf952340wwang result = spi_read_flash(srb, chip); 251877d89b08766c878a2594b15d203e513acf952340wwang break; 251977d89b08766c878a2594b15d203e513acf952340wwang 252077d89b08766c878a2594b15d203e513acf952340wwang case SCSI_SPI_WRITEFLASH: 252177d89b08766c878a2594b15d203e513acf952340wwang result = spi_write_flash(srb, chip); 252277d89b08766c878a2594b15d203e513acf952340wwang break; 252377d89b08766c878a2594b15d203e513acf952340wwang 252477d89b08766c878a2594b15d203e513acf952340wwang case SCSI_SPI_WRITEFLASHSTATUS: 252577d89b08766c878a2594b15d203e513acf952340wwang result = spi_write_flash_status(srb, chip); 252677d89b08766c878a2594b15d203e513acf952340wwang break; 252777d89b08766c878a2594b15d203e513acf952340wwang 252877d89b08766c878a2594b15d203e513acf952340wwang case SCSI_SPI_ERASEFLASH: 252977d89b08766c878a2594b15d203e513acf952340wwang result = spi_erase_flash(srb, chip); 253077d89b08766c878a2594b15d203e513acf952340wwang break; 253177d89b08766c878a2594b15d203e513acf952340wwang 253277d89b08766c878a2594b15d203e513acf952340wwang default: 253377d89b08766c878a2594b15d203e513acf952340wwang rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); 253477d89b08766c878a2594b15d203e513acf952340wwang 253577d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 253677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 253777d89b08766c878a2594b15d203e513acf952340wwang } 253877d89b08766c878a2594b15d203e513acf952340wwang 253977d89b08766c878a2594b15d203e513acf952340wwang rtsx_write_register(chip, CARD_GPIO_DIR, 0x07, gpio_dir); 254077d89b08766c878a2594b15d203e513acf952340wwang 254177d89b08766c878a2594b15d203e513acf952340wwang if (result != STATUS_SUCCESS) { 254277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 254377d89b08766c878a2594b15d203e513acf952340wwang } 254477d89b08766c878a2594b15d203e513acf952340wwang 254577d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 254677d89b08766c878a2594b15d203e513acf952340wwang} 254777d89b08766c878a2594b15d203e513acf952340wwang 254877d89b08766c878a2594b15d203e513acf952340wwangstatic int vendor_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) 254977d89b08766c878a2594b15d203e513acf952340wwang{ 255077d89b08766c878a2594b15d203e513acf952340wwang int result; 255177d89b08766c878a2594b15d203e513acf952340wwang 255277d89b08766c878a2594b15d203e513acf952340wwang switch (srb->cmnd[1]) { 255377d89b08766c878a2594b15d203e513acf952340wwang case READ_STATUS: 255477d89b08766c878a2594b15d203e513acf952340wwang result = read_status(srb, chip); 255577d89b08766c878a2594b15d203e513acf952340wwang break; 255677d89b08766c878a2594b15d203e513acf952340wwang 255777d89b08766c878a2594b15d203e513acf952340wwang case READ_MEM: 255877d89b08766c878a2594b15d203e513acf952340wwang result = read_mem(srb, chip); 255977d89b08766c878a2594b15d203e513acf952340wwang break; 256077d89b08766c878a2594b15d203e513acf952340wwang 256177d89b08766c878a2594b15d203e513acf952340wwang case WRITE_MEM: 256277d89b08766c878a2594b15d203e513acf952340wwang result = write_mem(srb, chip); 256377d89b08766c878a2594b15d203e513acf952340wwang break; 256477d89b08766c878a2594b15d203e513acf952340wwang 256577d89b08766c878a2594b15d203e513acf952340wwang case READ_EEPROM: 256677d89b08766c878a2594b15d203e513acf952340wwang result = read_eeprom(srb, chip); 256777d89b08766c878a2594b15d203e513acf952340wwang break; 256877d89b08766c878a2594b15d203e513acf952340wwang 256977d89b08766c878a2594b15d203e513acf952340wwang case WRITE_EEPROM: 257077d89b08766c878a2594b15d203e513acf952340wwang result = write_eeprom(srb, chip); 257177d89b08766c878a2594b15d203e513acf952340wwang break; 257277d89b08766c878a2594b15d203e513acf952340wwang 257377d89b08766c878a2594b15d203e513acf952340wwang case TOGGLE_GPIO: 257477d89b08766c878a2594b15d203e513acf952340wwang result = toggle_gpio_cmd(srb, chip); 257577d89b08766c878a2594b15d203e513acf952340wwang break; 257677d89b08766c878a2594b15d203e513acf952340wwang 257777d89b08766c878a2594b15d203e513acf952340wwang case GET_SD_CSD: 257877d89b08766c878a2594b15d203e513acf952340wwang result = get_sd_csd(srb, chip); 257977d89b08766c878a2594b15d203e513acf952340wwang break; 258077d89b08766c878a2594b15d203e513acf952340wwang 258177d89b08766c878a2594b15d203e513acf952340wwang case GET_BUS_WIDTH: 258277d89b08766c878a2594b15d203e513acf952340wwang result = get_card_bus_width(srb, chip); 258377d89b08766c878a2594b15d203e513acf952340wwang break; 258477d89b08766c878a2594b15d203e513acf952340wwang 258577d89b08766c878a2594b15d203e513acf952340wwang#ifdef _MSG_TRACE 258677d89b08766c878a2594b15d203e513acf952340wwang case TRACE_MSG: 258777d89b08766c878a2594b15d203e513acf952340wwang result = trace_msg_cmd(srb, chip); 258877d89b08766c878a2594b15d203e513acf952340wwang break; 258977d89b08766c878a2594b15d203e513acf952340wwang#endif 259077d89b08766c878a2594b15d203e513acf952340wwang 259177d89b08766c878a2594b15d203e513acf952340wwang case SCSI_APP_CMD: 259277d89b08766c878a2594b15d203e513acf952340wwang result = app_cmd(srb, chip); 259377d89b08766c878a2594b15d203e513acf952340wwang break; 259477d89b08766c878a2594b15d203e513acf952340wwang 259577d89b08766c878a2594b15d203e513acf952340wwang case SPI_VENDOR_COMMAND: 259677d89b08766c878a2594b15d203e513acf952340wwang result = spi_vendor_cmd(srb, chip); 259777d89b08766c878a2594b15d203e513acf952340wwang break; 259877d89b08766c878a2594b15d203e513acf952340wwang 259977d89b08766c878a2594b15d203e513acf952340wwang default: 260077d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 260177d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 260277d89b08766c878a2594b15d203e513acf952340wwang } 260377d89b08766c878a2594b15d203e513acf952340wwang 260477d89b08766c878a2594b15d203e513acf952340wwang return result; 260577d89b08766c878a2594b15d203e513acf952340wwang} 260677d89b08766c878a2594b15d203e513acf952340wwang 260777d89b08766c878a2594b15d203e513acf952340wwang#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) 260877d89b08766c878a2594b15d203e513acf952340wwangvoid led_shine(struct scsi_cmnd *srb, struct rtsx_chip *chip) 260977d89b08766c878a2594b15d203e513acf952340wwang{ 261077d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 261177d89b08766c878a2594b15d203e513acf952340wwang u16 sec_cnt; 261277d89b08766c878a2594b15d203e513acf952340wwang 261377d89b08766c878a2594b15d203e513acf952340wwang if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) { 261477d89b08766c878a2594b15d203e513acf952340wwang sec_cnt = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8]; 261577d89b08766c878a2594b15d203e513acf952340wwang } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { 261677d89b08766c878a2594b15d203e513acf952340wwang sec_cnt = srb->cmnd[4]; 261777d89b08766c878a2594b15d203e513acf952340wwang } else { 261877d89b08766c878a2594b15d203e513acf952340wwang return; 261977d89b08766c878a2594b15d203e513acf952340wwang } 262077d89b08766c878a2594b15d203e513acf952340wwang 262177d89b08766c878a2594b15d203e513acf952340wwang if (chip->rw_cap[lun] >= GPIO_TOGGLE_THRESHOLD) { 262277d89b08766c878a2594b15d203e513acf952340wwang toggle_gpio(chip, LED_GPIO); 262377d89b08766c878a2594b15d203e513acf952340wwang chip->rw_cap[lun] = 0; 262477d89b08766c878a2594b15d203e513acf952340wwang } else { 262577d89b08766c878a2594b15d203e513acf952340wwang chip->rw_cap[lun] += sec_cnt; 262677d89b08766c878a2594b15d203e513acf952340wwang } 262777d89b08766c878a2594b15d203e513acf952340wwang} 262877d89b08766c878a2594b15d203e513acf952340wwang#endif 262977d89b08766c878a2594b15d203e513acf952340wwang 263077d89b08766c878a2594b15d203e513acf952340wwangstatic int ms_format_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) 263177d89b08766c878a2594b15d203e513acf952340wwang{ 263277d89b08766c878a2594b15d203e513acf952340wwang struct ms_info *ms_card = &(chip->ms_card); 263377d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 263477d89b08766c878a2594b15d203e513acf952340wwang int retval, quick_format; 263577d89b08766c878a2594b15d203e513acf952340wwang 263677d89b08766c878a2594b15d203e513acf952340wwang if (get_lun_card(chip, lun) != MS_CARD) { 263777d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); 263877d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 263977d89b08766c878a2594b15d203e513acf952340wwang } 264077d89b08766c878a2594b15d203e513acf952340wwang 264177d89b08766c878a2594b15d203e513acf952340wwang if ((srb->cmnd[3] != 0x4D) || (srb->cmnd[4] != 0x47) || 264277d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[5] != 0x66) || (srb->cmnd[6] != 0x6D) || 264377d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[7] != 0x74)) { 264477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 264577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 264677d89b08766c878a2594b15d203e513acf952340wwang } 264777d89b08766c878a2594b15d203e513acf952340wwang 264877d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 264977d89b08766c878a2594b15d203e513acf952340wwang 265077d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 265177d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 265277d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 265377d89b08766c878a2594b15d203e513acf952340wwang 265477d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun) || 265577d89b08766c878a2594b15d203e513acf952340wwang (get_card_size(chip, lun) == 0)) { 265677d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 265777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 265877d89b08766c878a2594b15d203e513acf952340wwang } 265977d89b08766c878a2594b15d203e513acf952340wwang } 266077d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 266177d89b08766c878a2594b15d203e513acf952340wwang 266277d89b08766c878a2594b15d203e513acf952340wwang if (srb->cmnd[8] & 0x01) { 266377d89b08766c878a2594b15d203e513acf952340wwang quick_format = 0; 266477d89b08766c878a2594b15d203e513acf952340wwang } else { 266577d89b08766c878a2594b15d203e513acf952340wwang quick_format = 1; 266677d89b08766c878a2594b15d203e513acf952340wwang } 266777d89b08766c878a2594b15d203e513acf952340wwang 266877d89b08766c878a2594b15d203e513acf952340wwang if (!(chip->card_ready & MS_CARD)) { 266977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 267077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 267177d89b08766c878a2594b15d203e513acf952340wwang } 267277d89b08766c878a2594b15d203e513acf952340wwang 267377d89b08766c878a2594b15d203e513acf952340wwang if (chip->card_wp & MS_CARD) { 267477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); 267577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 267677d89b08766c878a2594b15d203e513acf952340wwang } 267777d89b08766c878a2594b15d203e513acf952340wwang 267877d89b08766c878a2594b15d203e513acf952340wwang if (!CHK_MSPRO(ms_card)) { 267977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); 268077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 268177d89b08766c878a2594b15d203e513acf952340wwang } 268277d89b08766c878a2594b15d203e513acf952340wwang 268377d89b08766c878a2594b15d203e513acf952340wwang retval = mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format); 268477d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 268577d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); 268677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 268777d89b08766c878a2594b15d203e513acf952340wwang } 268877d89b08766c878a2594b15d203e513acf952340wwang 268977d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 269077d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 269177d89b08766c878a2594b15d203e513acf952340wwang} 269277d89b08766c878a2594b15d203e513acf952340wwang 269377d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_PCGL_1P18 26946680d2cab316a0c0e4cea0727e6d63426a77bb12wwangstatic int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) 269577d89b08766c878a2594b15d203e513acf952340wwang{ 269677d89b08766c878a2594b15d203e513acf952340wwang struct ms_info *ms_card = &(chip->ms_card); 269777d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 269877d89b08766c878a2594b15d203e513acf952340wwang u8 dev_info_id, data_len; 269977d89b08766c878a2594b15d203e513acf952340wwang u8 *buf; 270077d89b08766c878a2594b15d203e513acf952340wwang unsigned int buf_len; 270177d89b08766c878a2594b15d203e513acf952340wwang int i; 270277d89b08766c878a2594b15d203e513acf952340wwang 270377d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun)) { 270477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 270577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 270677d89b08766c878a2594b15d203e513acf952340wwang } 270777d89b08766c878a2594b15d203e513acf952340wwang if ((get_lun_card(chip, lun) != MS_CARD)) { 270877d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); 270977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 271077d89b08766c878a2594b15d203e513acf952340wwang } 271177d89b08766c878a2594b15d203e513acf952340wwang 271277d89b08766c878a2594b15d203e513acf952340wwang if ((srb->cmnd[2] != 0xB0) || (srb->cmnd[4] != 0x4D) || 271377d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[5] != 0x53) || (srb->cmnd[6] != 0x49) || 271477d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[7] != 0x44)) { 271577d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 271677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 271777d89b08766c878a2594b15d203e513acf952340wwang } 271877d89b08766c878a2594b15d203e513acf952340wwang 271977d89b08766c878a2594b15d203e513acf952340wwang dev_info_id = srb->cmnd[3]; 272077d89b08766c878a2594b15d203e513acf952340wwang if ((CHK_MSXC(ms_card) && (dev_info_id == 0x10)) || 272177d89b08766c878a2594b15d203e513acf952340wwang (!CHK_MSXC(ms_card) && (dev_info_id == 0x13)) || 272277d89b08766c878a2594b15d203e513acf952340wwang !CHK_MSPRO(ms_card)) { 272377d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 272477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 272577d89b08766c878a2594b15d203e513acf952340wwang } 272677d89b08766c878a2594b15d203e513acf952340wwang 272777d89b08766c878a2594b15d203e513acf952340wwang if (dev_info_id == 0x15) { 272877d89b08766c878a2594b15d203e513acf952340wwang buf_len = data_len = 0x3A; 272977d89b08766c878a2594b15d203e513acf952340wwang } else { 273077d89b08766c878a2594b15d203e513acf952340wwang buf_len = data_len = 0x6A; 273177d89b08766c878a2594b15d203e513acf952340wwang } 273277d89b08766c878a2594b15d203e513acf952340wwang 2733a5232bde8449b28230f767e8b558021bb5d08e5cThomas Meyer buf = kmalloc(buf_len, GFP_KERNEL); 273477d89b08766c878a2594b15d203e513acf952340wwang if (!buf) { 273577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_ERROR); 273677d89b08766c878a2594b15d203e513acf952340wwang } 273777d89b08766c878a2594b15d203e513acf952340wwang 273877d89b08766c878a2594b15d203e513acf952340wwang i = 0; 273977d89b08766c878a2594b15d203e513acf952340wwang /* GET Memory Stick Media Information Response Header */ 274077d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; /* Data length MSB */ 274177d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = data_len; /* Data length LSB */ 274277d89b08766c878a2594b15d203e513acf952340wwang /* Device Information Type Code */ 274377d89b08766c878a2594b15d203e513acf952340wwang if (CHK_MSXC(ms_card)) { 274477d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x03; 274577d89b08766c878a2594b15d203e513acf952340wwang } else { 274677d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x02; 274777d89b08766c878a2594b15d203e513acf952340wwang } 274877d89b08766c878a2594b15d203e513acf952340wwang /* SGM bit */ 274977d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x01; 275077d89b08766c878a2594b15d203e513acf952340wwang /* Reserved */ 275177d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; 275277d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; 275377d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; 275477d89b08766c878a2594b15d203e513acf952340wwang /* Number of Device Information */ 275577d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x01; 275677d89b08766c878a2594b15d203e513acf952340wwang 275777d89b08766c878a2594b15d203e513acf952340wwang /* Device Information Body */ 275877d89b08766c878a2594b15d203e513acf952340wwang 275977d89b08766c878a2594b15d203e513acf952340wwang /* Device Information ID Number */ 276077d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = dev_info_id; 276177d89b08766c878a2594b15d203e513acf952340wwang /* Device Information Length */ 276277d89b08766c878a2594b15d203e513acf952340wwang if (dev_info_id == 0x15) { 276377d89b08766c878a2594b15d203e513acf952340wwang data_len = 0x31; 276477d89b08766c878a2594b15d203e513acf952340wwang } else { 276577d89b08766c878a2594b15d203e513acf952340wwang data_len = 0x61; 276677d89b08766c878a2594b15d203e513acf952340wwang } 276777d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x00; /* Data length MSB */ 276877d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = data_len; /* Data length LSB */ 276977d89b08766c878a2594b15d203e513acf952340wwang /* Valid Bit */ 277077d89b08766c878a2594b15d203e513acf952340wwang buf[i++] = 0x80; 277177d89b08766c878a2594b15d203e513acf952340wwang if ((dev_info_id == 0x10) || (dev_info_id == 0x13)) { 277277d89b08766c878a2594b15d203e513acf952340wwang /* System Information */ 277377d89b08766c878a2594b15d203e513acf952340wwang memcpy(buf+i, ms_card->raw_sys_info, 96); 277477d89b08766c878a2594b15d203e513acf952340wwang } else { 277577d89b08766c878a2594b15d203e513acf952340wwang /* Model Name */ 277677d89b08766c878a2594b15d203e513acf952340wwang memcpy(buf+i, ms_card->raw_model_name, 48); 277777d89b08766c878a2594b15d203e513acf952340wwang } 277877d89b08766c878a2594b15d203e513acf952340wwang 277977d89b08766c878a2594b15d203e513acf952340wwang rtsx_stor_set_xfer_buf(buf, buf_len, srb); 278077d89b08766c878a2594b15d203e513acf952340wwang 278177d89b08766c878a2594b15d203e513acf952340wwang if (dev_info_id == 0x15) { 278277d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb)-0x3C); 278377d89b08766c878a2594b15d203e513acf952340wwang } else { 278477d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, scsi_bufflen(srb)-0x6C); 278577d89b08766c878a2594b15d203e513acf952340wwang } 278677d89b08766c878a2594b15d203e513acf952340wwang 278777d89b08766c878a2594b15d203e513acf952340wwang kfree(buf); 278877d89b08766c878a2594b15d203e513acf952340wwang return STATUS_SUCCESS; 278977d89b08766c878a2594b15d203e513acf952340wwang} 279077d89b08766c878a2594b15d203e513acf952340wwang#endif 279177d89b08766c878a2594b15d203e513acf952340wwang 279277d89b08766c878a2594b15d203e513acf952340wwangstatic int ms_sp_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) 279377d89b08766c878a2594b15d203e513acf952340wwang{ 279477d89b08766c878a2594b15d203e513acf952340wwang int retval = TRANSPORT_ERROR; 279577d89b08766c878a2594b15d203e513acf952340wwang 279677d89b08766c878a2594b15d203e513acf952340wwang if (srb->cmnd[2] == MS_FORMAT) { 279777d89b08766c878a2594b15d203e513acf952340wwang retval = ms_format_cmnd(srb, chip); 279877d89b08766c878a2594b15d203e513acf952340wwang } 279977d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_PCGL_1P18 280077d89b08766c878a2594b15d203e513acf952340wwang else if (srb->cmnd[2] == GET_MS_INFORMATION) { 280177d89b08766c878a2594b15d203e513acf952340wwang retval = get_ms_information(srb, chip); 280277d89b08766c878a2594b15d203e513acf952340wwang } 280377d89b08766c878a2594b15d203e513acf952340wwang#endif 280477d89b08766c878a2594b15d203e513acf952340wwang 280577d89b08766c878a2594b15d203e513acf952340wwang return retval; 280677d89b08766c878a2594b15d203e513acf952340wwang} 280777d89b08766c878a2594b15d203e513acf952340wwang 280877d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_CPRM 280977d89b08766c878a2594b15d203e513acf952340wwangstatic int sd_extention_cmnd(struct scsi_cmnd *srb, struct rtsx_chip *chip) 281077d89b08766c878a2594b15d203e513acf952340wwang{ 281177d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 281277d89b08766c878a2594b15d203e513acf952340wwang int result; 281377d89b08766c878a2594b15d203e513acf952340wwang 281477d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 281577d89b08766c878a2594b15d203e513acf952340wwang 281677d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 281777d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 281877d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 281977d89b08766c878a2594b15d203e513acf952340wwang } 282077d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 282177d89b08766c878a2594b15d203e513acf952340wwang 282277d89b08766c878a2594b15d203e513acf952340wwang sd_cleanup_work(chip); 282377d89b08766c878a2594b15d203e513acf952340wwang 282477d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun)) { 282577d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 282677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 282777d89b08766c878a2594b15d203e513acf952340wwang } 282877d89b08766c878a2594b15d203e513acf952340wwang if ((get_lun_card(chip, lun) != SD_CARD)) { 282977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); 283077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 283177d89b08766c878a2594b15d203e513acf952340wwang } 283277d89b08766c878a2594b15d203e513acf952340wwang 283377d89b08766c878a2594b15d203e513acf952340wwang switch (srb->cmnd[0]) { 283477d89b08766c878a2594b15d203e513acf952340wwang case SD_PASS_THRU_MODE: 283577d89b08766c878a2594b15d203e513acf952340wwang result = sd_pass_thru_mode(srb, chip); 283677d89b08766c878a2594b15d203e513acf952340wwang break; 283777d89b08766c878a2594b15d203e513acf952340wwang 283877d89b08766c878a2594b15d203e513acf952340wwang case SD_EXECUTE_NO_DATA: 283977d89b08766c878a2594b15d203e513acf952340wwang result = sd_execute_no_data(srb, chip); 284077d89b08766c878a2594b15d203e513acf952340wwang break; 284177d89b08766c878a2594b15d203e513acf952340wwang 284277d89b08766c878a2594b15d203e513acf952340wwang case SD_EXECUTE_READ: 284377d89b08766c878a2594b15d203e513acf952340wwang result = sd_execute_read_data(srb, chip); 284477d89b08766c878a2594b15d203e513acf952340wwang break; 284577d89b08766c878a2594b15d203e513acf952340wwang 284677d89b08766c878a2594b15d203e513acf952340wwang case SD_EXECUTE_WRITE: 284777d89b08766c878a2594b15d203e513acf952340wwang result = sd_execute_write_data(srb, chip); 284877d89b08766c878a2594b15d203e513acf952340wwang break; 284977d89b08766c878a2594b15d203e513acf952340wwang 285077d89b08766c878a2594b15d203e513acf952340wwang case SD_GET_RSP: 285177d89b08766c878a2594b15d203e513acf952340wwang result = sd_get_cmd_rsp(srb, chip); 285277d89b08766c878a2594b15d203e513acf952340wwang break; 285377d89b08766c878a2594b15d203e513acf952340wwang 285477d89b08766c878a2594b15d203e513acf952340wwang case SD_HW_RST: 285577d89b08766c878a2594b15d203e513acf952340wwang result = sd_hw_rst(srb, chip); 285677d89b08766c878a2594b15d203e513acf952340wwang break; 285777d89b08766c878a2594b15d203e513acf952340wwang 285877d89b08766c878a2594b15d203e513acf952340wwang default: 285977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 286077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 286177d89b08766c878a2594b15d203e513acf952340wwang } 286277d89b08766c878a2594b15d203e513acf952340wwang 286377d89b08766c878a2594b15d203e513acf952340wwang return result; 286477d89b08766c878a2594b15d203e513acf952340wwang} 286577d89b08766c878a2594b15d203e513acf952340wwang#endif 286677d89b08766c878a2594b15d203e513acf952340wwang 286777d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_MAGIC_GATE 28686680d2cab316a0c0e4cea0727e6d63426a77bb12wwangstatic int mg_report_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) 286977d89b08766c878a2594b15d203e513acf952340wwang{ 287077d89b08766c878a2594b15d203e513acf952340wwang struct ms_info *ms_card = &(chip->ms_card); 287177d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 287277d89b08766c878a2594b15d203e513acf952340wwang int retval; 287377d89b08766c878a2594b15d203e513acf952340wwang u8 key_format; 287477d89b08766c878a2594b15d203e513acf952340wwang 287577d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("--%s--\n", __func__); 287677d89b08766c878a2594b15d203e513acf952340wwang 287777d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 287877d89b08766c878a2594b15d203e513acf952340wwang 287977d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 288077d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 288177d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 288277d89b08766c878a2594b15d203e513acf952340wwang } 288377d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 288477d89b08766c878a2594b15d203e513acf952340wwang 288577d89b08766c878a2594b15d203e513acf952340wwang ms_cleanup_work(chip); 288677d89b08766c878a2594b15d203e513acf952340wwang 288777d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun)) { 288877d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 288977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 289077d89b08766c878a2594b15d203e513acf952340wwang } 289177d89b08766c878a2594b15d203e513acf952340wwang if ((get_lun_card(chip, lun) != MS_CARD)) { 289277d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); 289377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 289477d89b08766c878a2594b15d203e513acf952340wwang } 289577d89b08766c878a2594b15d203e513acf952340wwang 289677d89b08766c878a2594b15d203e513acf952340wwang if (srb->cmnd[7] != KC_MG_R_PRO) { 289777d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 289877d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 289977d89b08766c878a2594b15d203e513acf952340wwang } 290077d89b08766c878a2594b15d203e513acf952340wwang 290177d89b08766c878a2594b15d203e513acf952340wwang if (!CHK_MSPRO(ms_card)) { 290277d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); 290377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 290477d89b08766c878a2594b15d203e513acf952340wwang } 290577d89b08766c878a2594b15d203e513acf952340wwang 290677d89b08766c878a2594b15d203e513acf952340wwang key_format = srb->cmnd[10] & 0x3F; 290777d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("key_format = 0x%x\n", key_format); 290877d89b08766c878a2594b15d203e513acf952340wwang 290977d89b08766c878a2594b15d203e513acf952340wwang switch (key_format) { 291077d89b08766c878a2594b15d203e513acf952340wwang case KF_GET_LOC_EKB: 291177d89b08766c878a2594b15d203e513acf952340wwang if ((scsi_bufflen(srb) == 0x41C) && 291277d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[8] == 0x04) && 291377d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[9] == 0x1C)) { 291477d89b08766c878a2594b15d203e513acf952340wwang retval = mg_get_local_EKB(srb, chip); 291577d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 291677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 291777d89b08766c878a2594b15d203e513acf952340wwang } 291877d89b08766c878a2594b15d203e513acf952340wwang } else { 291977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 292077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 292177d89b08766c878a2594b15d203e513acf952340wwang } 292277d89b08766c878a2594b15d203e513acf952340wwang break; 292377d89b08766c878a2594b15d203e513acf952340wwang 292477d89b08766c878a2594b15d203e513acf952340wwang case KF_RSP_CHG: 292577d89b08766c878a2594b15d203e513acf952340wwang if ((scsi_bufflen(srb) == 0x24) && 292677d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[8] == 0x00) && 292777d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[9] == 0x24)) { 292877d89b08766c878a2594b15d203e513acf952340wwang retval = mg_get_rsp_chg(srb, chip); 292977d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 293077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 293177d89b08766c878a2594b15d203e513acf952340wwang } 293277d89b08766c878a2594b15d203e513acf952340wwang } else { 293377d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 293477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 293577d89b08766c878a2594b15d203e513acf952340wwang } 293677d89b08766c878a2594b15d203e513acf952340wwang break; 293777d89b08766c878a2594b15d203e513acf952340wwang 293877d89b08766c878a2594b15d203e513acf952340wwang case KF_GET_ICV: 293977d89b08766c878a2594b15d203e513acf952340wwang ms_card->mg_entry_num = srb->cmnd[5]; 294077d89b08766c878a2594b15d203e513acf952340wwang if ((scsi_bufflen(srb) == 0x404) && 294177d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[8] == 0x04) && 294277d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[9] == 0x04) && 294377d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[2] == 0x00) && 294477d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[3] == 0x00) && 294577d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[4] == 0x00) && 294677d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[5] < 32)) { 294777d89b08766c878a2594b15d203e513acf952340wwang retval = mg_get_ICV(srb, chip); 294877d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 294977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 295077d89b08766c878a2594b15d203e513acf952340wwang } 295177d89b08766c878a2594b15d203e513acf952340wwang } else { 295277d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 295377d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 295477d89b08766c878a2594b15d203e513acf952340wwang } 295577d89b08766c878a2594b15d203e513acf952340wwang break; 295677d89b08766c878a2594b15d203e513acf952340wwang 295777d89b08766c878a2594b15d203e513acf952340wwang default: 295877d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 295977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 296077d89b08766c878a2594b15d203e513acf952340wwang } 296177d89b08766c878a2594b15d203e513acf952340wwang 296277d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 296377d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 296477d89b08766c878a2594b15d203e513acf952340wwang} 296577d89b08766c878a2594b15d203e513acf952340wwang 29666680d2cab316a0c0e4cea0727e6d63426a77bb12wwangstatic int mg_send_key(struct scsi_cmnd *srb, struct rtsx_chip *chip) 296777d89b08766c878a2594b15d203e513acf952340wwang{ 296877d89b08766c878a2594b15d203e513acf952340wwang struct ms_info *ms_card = &(chip->ms_card); 296977d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 297077d89b08766c878a2594b15d203e513acf952340wwang int retval; 297177d89b08766c878a2594b15d203e513acf952340wwang u8 key_format; 297277d89b08766c878a2594b15d203e513acf952340wwang 297377d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("--%s--\n", __func__); 297477d89b08766c878a2594b15d203e513acf952340wwang 297577d89b08766c878a2594b15d203e513acf952340wwang rtsx_disable_aspm(chip); 297677d89b08766c878a2594b15d203e513acf952340wwang 297777d89b08766c878a2594b15d203e513acf952340wwang if (chip->ss_en && (rtsx_get_stat(chip) == RTSX_STAT_SS)) { 297877d89b08766c878a2594b15d203e513acf952340wwang rtsx_exit_ss(chip); 297977d89b08766c878a2594b15d203e513acf952340wwang wait_timeout(100); 298077d89b08766c878a2594b15d203e513acf952340wwang } 298177d89b08766c878a2594b15d203e513acf952340wwang rtsx_set_stat(chip, RTSX_STAT_RUN); 298277d89b08766c878a2594b15d203e513acf952340wwang 298377d89b08766c878a2594b15d203e513acf952340wwang ms_cleanup_work(chip); 298477d89b08766c878a2594b15d203e513acf952340wwang 298577d89b08766c878a2594b15d203e513acf952340wwang if (!check_card_ready(chip, lun)) { 298677d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); 298777d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 298877d89b08766c878a2594b15d203e513acf952340wwang } 298977d89b08766c878a2594b15d203e513acf952340wwang if (check_card_wp(chip, lun)) { 299077d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); 299177d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 299277d89b08766c878a2594b15d203e513acf952340wwang } 299377d89b08766c878a2594b15d203e513acf952340wwang if ((get_lun_card(chip, lun) != MS_CARD)) { 299477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); 299577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 299677d89b08766c878a2594b15d203e513acf952340wwang } 299777d89b08766c878a2594b15d203e513acf952340wwang 299877d89b08766c878a2594b15d203e513acf952340wwang if (srb->cmnd[7] != KC_MG_R_PRO) { 299977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 300077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 300177d89b08766c878a2594b15d203e513acf952340wwang } 300277d89b08766c878a2594b15d203e513acf952340wwang 300377d89b08766c878a2594b15d203e513acf952340wwang if (!CHK_MSPRO(ms_card)) { 300477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); 300577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 300677d89b08766c878a2594b15d203e513acf952340wwang } 300777d89b08766c878a2594b15d203e513acf952340wwang 300877d89b08766c878a2594b15d203e513acf952340wwang key_format = srb->cmnd[10] & 0x3F; 300977d89b08766c878a2594b15d203e513acf952340wwang RTSX_DEBUGP("key_format = 0x%x\n", key_format); 301077d89b08766c878a2594b15d203e513acf952340wwang 301177d89b08766c878a2594b15d203e513acf952340wwang switch (key_format) { 301277d89b08766c878a2594b15d203e513acf952340wwang case KF_SET_LEAF_ID: 301377d89b08766c878a2594b15d203e513acf952340wwang if ((scsi_bufflen(srb) == 0x0C) && 301477d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[8] == 0x00) && 301577d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[9] == 0x0C)) { 301677d89b08766c878a2594b15d203e513acf952340wwang retval = mg_set_leaf_id(srb, chip); 301777d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 301877d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 301977d89b08766c878a2594b15d203e513acf952340wwang } 302077d89b08766c878a2594b15d203e513acf952340wwang } else { 302177d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 302277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 302377d89b08766c878a2594b15d203e513acf952340wwang } 302477d89b08766c878a2594b15d203e513acf952340wwang break; 302577d89b08766c878a2594b15d203e513acf952340wwang 302677d89b08766c878a2594b15d203e513acf952340wwang case KF_CHG_HOST: 302777d89b08766c878a2594b15d203e513acf952340wwang if ((scsi_bufflen(srb) == 0x0C) && 302877d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[8] == 0x00) && 302977d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[9] == 0x0C)) { 303077d89b08766c878a2594b15d203e513acf952340wwang retval = mg_chg(srb, chip); 303177d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 303277d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 303377d89b08766c878a2594b15d203e513acf952340wwang } 303477d89b08766c878a2594b15d203e513acf952340wwang } else { 303577d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 303677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 303777d89b08766c878a2594b15d203e513acf952340wwang } 303877d89b08766c878a2594b15d203e513acf952340wwang break; 303977d89b08766c878a2594b15d203e513acf952340wwang 304077d89b08766c878a2594b15d203e513acf952340wwang case KF_RSP_HOST: 304177d89b08766c878a2594b15d203e513acf952340wwang if ((scsi_bufflen(srb) == 0x0C) && 304277d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[8] == 0x00) && 304377d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[9] == 0x0C)) { 304477d89b08766c878a2594b15d203e513acf952340wwang retval = mg_rsp(srb, chip); 304577d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 304677d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 304777d89b08766c878a2594b15d203e513acf952340wwang } 304877d89b08766c878a2594b15d203e513acf952340wwang } else { 304977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 305077d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 305177d89b08766c878a2594b15d203e513acf952340wwang } 305277d89b08766c878a2594b15d203e513acf952340wwang break; 305377d89b08766c878a2594b15d203e513acf952340wwang 305477d89b08766c878a2594b15d203e513acf952340wwang case KF_SET_ICV: 305577d89b08766c878a2594b15d203e513acf952340wwang ms_card->mg_entry_num = srb->cmnd[5]; 305677d89b08766c878a2594b15d203e513acf952340wwang if ((scsi_bufflen(srb) == 0x404) && 305777d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[8] == 0x04) && 305877d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[9] == 0x04) && 305977d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[2] == 0x00) && 306077d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[3] == 0x00) && 306177d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[4] == 0x00) && 306277d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[5] < 32)) { 306377d89b08766c878a2594b15d203e513acf952340wwang retval = mg_set_ICV(srb, chip); 306477d89b08766c878a2594b15d203e513acf952340wwang if (retval != STATUS_SUCCESS) { 306577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 306677d89b08766c878a2594b15d203e513acf952340wwang } 306777d89b08766c878a2594b15d203e513acf952340wwang } else { 306877d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 306977d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 307077d89b08766c878a2594b15d203e513acf952340wwang } 307177d89b08766c878a2594b15d203e513acf952340wwang break; 307277d89b08766c878a2594b15d203e513acf952340wwang 307377d89b08766c878a2594b15d203e513acf952340wwang default: 307477d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 307577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 307677d89b08766c878a2594b15d203e513acf952340wwang } 307777d89b08766c878a2594b15d203e513acf952340wwang 307877d89b08766c878a2594b15d203e513acf952340wwang scsi_set_resid(srb, 0); 307977d89b08766c878a2594b15d203e513acf952340wwang return TRANSPORT_GOOD; 308077d89b08766c878a2594b15d203e513acf952340wwang} 308177d89b08766c878a2594b15d203e513acf952340wwang#endif 308277d89b08766c878a2594b15d203e513acf952340wwang 308377d89b08766c878a2594b15d203e513acf952340wwangint rtsx_scsi_handler(struct scsi_cmnd *srb, struct rtsx_chip *chip) 308477d89b08766c878a2594b15d203e513acf952340wwang{ 308577d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_SD_LOCK 308677d89b08766c878a2594b15d203e513acf952340wwang struct sd_info *sd_card = &(chip->sd_card); 308777d89b08766c878a2594b15d203e513acf952340wwang#endif 308877d89b08766c878a2594b15d203e513acf952340wwang struct ms_info *ms_card = &(chip->ms_card); 308977d89b08766c878a2594b15d203e513acf952340wwang unsigned int lun = SCSI_LUN(srb); 309077d89b08766c878a2594b15d203e513acf952340wwang int result; 309177d89b08766c878a2594b15d203e513acf952340wwang 309277d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_SD_LOCK 309377d89b08766c878a2594b15d203e513acf952340wwang if (sd_card->sd_erase_status) { 309477d89b08766c878a2594b15d203e513acf952340wwang /* Block all SCSI command except for 309577d89b08766c878a2594b15d203e513acf952340wwang * REQUEST_SENSE and rs_ppstatus 309677d89b08766c878a2594b15d203e513acf952340wwang */ 309777d89b08766c878a2594b15d203e513acf952340wwang if (!((srb->cmnd[0] == VENDOR_CMND) && 309877d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[1] == SCSI_APP_CMD) && 309977d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[2] == GET_DEV_STATUS)) && 310077d89b08766c878a2594b15d203e513acf952340wwang (srb->cmnd[0] != REQUEST_SENSE)) { 310177d89b08766c878a2594b15d203e513acf952340wwang /* Logical Unit Not Ready Format in Progress */ 310277d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 310377d89b08766c878a2594b15d203e513acf952340wwang 0x02, 0, 0x04, 0x04, 0, 0); 310477d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 310577d89b08766c878a2594b15d203e513acf952340wwang } 310677d89b08766c878a2594b15d203e513acf952340wwang } 310777d89b08766c878a2594b15d203e513acf952340wwang#endif 310877d89b08766c878a2594b15d203e513acf952340wwang 310977d89b08766c878a2594b15d203e513acf952340wwang if ((get_lun_card(chip, lun) == MS_CARD) && 311077d89b08766c878a2594b15d203e513acf952340wwang (ms_card->format_status == FORMAT_IN_PROGRESS)) { 311177d89b08766c878a2594b15d203e513acf952340wwang if ((srb->cmnd[0] != REQUEST_SENSE) && (srb->cmnd[0] != INQUIRY)) { 311277d89b08766c878a2594b15d203e513acf952340wwang /* Logical Unit Not Ready Format in Progress */ 311377d89b08766c878a2594b15d203e513acf952340wwang set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 311477d89b08766c878a2594b15d203e513acf952340wwang 0, (u16)(ms_card->progress)); 311577d89b08766c878a2594b15d203e513acf952340wwang TRACE_RET(chip, TRANSPORT_FAILED); 311677d89b08766c878a2594b15d203e513acf952340wwang } 311777d89b08766c878a2594b15d203e513acf952340wwang } 311877d89b08766c878a2594b15d203e513acf952340wwang 311977d89b08766c878a2594b15d203e513acf952340wwang switch (srb->cmnd[0]) { 312077d89b08766c878a2594b15d203e513acf952340wwang case READ_10: 312177d89b08766c878a2594b15d203e513acf952340wwang case WRITE_10: 312277d89b08766c878a2594b15d203e513acf952340wwang case READ_6: 312377d89b08766c878a2594b15d203e513acf952340wwang case WRITE_6: 312477d89b08766c878a2594b15d203e513acf952340wwang result = read_write(srb, chip); 312577d89b08766c878a2594b15d203e513acf952340wwang#if !defined(LED_AUTO_BLINK) && !defined(REGULAR_BLINK) 312677d89b08766c878a2594b15d203e513acf952340wwang led_shine(srb, chip); 312777d89b08766c878a2594b15d203e513acf952340wwang#endif 312877d89b08766c878a2594b15d203e513acf952340wwang break; 312977d89b08766c878a2594b15d203e513acf952340wwang 313077d89b08766c878a2594b15d203e513acf952340wwang case TEST_UNIT_READY: 313177d89b08766c878a2594b15d203e513acf952340wwang result = test_unit_ready(srb, chip); 313277d89b08766c878a2594b15d203e513acf952340wwang break; 313377d89b08766c878a2594b15d203e513acf952340wwang 313477d89b08766c878a2594b15d203e513acf952340wwang case INQUIRY: 313577d89b08766c878a2594b15d203e513acf952340wwang result = inquiry(srb, chip); 313677d89b08766c878a2594b15d203e513acf952340wwang break; 313777d89b08766c878a2594b15d203e513acf952340wwang 313877d89b08766c878a2594b15d203e513acf952340wwang case READ_CAPACITY: 313977d89b08766c878a2594b15d203e513acf952340wwang result = read_capacity(srb, chip); 314077d89b08766c878a2594b15d203e513acf952340wwang break; 314177d89b08766c878a2594b15d203e513acf952340wwang 314277d89b08766c878a2594b15d203e513acf952340wwang case START_STOP: 314377d89b08766c878a2594b15d203e513acf952340wwang result = start_stop_unit(srb, chip); 314477d89b08766c878a2594b15d203e513acf952340wwang break; 314577d89b08766c878a2594b15d203e513acf952340wwang 314677d89b08766c878a2594b15d203e513acf952340wwang case ALLOW_MEDIUM_REMOVAL: 314777d89b08766c878a2594b15d203e513acf952340wwang result = allow_medium_removal(srb, chip); 314877d89b08766c878a2594b15d203e513acf952340wwang break; 314977d89b08766c878a2594b15d203e513acf952340wwang 315077d89b08766c878a2594b15d203e513acf952340wwang case REQUEST_SENSE: 315177d89b08766c878a2594b15d203e513acf952340wwang result = request_sense(srb, chip); 315277d89b08766c878a2594b15d203e513acf952340wwang break; 315377d89b08766c878a2594b15d203e513acf952340wwang 315477d89b08766c878a2594b15d203e513acf952340wwang case MODE_SENSE: 315577d89b08766c878a2594b15d203e513acf952340wwang case MODE_SENSE_10: 315677d89b08766c878a2594b15d203e513acf952340wwang result = mode_sense(srb, chip); 315777d89b08766c878a2594b15d203e513acf952340wwang break; 315877d89b08766c878a2594b15d203e513acf952340wwang 315977d89b08766c878a2594b15d203e513acf952340wwang case 0x23: 316077d89b08766c878a2594b15d203e513acf952340wwang result = read_format_capacity(srb, chip); 316177d89b08766c878a2594b15d203e513acf952340wwang break; 316277d89b08766c878a2594b15d203e513acf952340wwang 316377d89b08766c878a2594b15d203e513acf952340wwang case VENDOR_CMND: 316477d89b08766c878a2594b15d203e513acf952340wwang result = vendor_cmnd(srb, chip); 316577d89b08766c878a2594b15d203e513acf952340wwang break; 316677d89b08766c878a2594b15d203e513acf952340wwang 316777d89b08766c878a2594b15d203e513acf952340wwang case MS_SP_CMND: 316877d89b08766c878a2594b15d203e513acf952340wwang result = ms_sp_cmnd(srb, chip); 316977d89b08766c878a2594b15d203e513acf952340wwang break; 317077d89b08766c878a2594b15d203e513acf952340wwang 317177d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_CPRM 317277d89b08766c878a2594b15d203e513acf952340wwang case SD_PASS_THRU_MODE: 317377d89b08766c878a2594b15d203e513acf952340wwang case SD_EXECUTE_NO_DATA: 317477d89b08766c878a2594b15d203e513acf952340wwang case SD_EXECUTE_READ: 317577d89b08766c878a2594b15d203e513acf952340wwang case SD_EXECUTE_WRITE: 317677d89b08766c878a2594b15d203e513acf952340wwang case SD_GET_RSP: 317777d89b08766c878a2594b15d203e513acf952340wwang case SD_HW_RST: 317877d89b08766c878a2594b15d203e513acf952340wwang result = sd_extention_cmnd(srb, chip); 317977d89b08766c878a2594b15d203e513acf952340wwang break; 318077d89b08766c878a2594b15d203e513acf952340wwang#endif 318177d89b08766c878a2594b15d203e513acf952340wwang 318277d89b08766c878a2594b15d203e513acf952340wwang#ifdef SUPPORT_MAGIC_GATE 318377d89b08766c878a2594b15d203e513acf952340wwang case CMD_MSPRO_MG_RKEY: 318477d89b08766c878a2594b15d203e513acf952340wwang result = mg_report_key(srb, chip); 318577d89b08766c878a2594b15d203e513acf952340wwang break; 318677d89b08766c878a2594b15d203e513acf952340wwang 318777d89b08766c878a2594b15d203e513acf952340wwang case CMD_MSPRO_MG_SKEY: 318877d89b08766c878a2594b15d203e513acf952340wwang result = mg_send_key(srb, chip); 318977d89b08766c878a2594b15d203e513acf952340wwang break; 319077d89b08766c878a2594b15d203e513acf952340wwang#endif 319177d89b08766c878a2594b15d203e513acf952340wwang 319277d89b08766c878a2594b15d203e513acf952340wwang case FORMAT_UNIT: 319377d89b08766c878a2594b15d203e513acf952340wwang case MODE_SELECT: 319477d89b08766c878a2594b15d203e513acf952340wwang case VERIFY: 319577d89b08766c878a2594b15d203e513acf952340wwang result = TRANSPORT_GOOD; 319677d89b08766c878a2594b15d203e513acf952340wwang break; 319777d89b08766c878a2594b15d203e513acf952340wwang 319877d89b08766c878a2594b15d203e513acf952340wwang default: 319977d89b08766c878a2594b15d203e513acf952340wwang set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); 320077d89b08766c878a2594b15d203e513acf952340wwang result = TRANSPORT_FAILED; 320177d89b08766c878a2594b15d203e513acf952340wwang } 320277d89b08766c878a2594b15d203e513acf952340wwang 320377d89b08766c878a2594b15d203e513acf952340wwang return result; 320477d89b08766c878a2594b15d203e513acf952340wwang} 3205