@@ -459,7 +459,7 @@ void ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
459
459
460
460
/* Get the descriptor */
461
461
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 +
463
463
GENERAL_UPIU_REQUEST_SIZE ;
464
464
u16 len ;
465
465
@@ -1133,6 +1133,30 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
1133
1133
return err ;
1134
1134
}
1135
1135
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
+
1136
1160
/**
1137
1161
* ufshcd_query_flag() - API function for sending flag query requests
1138
1162
* hba: per-adapter instance
@@ -1145,17 +1169,15 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
1145
1169
static int ufshcd_query_flag (struct ufs_hba * hba , enum query_opcode opcode ,
1146
1170
enum flag_idn idn , bool * flag_res )
1147
1171
{
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 ;
1151
1175
1152
1176
BUG_ON (!hba );
1153
1177
1154
1178
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 );
1159
1181
1160
1182
switch (opcode ) {
1161
1183
case UPIU_QUERY_OPCODE_SET_FLAG :
@@ -1180,12 +1202,8 @@ static int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
1180
1202
err = - EINVAL ;
1181
1203
goto out_unlock ;
1182
1204
}
1183
- request -> upiu_req .opcode = opcode ;
1184
- request -> upiu_req .idn = idn ;
1185
1205
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 );
1189
1207
1190
1208
if (err ) {
1191
1209
dev_err (hba -> dev ,
@@ -1217,8 +1235,8 @@ static int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode,
1217
1235
static int ufshcd_query_attr (struct ufs_hba * hba , enum query_opcode opcode ,
1218
1236
enum attr_idn idn , u8 index , u8 selector , u32 * attr_val )
1219
1237
{
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 ;
1222
1240
int err ;
1223
1241
1224
1242
BUG_ON (!hba );
@@ -1231,10 +1249,8 @@ static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
1231
1249
}
1232
1250
1233
1251
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 );
1238
1254
1239
1255
switch (opcode ) {
1240
1256
case UPIU_QUERY_OPCODE_WRITE_ATTR :
@@ -1251,14 +1267,7 @@ static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
1251
1267
goto out_unlock ;
1252
1268
}
1253
1269
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 );
1262
1271
1263
1272
if (err ) {
1264
1273
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,
1274
1283
return err ;
1275
1284
}
1276
1285
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
+
1277
1362
/**
1278
1363
* ufshcd_memory_alloc - allocate memory for host memory space data structures
1279
1364
* @hba: per adapter instance
0 commit comments