@@ -459,7 +459,7 @@ void ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
459459
460460 /* Get the descriptor */
461461 if (lrbp -> ucd_rsp_ptr -> qr .opcode == UPIU_QUERY_OPCODE_READ_DESC ) {
462- u8 * descp = (u8 * )& lrbp -> ucd_rsp_ptr +
462+ u8 * descp = (u8 * )lrbp -> ucd_rsp_ptr +
463463 GENERAL_UPIU_REQUEST_SIZE ;
464464 u16 len ;
465465
@@ -1133,6 +1133,30 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
11331133 return err ;
11341134}
11351135
1136+ /**
1137+ * ufshcd_init_query() - init the query response and request parameters
1138+ * @hba: per-adapter instance
1139+ * @request: address of the request pointer to be initialized
1140+ * @response: address of the response pointer to be initialized
1141+ * @opcode: operation to perform
1142+ * @idn: flag idn to access
1143+ * @index: LU number to access
1144+ * @selector: query/flag/descriptor further identification
1145+ */
1146+ static inline void ufshcd_init_query (struct ufs_hba * hba ,
1147+ struct ufs_query_req * * request , struct ufs_query_res * * response ,
1148+ enum query_opcode opcode , u8 idn , u8 index , u8 selector )
1149+ {
1150+ * request = & hba -> dev_cmd .query .request ;
1151+ * response = & hba -> dev_cmd .query .response ;
1152+ memset (* request , 0 , sizeof (struct ufs_query_req ));
1153+ memset (* response , 0 , sizeof (struct ufs_query_res ));
1154+ (* request )-> upiu_req .opcode = opcode ;
1155+ (* request )-> upiu_req .idn = idn ;
1156+ (* request )-> upiu_req .index = index ;
1157+ (* request )-> upiu_req .selector = selector ;
1158+ }
1159+
11361160/**
11371161 * ufshcd_query_flag() - API function for sending flag query requests
11381162 * hba: per-adapter instance
@@ -1145,17 +1169,15 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
11451169static int ufshcd_query_flag (struct ufs_hba * hba , enum query_opcode opcode ,
11461170 enum flag_idn idn , bool * flag_res )
11471171{
1148- struct ufs_query_req * request ;
1149- struct ufs_query_res * response ;
1150- int err ;
1172+ struct ufs_query_req * request = NULL ;
1173+ struct ufs_query_res * response = NULL ;
1174+ int err , index = 0 , selector = 0 ;
11511175
11521176 BUG_ON (!hba );
11531177
11541178 mutex_lock (& hba -> dev_cmd .lock );
1155- request = & hba -> dev_cmd .query .request ;
1156- response = & hba -> dev_cmd .query .response ;
1157- memset (request , 0 , sizeof (struct ufs_query_req ));
1158- memset (response , 0 , sizeof (struct ufs_query_res ));
1179+ ufshcd_init_query (hba , & request , & response , opcode , idn , index ,
1180+ selector );
11591181
11601182 switch (opcode ) {
11611183 case UPIU_QUERY_OPCODE_SET_FLAG :
@@ -1180,12 +1202,8 @@ static int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
11801202 err = - EINVAL ;
11811203 goto out_unlock ;
11821204 }
1183- request -> upiu_req .opcode = opcode ;
1184- request -> upiu_req .idn = idn ;
11851205
1186- /* Send query request */
1187- err = ufshcd_exec_dev_cmd (hba , DEV_CMD_TYPE_QUERY ,
1188- QUERY_REQ_TIMEOUT );
1206+ err = ufshcd_exec_dev_cmd (hba , DEV_CMD_TYPE_QUERY , QUERY_REQ_TIMEOUT );
11891207
11901208 if (err ) {
11911209 dev_err (hba -> dev ,
@@ -1217,8 +1235,8 @@ static int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
12171235static int ufshcd_query_attr (struct ufs_hba * hba , enum query_opcode opcode ,
12181236 enum attr_idn idn , u8 index , u8 selector , u32 * attr_val )
12191237{
1220- struct ufs_query_req * request ;
1221- struct ufs_query_res * response ;
1238+ struct ufs_query_req * request = NULL ;
1239+ struct ufs_query_res * response = NULL ;
12221240 int err ;
12231241
12241242 BUG_ON (!hba );
@@ -1231,10 +1249,8 @@ static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
12311249 }
12321250
12331251 mutex_lock (& hba -> dev_cmd .lock );
1234- request = & hba -> dev_cmd .query .request ;
1235- response = & hba -> dev_cmd .query .response ;
1236- memset (request , 0 , sizeof (struct ufs_query_req ));
1237- memset (response , 0 , sizeof (struct ufs_query_res ));
1252+ ufshcd_init_query (hba , & request , & response , opcode , idn , index ,
1253+ selector );
12381254
12391255 switch (opcode ) {
12401256 case UPIU_QUERY_OPCODE_WRITE_ATTR :
@@ -1251,14 +1267,7 @@ static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
12511267 goto out_unlock ;
12521268 }
12531269
1254- request -> upiu_req .opcode = opcode ;
1255- request -> upiu_req .idn = idn ;
1256- request -> upiu_req .index = index ;
1257- request -> upiu_req .selector = selector ;
1258-
1259- /* Send query request */
1260- err = ufshcd_exec_dev_cmd (hba , DEV_CMD_TYPE_QUERY ,
1261- QUERY_REQ_TIMEOUT );
1270+ err = ufshcd_exec_dev_cmd (hba , DEV_CMD_TYPE_QUERY , QUERY_REQ_TIMEOUT );
12621271
12631272 if (err ) {
12641273 dev_err (hba -> dev , "%s: opcode 0x%.2x for idn %d failed, err = %d\n" ,
@@ -1274,6 +1283,82 @@ static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
12741283 return err ;
12751284}
12761285
1286+ /**
1287+ * ufshcd_query_descriptor - API function for sending descriptor requests
1288+ * hba: per-adapter instance
1289+ * opcode: attribute opcode
1290+ * idn: attribute idn to access
1291+ * index: index field
1292+ * selector: selector field
1293+ * desc_buf: the buffer that contains the descriptor
1294+ * buf_len: length parameter passed to the device
1295+ *
1296+ * Returns 0 for success, non-zero in case of failure.
1297+ * The buf_len parameter will contain, on return, the length parameter
1298+ * received on the response.
1299+ */
1300+ int ufshcd_query_descriptor (struct ufs_hba * hba ,
1301+ enum query_opcode opcode , enum desc_idn idn , u8 index ,
1302+ u8 selector , u8 * desc_buf , int * buf_len )
1303+ {
1304+ struct ufs_query_req * request = NULL ;
1305+ struct ufs_query_res * response = NULL ;
1306+ int err ;
1307+
1308+ BUG_ON (!hba );
1309+
1310+ if (!desc_buf ) {
1311+ dev_err (hba -> dev , "%s: descriptor buffer required for opcode 0x%x\n" ,
1312+ __func__ , opcode );
1313+ err = - EINVAL ;
1314+ goto out ;
1315+ }
1316+
1317+ if (* buf_len <= QUERY_DESC_MIN_SIZE || * buf_len > QUERY_DESC_MAX_SIZE ) {
1318+ dev_err (hba -> dev , "%s: descriptor buffer size (%d) is out of range\n" ,
1319+ __func__ , * buf_len );
1320+ err = - EINVAL ;
1321+ goto out ;
1322+ }
1323+
1324+ mutex_lock (& hba -> dev_cmd .lock );
1325+ ufshcd_init_query (hba , & request , & response , opcode , idn , index ,
1326+ selector );
1327+ hba -> dev_cmd .query .descriptor = desc_buf ;
1328+ request -> upiu_req .length = * buf_len ;
1329+
1330+ switch (opcode ) {
1331+ case UPIU_QUERY_OPCODE_WRITE_DESC :
1332+ request -> query_func = UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST ;
1333+ break ;
1334+ case UPIU_QUERY_OPCODE_READ_DESC :
1335+ request -> query_func = UPIU_QUERY_FUNC_STANDARD_READ_REQUEST ;
1336+ break ;
1337+ default :
1338+ dev_err (hba -> dev ,
1339+ "%s: Expected query descriptor opcode but got = 0x%.2x\n" ,
1340+ __func__ , opcode );
1341+ err = - EINVAL ;
1342+ goto out_unlock ;
1343+ }
1344+
1345+ err = ufshcd_exec_dev_cmd (hba , DEV_CMD_TYPE_QUERY , QUERY_REQ_TIMEOUT );
1346+
1347+ if (err ) {
1348+ dev_err (hba -> dev , "%s: opcode 0x%.2x for idn %d failed, err = %d\n" ,
1349+ __func__ , opcode , idn , err );
1350+ goto out_unlock ;
1351+ }
1352+
1353+ hba -> dev_cmd .query .descriptor = NULL ;
1354+ * buf_len = response -> upiu_res .length ;
1355+
1356+ out_unlock :
1357+ mutex_unlock (& hba -> dev_cmd .lock );
1358+ out :
1359+ return err ;
1360+ }
1361+
12771362/**
12781363 * ufshcd_memory_alloc - allocate memory for host memory space data structures
12791364 * @hba: per adapter instance
0 commit comments