firewire: sbp2: remove a workaround for Momobay FX-3A
[sfrench/cifs-2.6.git] / drivers / firewire / sbp2.c
index 24c45635376a746ba9ae3e69ef53cfa7da1ab514..50f0176de61590e82b5ac2c0420139b8fe3bf1ea 100644 (file)
@@ -200,6 +200,12 @@ static struct fw_device *target_device(struct sbp2_target *tgt)
 #define SBP2_RETRY_LIMIT               0xf             /* 15 retries */
 #define SBP2_CYCLE_LIMIT               (0xc8 << 12)    /* 200 125us cycles */
 
+/*
+ * There is no transport protocol limit to the CDB length,  but we implement
+ * a fixed length only.  16 bytes is enough for disks larger than 2 TB.
+ */
+#define SBP2_MAX_CDB_SIZE              16
+
 /*
  * The default maximum s/g segment size of a FireWire controller is
  * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to
@@ -312,7 +318,7 @@ struct sbp2_command_orb {
                struct sbp2_pointer next;
                struct sbp2_pointer data_descriptor;
                __be32 misc;
-               u8 command_block[12];
+               u8 command_block[SBP2_MAX_CDB_SIZE];
        } request;
        struct scsi_cmnd *cmd;
        scsi_done_fn_t done;
@@ -348,8 +354,7 @@ static const struct {
        /* DViCO Momobay FX-3A with TSB42AA9A bridge */ {
                .firmware_revision      = 0x002800,
                .model                  = 0x000000,
-               .workarounds            = SBP2_WORKAROUND_DELAY_INQUIRY |
-                                         SBP2_WORKAROUND_POWER_CONDITION,
+               .workarounds            = SBP2_WORKAROUND_POWER_CONDITION,
        },
        /* Initio bridges, actually only needed for some older ones */ {
                .firmware_revision      = 0x000200,
@@ -419,19 +424,20 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
        struct sbp2_logical_unit *lu = callback_data;
        struct sbp2_orb *orb;
        struct sbp2_status status;
-       size_t header_size;
        unsigned long flags;
 
        if (tcode != TCODE_WRITE_BLOCK_REQUEST ||
-           length == 0 || length > sizeof(status)) {
+           length < 8 || length > sizeof(status)) {
                fw_send_response(card, request, RCODE_TYPE_ERROR);
                return;
        }
 
-       header_size = min(length, 2 * sizeof(u32));
-       fw_memcpy_from_be32(&status, payload, header_size);
-       if (length > header_size)
-               memcpy(status.data, payload + 8, length - header_size);
+       status.status  = be32_to_cpup(payload);
+       status.orb_low = be32_to_cpup(payload + 4);
+       memset(status.data, 0, sizeof(status.data));
+       if (length > 8)
+               memcpy(status.data, payload + 8, length - 8);
+
        if (STATUS_GET_SOURCE(status) == 2 || STATUS_GET_SOURCE(status) == 3) {
                fw_notify("non-orb related status write, not handled\n");
                fw_send_response(card, request, RCODE_COMPLETE);
@@ -450,12 +456,12 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
        }
        spin_unlock_irqrestore(&card->lock, flags);
 
-       if (&orb->link != &lu->orb_list)
+       if (&orb->link != &lu->orb_list) {
                orb->callback(orb, &status);
-       else
+               kref_put(&orb->kref, free_orb);
+       } else {
                fw_error("status write for unknown orb\n");
-
-       kref_put(&orb->kref, free_orb);
+       }
 
        fw_send_response(card, request, RCODE_COMPLETE);
 }
@@ -1146,6 +1152,8 @@ static int sbp2_probe(struct device *dev)
        if (fw_device_enable_phys_dma(device) < 0)
                goto fail_shost_put;
 
+       shost->max_cmd_len = SBP2_MAX_CDB_SIZE;
+
        if (scsi_add_host(shost, &unit->device) < 0)
                goto fail_shost_put;