1616
1717#include <errno.h>
1818#include <fcntl.h>
19+ #include <scsi/scsi.h>
20+ #include <scsi/scsi_proto.h>
1921#include <scsi/sg.h>
22+ #include <stdbool.h>
2023#include <stdint.h>
2124#include <stdio.h>
2225#include <stdlib.h>
@@ -104,21 +107,62 @@ static enum dev_type dev_type = UNKNOWN_RPMB;
104107
105108static const char * UFS_WAKE_LOCK_NAME = "ufs_seq_wakelock" ;
106109
107- #ifdef RPMB_DEBUG
108-
109- static void print_buf (const char * prefix , const uint8_t * buf , size_t size ) {
110+ /**
111+ * log_buf - Log a byte buffer to the android log.
112+ * @priority: One of ANDROID_LOG_* priority levels from android_LogPriority in
113+ * android/log.h
114+ * @prefix: A null-terminated string that identifies this buffer. Must be less
115+ * than 128 bytes.
116+ * @buf: Buffer to dump.
117+ * @size: Length of @buf in bytes.
118+ */
119+ #define LOG_BUF_SIZE 256
120+ static int log_buf (int priority , const char * prefix , const uint8_t * buf , size_t size ) {
121+ int rc ;
110122 size_t i ;
123+ char line [LOG_BUF_SIZE ] = {0 };
124+ char * cur = line ;
111125
112- printf ("%s @%p [%zu]" , prefix , buf , size );
126+ rc = snprintf (line , LOG_BUF_SIZE , "%s @%p [%zu]" , prefix , buf , size );
127+ if (rc < 0 || rc >= LOG_BUF_SIZE ) {
128+ goto err ;
129+ }
130+ cur += rc ;
113131 for (i = 0 ; i < size ; i ++ ) {
114- if (i && i % 32 == 0 ) printf ("\n%*s" , (int )strlen (prefix ), "" );
115- printf (" %02x" , buf [i ]);
132+ if (i % 32 == 0 ) {
133+ /*
134+ * Flush the line out to the log after we have printed 32 bytes
135+ * (also flushes the header line on the first iteration and sets up
136+ * for printing the buffer itself)
137+ */
138+ LOG_PRI (priority , LOG_TAG , "%s" , line );
139+ memset (line , 0 , LOG_BUF_SIZE );
140+ cur = line ;
141+ /* Shift output over by the length of the prefix */
142+ rc = snprintf (line , LOG_BUF_SIZE , "%*s" , (int )strlen (prefix ), "" );
143+ if (rc < 0 || rc >= LOG_BUF_SIZE ) {
144+ goto err ;
145+ }
146+ cur += rc ;
147+ }
148+ rc = snprintf (cur , LOG_BUF_SIZE - (cur - line ), "%02x " , buf [i ]);
149+ if (rc < 0 || rc >= LOG_BUF_SIZE - (cur - line )) {
150+ goto err ;
151+ }
152+ cur += rc ;
116153 }
117- printf ("\n" );
118- fflush (stdout );
119- }
154+ LOG_PRI (priority , LOG_TAG , "%s" , line );
120155
121- #endif
156+ return 0 ;
157+
158+ err :
159+ if (rc < 0 ) {
160+ return rc ;
161+ } else {
162+ ALOGE ("log_buf prefix was too long" );
163+ return -1 ;
164+ }
165+ }
122166
123167static void set_sg_io_hdr (sg_io_hdr_t * io_hdrp , int dxfer_direction , unsigned char cmd_len ,
124168 unsigned char mx_sb_len , unsigned int dxfer_len , void * dxferp ,
@@ -135,6 +179,111 @@ static void set_sg_io_hdr(sg_io_hdr_t* io_hdrp, int dxfer_direction, unsigned ch
135179 io_hdrp -> timeout = TIMEOUT ;
136180}
137181
182+ /* Returns false if the sense data was valid and no errors were present */
183+ static bool check_scsi_sense (const uint8_t * sense_buf , size_t len ) {
184+ uint8_t response_code = 0 ;
185+ uint8_t sense_key = 0 ;
186+ uint8_t additional_sense_code = 0 ;
187+ uint8_t additional_sense_code_qualifier = 0 ;
188+ uint8_t additional_length = 0 ;
189+
190+ if (!sense_buf || len == 0 ) {
191+ ALOGE ("Invalid SCSI sense buffer, length: %zu\n" , len );
192+ return false;
193+ }
194+
195+ response_code = 0x7f & sense_buf [0 ];
196+
197+ if (response_code < 0x70 || response_code > 0x73 ) {
198+ ALOGE ("Invalid SCSI sense response code: %hhu\n" , response_code );
199+ return false;
200+ }
201+
202+ if (response_code >= 0x72 ) {
203+ /* descriptor format, SPC-6 4.4.2 */
204+ if (len > 1 ) {
205+ sense_key = 0xf & sense_buf [1 ];
206+ }
207+ if (len > 2 ) {
208+ additional_sense_code = sense_buf [2 ];
209+ }
210+ if (len > 3 ) {
211+ additional_sense_code_qualifier = sense_buf [3 ];
212+ }
213+ if (len > 7 ) {
214+ additional_length = sense_buf [7 ];
215+ }
216+ } else {
217+ /* fixed format, SPC-6 4.4.3 */
218+ if (len > 2 ) {
219+ sense_key = 0xf & sense_buf [2 ];
220+ }
221+ if (len > 7 ) {
222+ additional_length = sense_buf [7 ];
223+ }
224+ if (len > 12 ) {
225+ additional_sense_code = sense_buf [12 ];
226+ }
227+ if (len > 13 ) {
228+ additional_sense_code_qualifier = sense_buf [13 ];
229+ }
230+ }
231+
232+ switch (sense_key ) {
233+ case NO_SENSE :
234+ case 0x0f : /* COMPLETED, not present in kernel headers */
235+ ALOGD ("SCSI success with sense data: key=%hhu, asc=%hhu, ascq=%hhu\n" , sense_key ,
236+ additional_sense_code , additional_sense_code_qualifier );
237+ return true;
238+ }
239+
240+ ALOGE ("Unexpected SCSI sense data: key=%hhu, asc=%hhu, ascq=%hhu\n" , sense_key ,
241+ additional_sense_code , additional_sense_code_qualifier );
242+ log_buf (ANDROID_LOG_ERROR , "sense buffer: " , sense_buf , len );
243+ return false;
244+ }
245+
246+ static void check_sg_io_hdr (const sg_io_hdr_t * io_hdrp ) {
247+ if (io_hdrp -> status == 0 && io_hdrp -> host_status == 0 && io_hdrp -> driver_status == 0 ) {
248+ return ;
249+ }
250+
251+ if (io_hdrp -> status & 0x01 ) {
252+ ALOGE ("SG_IO received unknown status, LSB is set: %hhu" , io_hdrp -> status );
253+ }
254+
255+ if (io_hdrp -> masked_status != GOOD && io_hdrp -> sb_len_wr > 0 ) {
256+ bool sense_error = check_scsi_sense (io_hdrp -> sbp , io_hdrp -> sb_len_wr );
257+ if (sense_error ) {
258+ ALOGE ("Unexpected SCSI sense. masked_status: %hhu, host_status: %hu, driver_status: "
259+ "%hu\n" ,
260+ io_hdrp -> masked_status , io_hdrp -> host_status , io_hdrp -> driver_status );
261+ return ;
262+ }
263+ }
264+
265+ switch (io_hdrp -> masked_status ) {
266+ case GOOD :
267+ break ;
268+ case CHECK_CONDITION :
269+ /* handled by check_sg_sense above */
270+ break ;
271+ default :
272+ ALOGE ("SG_IO failed with masked_status: %hhu, host_status: %hu, driver_status: %hu\n" ,
273+ io_hdrp -> masked_status , io_hdrp -> host_status , io_hdrp -> driver_status );
274+ return ;
275+ }
276+
277+ if (io_hdrp -> host_status != 0 ) {
278+ ALOGE ("SG_IO failed with host_status: %hu, driver_status: %hu\n" , io_hdrp -> host_status ,
279+ io_hdrp -> driver_status );
280+ }
281+
282+ if (io_hdrp -> resid != 0 ) {
283+ ALOGE ("SG_IO resid was non-zero: %d\n" , io_hdrp -> resid );
284+ }
285+ }
286+
138287static int send_mmc_rpmb_req (int mmc_fd , const struct storage_rpmb_send_req * req ) {
139288 struct {
140289 struct mmc_ioc_multi_cmd multi ;
@@ -153,7 +302,7 @@ static int send_mmc_rpmb_req(int mmc_fd, const struct storage_rpmb_send_req* req
153302 mmc_ioc_cmd_set_data ((* cmd ), write_buf );
154303#ifdef RPMB_DEBUG
155304 ALOGI ("opcode: 0x%x, write_flag: 0x%x\n" , cmd -> opcode , cmd -> write_flag );
156- print_buf ( "request: " , write_buf , req -> reliable_write_size );
305+ log_buf ( ANDROID_LOG_INFO , "request: " , write_buf , req -> reliable_write_size );
157306#endif
158307 write_buf += req -> reliable_write_size ;
159308 mmc .multi .num_of_cmds ++ ;
@@ -169,7 +318,7 @@ static int send_mmc_rpmb_req(int mmc_fd, const struct storage_rpmb_send_req* req
169318 mmc_ioc_cmd_set_data ((* cmd ), write_buf );
170319#ifdef RPMB_DEBUG
171320 ALOGI ("opcode: 0x%x, write_flag: 0x%x\n" , cmd -> opcode , cmd -> write_flag );
172- print_buf ( "request: " , write_buf , req -> write_size );
321+ log_buf ( ANDROID_LOG_INFO , "request: " , write_buf , req -> write_size );
173322#endif
174323 write_buf += req -> write_size ;
175324 mmc .multi .num_of_cmds ++ ;
@@ -225,6 +374,7 @@ static int send_ufs_rpmb_req(int sg_fd, const struct storage_rpmb_send_req* req)
225374 ALOGE ("%s: ufs ioctl failed: %d, %s\n" , __func__ , rc , strerror (errno ));
226375 goto err_op ;
227376 }
377+ check_sg_io_hdr (& io_hdr );
228378 write_buf += req -> reliable_write_size ;
229379 }
230380
@@ -239,6 +389,7 @@ static int send_ufs_rpmb_req(int sg_fd, const struct storage_rpmb_send_req* req)
239389 ALOGE ("%s: ufs ioctl failed: %d, %s\n" , __func__ , rc , strerror (errno ));
240390 goto err_op ;
241391 }
392+ check_sg_io_hdr (& io_hdr );
242393 write_buf += req -> write_size ;
243394 }
244395
@@ -252,6 +403,7 @@ static int send_ufs_rpmb_req(int sg_fd, const struct storage_rpmb_send_req* req)
252403 if (rc < 0 ) {
253404 ALOGE ("%s: ufs ioctl failed: %d, %s\n" , __func__ , rc , strerror (errno ));
254405 }
406+ check_sg_io_hdr (& io_hdr );
255407 }
256408
257409err_op :
@@ -353,7 +505,7 @@ int rpmb_send(struct storage_msg* msg, const void* r, size_t req_len) {
353505 goto err_response ;
354506 }
355507#ifdef RPMB_DEBUG
356- if (req -> read_size ) print_buf ( "response: " , read_buf , req -> read_size );
508+ if (req -> read_size ) log_buf ( ANDROID_LOG_INFO , "response: " , read_buf , req -> read_size );
357509#endif
358510
359511 if (msg -> flags & STORAGE_MSG_FLAG_POST_COMMIT ) {
0 commit comments