[haiku-commits] haiku: hrev44238 - src/add-ons/kernel/busses/scsi/ahci headers/private/drivers

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 11 Jun 2012 03:53:06 +0200 (CEST)

hrev44238 adds 2 changesets to branch 'master'
old head: 163cd4bf53064ff57a1feadc14f04d7c09fc8efc
new head: b937bd211c37af1cbd71f58ab0b1f272020f1103

----------------------------------------------------------------------------

3728636: scsi: Add write same SCSI operation
  
  * Will be used for TRIM

b937bd2: ahci: Initial TRIM work
  
  * Since ahci devices are emulated as scsi, we use
    the SAS style TRIM call (unmap in scsi write same)
  * This prevents the need for special, one off trim
    calls.
  * We don't perform the TRIM just yet, just laying
    the goundwork for the request.

                          [ Alexander von Gluck IV <kallisti5@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

3 files changed, 53 insertions(+), 3 deletions(-)
headers/private/drivers/scsi_cmds.h               |   23 ++++++++++++
src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp |   32 +++++++++++++++--
src/add-ons/kernel/busses/scsi/ahci/ahci_port.h   |    1 +

############################################################################

Commit:      372863638f6eb692e597c69b6677e2312a7ee600
URL:         http://cgit.haiku-os.org/haiku/commit/?id=3728636
Author:      Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date:        Fri Jun  8 15:48:21 2012 UTC

scsi: Add write same SCSI operation

* Will be used for TRIM

----------------------------------------------------------------------------

diff --git a/headers/private/drivers/scsi_cmds.h 
b/headers/private/drivers/scsi_cmds.h
index 2baabdd..1e1a47c 100644
--- a/headers/private/drivers/scsi_cmds.h
+++ b/headers/private/drivers/scsi_cmds.h
@@ -196,6 +196,7 @@
 #define SCSI_OP_READ_16                                                0x88
 #define SCSI_OP_WRITE_16                                       0x8a
 #define SCSI_OP_VERIFY_16                                      0x8f
+#define SCSI_OP_WRITE_SAME_16                          0x93
 #define SCSI_OP_SERVICE_ACTION_IN                      0x9e
 #define SCSI_OP_SERVICE_ACTION_OUT                     0x9f
 #define SCSI_OP_MOVE_MEDIUM                                    0xa5
@@ -435,6 +436,28 @@ typedef struct scsi_cmd_rw_16 {
 } _PACKED scsi_cmd_rw_16;
 
 
+// WRITE SAME (16)
+
+typedef struct scsi_cmd_wsame_16 {
+       uint8   opcode;
+       LBITFIELD8_6(
+               _res1_0 : 1,
+               lb_data : 1,
+               pb_data : 1,
+               unmap : 1,
+               _res1_4 : 1,
+               write_protect : 3
+       );
+       uint64  lba;
+       uint32  length;
+       LBITFIELD8_2(
+               group_number : 5,
+               _res14_5 : 3
+       );
+       uint8   control;
+} _PACKED scsi_cmd_wsame_16;
+       
+
 // REQUEST SENSE
 
 typedef struct scsi_cmd_request_sense {

############################################################################

Revision:    hrev44238
Commit:      b937bd211c37af1cbd71f58ab0b1f272020f1103
URL:         http://cgit.haiku-os.org/haiku/commit/?id=b937bd2
Author:      Alexander von Gluck IV <kallisti5@xxxxxxxxxxx>
Date:        Fri Jun  8 16:18:31 2012 UTC

ahci: Initial TRIM work

* Since ahci devices are emulated as scsi, we use
  the SAS style TRIM call (unmap in scsi write same)
* This prevents the need for special, one off trim
  calls.
* We don't perform the TRIM just yet, just laying
  the goundwork for the request.

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp 
b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp
index 74b042b..9b6da85 100644
--- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp
+++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp
@@ -50,7 +50,8 @@ AHCIPort::AHCIPort(AHCIController *controller, int index)
        fIsATAPI(false),
        fTestUnitReadyActive(false),
        fResetPort(false),
-       fError(false)
+       fError(false),
+       fTrim(false)
 {
        B_INITIALIZE_SPINLOCK(&fSpinlock);
        fRequestSem = create_sem(1, "ahci request");
@@ -613,6 +614,7 @@ AHCIPort::ScsiInquiry(scsi_ccb *request)
                fUse48BitCommands = lba && lba48;
                fSectorSize = 512;
                fSectorCount = !(lba || sectors) ? 0 : lba48 ? sectors48 : 
sectors;
+               fTrim = ataData.data_set_management_support;
                TRACE("lba %d, lba48 %d, fUse48BitCommands %d, sectors %lu, "
                        "sectors48 %llu, size %llu\n",
                        lba, lba48, fUse48BitCommands, sectors, sectors48,
@@ -641,8 +643,7 @@ AHCIPort::ScsiInquiry(scsi_ccb *request)
        TRACE("model number: %s\n", modelNumber);
        TRACE("serial number: %s\n", serialNumber);
        TRACE("firmware rev.: %s\n", firmwareRev);
-       TRACE("trim support: %s\n",
-               ataData.data_set_management_support ? "yes" : "no");
+       TRACE("trim support: %s\n", fTrim ? "yes" : "no");
 
        if (sg_memcpy(request->sg_list, request->sg_count, &scsiData,
                        sizeof(scsiData)) < B_OK) {
@@ -960,6 +961,31 @@ AHCIPort::ScsiExecuteRequest(scsi_ccb *request)
                        }
                        break;
                }
+               case SCSI_OP_WRITE_SAME_16:
+               {
+                       scsi_cmd_wsame_16 *cmd = (scsi_cmd_wsame_16 
*)request->cdb;
+
+                       // SCSI unmap is used for trim, otherwise we don't 
support it
+                       if (!cmd->unmap) {
+                               TRACE("%s port %d: unsupported request opcode 
0x%02x\n",
+                                       __func__, fIndex, request->cdb[0]);
+                               request->subsys_status = SCSI_REQ_ABORTED;
+                               gSCSI->finished(request, 1);
+                               break;
+                       }
+
+                       if (!fTrim) {
+                               // Drive doesn't support trim (or atapi)
+                               // Just say it was successful and quit
+                               request->subsys_status = SCSI_REQ_CMP;
+                       } else {
+                               TRACE("%s unimplemented: TRIM call\n", 
__func__);
+                               // TODO: Make Serial ATA (sata_request?) trim 
call here.
+                               request->subsys_status = SCSI_REQ_ABORTED;
+                       }
+                       gSCSI->finished(request, 1);
+                       break;
+               }
                default:
                        TRACE("AHCIPort::ScsiExecuteRequest port %d unsupported 
request "
                                "opcode 0x%02x\n", fIndex, request->cdb[0]);
diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h 
b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h
index 9781458..42b8e6b 100644
--- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h
+++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.h
@@ -70,6 +70,7 @@ private:
        bool                                                    
fTestUnitReadyActive;
        bool                                                    fResetPort;
        bool                                                    fError;
+       bool                                                    fTrim;
 
        volatile fis *                                  fFIS;
        volatile command_list_entry *   fCommandList;


Other related posts:

  • » [haiku-commits] haiku: hrev44238 - src/add-ons/kernel/busses/scsi/ahci headers/private/drivers - kallisti5