|
@@ -84,7 +84,7 @@ static int aoe_send_command ( struct aoe_session *aoe ) {
|
84
|
84
|
aoecmd->cmd_stat = command->cb.cmd_stat;
|
85
|
85
|
aoecmd->lba.u64 = cpu_to_le64 ( command->cb.lba.native );
|
86
|
86
|
if ( ! command->cb.lba48 )
|
87
|
|
- aoecmd->lba.bytes[3] |= command->cb.device;
|
|
87
|
+ aoecmd->lba.bytes[3] |= ( command->cb.device & ATA_DEV_MASK );
|
88
|
88
|
|
89
|
89
|
/* Fill data payload */
|
90
|
90
|
copy_from_user ( pkb_put ( pkb, command->data_out_len ),
|
|
@@ -244,8 +244,11 @@ void aoe_kick ( struct aoe_session *aoe ) {
|
244
|
244
|
* Issue ATA command via an open AoE session
|
245
|
245
|
*
|
246
|
246
|
* @v aoe AoE session
|
247
|
|
- * @v command AoE command
|
|
247
|
+ * @v command ATA command
|
248
|
248
|
* @ret rc Return status code
|
|
249
|
+ *
|
|
250
|
+ * The ATA command must fit within a single AoE frame (i.e. the sector
|
|
251
|
+ * count must not exceed AOE_MAX_COUNT).
|
249
|
252
|
*/
|
250
|
253
|
int aoe_issue ( struct aoe_session *aoe, struct ata_command *command ) {
|
251
|
254
|
aoe->command = command;
|
|
@@ -259,3 +262,46 @@ int aoe_issue ( struct aoe_session *aoe, struct ata_command *command ) {
|
259
|
262
|
|
260
|
263
|
return ( ( aoe->status & AOE_STATUS_ERR_MASK ) ? -EIO : 0 );
|
261
|
264
|
}
|
|
265
|
+
|
|
266
|
+/**
|
|
267
|
+ * Issue ATA command via an open AoE session
|
|
268
|
+ *
|
|
269
|
+ * @v aoe AoE session
|
|
270
|
+ * @v command ATA command
|
|
271
|
+ * @ret rc Return status code
|
|
272
|
+ *
|
|
273
|
+ * The ATA command will be split into several smaller ATA commands,
|
|
274
|
+ * each with a sector count no larger than AOE_MAX_COUNT.
|
|
275
|
+ */
|
|
276
|
+int aoe_issue_split ( struct aoe_session *aoe, struct ata_command *command ) {
|
|
277
|
+ struct ata_command subcommand;
|
|
278
|
+ unsigned int offset;
|
|
279
|
+ unsigned int count;
|
|
280
|
+ unsigned int data_len;
|
|
281
|
+ unsigned int status = 0;
|
|
282
|
+ int rc = 0;
|
|
283
|
+
|
|
284
|
+ /* Split ATA command into AoE-sized subcommands */
|
|
285
|
+ for ( offset = 0; offset < command->cb.count.native; offset += count ){
|
|
286
|
+ memcpy ( &subcommand, command, sizeof ( subcommand ) );
|
|
287
|
+ count = ( command->cb.count.native - offset );
|
|
288
|
+ if ( count > AOE_MAX_COUNT )
|
|
289
|
+ count = AOE_MAX_COUNT;
|
|
290
|
+ data_len = count * ATA_SECTOR_SIZE;
|
|
291
|
+ if ( subcommand.data_in_len )
|
|
292
|
+ subcommand.data_in_len = data_len;
|
|
293
|
+ if ( subcommand.data_out_len )
|
|
294
|
+ subcommand.data_out_len = data_len;
|
|
295
|
+ aoe->command_offset = ( offset * ATA_SECTOR_SIZE );
|
|
296
|
+ subcommand.cb.lba.native += offset;
|
|
297
|
+ subcommand.cb.count.native = count;
|
|
298
|
+ if ( ( rc = aoe_issue ( aoe, &subcommand ) ) != 0 )
|
|
299
|
+ goto done;
|
|
300
|
+ status |= subcommand.cb.cmd_stat;
|
|
301
|
+ }
|
|
302
|
+ command->cb.cmd_stat = status;
|
|
303
|
+
|
|
304
|
+ done:
|
|
305
|
+ aoe->command_offset = 0;
|
|
306
|
+ return rc;
|
|
307
|
+}
|