// SPDX-License-Identifier: GPL-2.0-or-later/* * SBP2 driver (SCSI over IEEE1394) * * Copyright (C) 2005-2007 Kristian Hoegsberg <krh@bitplanet.net> */ /* * The basic structure of this driver is based on the old storage driver, * drivers/ieee1394/sbp2.c, originally written by * James Goodwin <jamesg@filanet.com> * with later contributions and ongoing maintenance from * Ben Collins <bcollins@debian.org>, * Stefan Richter <stefanr@s5r6.in-berlin.de> * and many others. */ #include <linux/blkdev.h>#include <linux/bug.h>#include <linux/completion.h>#include <linux/delay.h>#include <linux/device.h>#include <linux/dma-mapping.h>#include <linux/firewire.h>#include <linux/firewire-constants.h>#include <linux/init.h>#include <linux/jiffies.h>#include <linux/kernel.h>#include <linux/kref.h>#include <linux/list.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/scatterlist.h>#include <linux/slab.h>#include <linux/spinlock.h>#include <linux/string.h>#include <linux/stringify.h>#include <linux/workqueue.h> #include <asm/byteorder.h> #include <scsi/scsi.h>#include <scsi/scsi_cmnd.h>#include <scsi/scsi_device.h>#include <scsi/scsi_host.h> /* * So far only bridges from Oxford Semiconductor are known to support * concurrent logins. Depending on firmware, four or two concurrent logins * are possible on OXFW911 and newer Oxsemi bridges. * * Concurrent logins are useful together with cluster filesystems. */static bool sbp2_param_exclusive_login = 1;module_param_named(exclusive_login, sbp2_param_exclusive_login, bool, 0644);MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " "(default = Y, use N for concurrent initiators)"); /* * Flags for firmware oddities * * - 128kB max transfer * Limit transfer size. Necessary for some old bridges. * * - 36 byte inquiry * When scsi_mod probes the device, let the inquiry command look like that * from MS Windows. * * - skip mode page 8 * Suppress sending of mode_sense for mode page 8 if the device pretends to * support the SCSI Primary Block commands instead of Reduced Block Commands. * * - fix capacity * Tell sd_mod to correct the last sector number reported by read_capacity. * Avoids access beyond actual disk limits on devices with an off-by-one bug. * Don't use this with devices which don't have this bug. * * - delay inquiry * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry. * * - power condition * Set the power condition field in the START STOP UNIT commands sent by * sd_mod on suspend, resume, and shutdown (if manage_system_start_stop or * manage_runtime_start_stop is on). * Some disks need this to spin down or to resume properly. * * - override internal blacklist * Instead of adding to the built-in blacklist, use only the workarounds * specified in the module load parameter. * Useful if a blacklist entry interfered with a non-broken device. */#define SBP2_WORKAROUND_128K_MAX_TRANS 0x1#define SBP2_WORKAROUND_INQUIRY_36 0x2#define SBP2_WORKAROUND_MODE_SENSE_8 0x4#define SBP2_WORKAROUND_FIX_CAPACITY 0x8#define SBP2_WORKAROUND_DELAY_INQUIRY 0x10#define SBP2_INQUIRY_DELAY 12#define SBP2_WORKAROUND_POWER_CONDITION 0x20#define SBP2_WORKAROUND_OVERRIDE 0x100 static int sbp2_param_workarounds;module_param_named(workarounds, sbp2_param_workarounds, int, 0644);MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" ", 128kB max transfer = " __stringify(SBP2_WORKAROUND_128K_MAX_TRANS) ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36) ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY) ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY) ", set power condition in start stop unit = " __stringify(SBP2_WORKAROUND_POWER_CONDITION) ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) ", or a combination)"); /* * We create one struct sbp2_logical_unit per SBP-2 Logical Unit Number Entry * and one struct scsi_device per sbp2_logical_unit. */struct sbp2_logical_unit { struct sbp2_target *tgt; struct list_head link; struct fw_address_handler address_handler; struct list_head orb_list; u64 command_block_agent_address; u16 lun; int login_id; /* * The generation is updated once we've logged in or reconnected * to the logical unit. Thus, I/O to the device will automatically * fail and get retried if it happens in a window where the device * is not ready, e.g. after a bus reset but before we reconnect. */ int generation; int retries; work_func_t workfn; struct delayed_work work; bool has_sdev; bool blocked;}; static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay){ queue_delayed_work(fw_workqueue, &lu->work, delay);} /* * We create one struct sbp2_target per IEEE 1212 Unit Directory * and one struct Scsi_Host per sbp2_target. */struct sbp2_target { struct fw_unit *unit; struct list_head lu_list; u64 management_agent_address; u64 guid; int directory_id; int node_id; int address_high; unsigned int workarounds; unsigned int mgt_orb_timeout; unsigned int max_payload; spinlock_t lock; int dont_block; /* counter for each logical unit */ int blocked; /* ditto */}; static struct fw_device *target_parent_device(struct sbp2_target *tgt){ return fw_parent_device(tgt->unit);} static const struct device *tgt_dev(const struct sbp2_target *tgt){ return &tgt->unit->device;} static const struct device *lu_dev(const struct sbp2_logical_unit *lu){ return &lu->tgt->unit->device;} /* Impossible login_id, to detect logout attempt before successful login */#define INVALID_LOGIN_ID 0x10000 #define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */#define SBP2_ORB_NULL 0x80000000#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 maximum SBP-2 data buffer size is 0xffff. We quadlet-align this * for compatibility with earlier versions of this driver. */#define SBP2_MAX_SEG_SIZE 0xfffc /* Unit directory keys */#define SBP2_CSR_UNIT_CHARACTERISTICS 0x3a#define SBP2_CSR_FIRMWARE_REVISION 0x3c#define SBP2_CSR_LOGICAL_UNIT_NUMBER 0x14#define SBP2_CSR_UNIT_UNIQUE_ID 0x8d#define SBP2_CSR_LOGICAL_UNIT_DIRECTORY 0xd4 /* Management orb opcodes */#define SBP2_LOGIN_REQUEST 0x0#define SBP2_QUERY_LOGINS_REQUEST 0x1#define SBP2_RECONNECT_REQUEST 0x3#define SBP2_SET_PASSWORD_REQUEST 0x4#define SBP2_LOGOUT_REQUEST 0x7#define SBP2_ABORT_TASK_REQUEST 0xb#define SBP2_ABORT_TASK_SET 0xc#define SBP2_LOGICAL_UNIT_RESET 0xe#define SBP2_TARGET_RESET_REQUEST 0xf /* Offsets for command block agent registers */#define SBP2_AGENT_STATE 0x00#define SBP2_AGENT_RESET 0x04#define SBP2_ORB_POINTER 0x08#define SBP2_DOORBELL 0x10#define SBP2_UNSOLICITED_STATUS_ENABLE 0x14 /* Status write response codes */#define SBP2_STATUS_REQUEST_COMPLETE 0x0#define SBP2_STATUS_TRANSPORT_FAILURE 0x1#define SBP2_STATUS_ILLEGAL_REQUEST 0x2#define SBP2_STATUS_VENDOR_DEPENDENT 0x3 #define STATUS_GET_ORB_HIGH(v) ((v).status & 0xffff)#define STATUS_GET_SBP_STATUS(v) (((v).status >> 16) & 0xff)#define STATUS_GET_LEN(v) (((v).status >> 24) & 0x07)#define STATUS_GET_DEAD(v) (((v).status >> 27) & 0x01)#define STATUS_GET_RESPONSE(v) (((v).status >> 28) & 0x03)#define STATUS_GET_SOURCE(v) (((v).status >> 30) & 0x03)#define STATUS_GET_ORB_LOW(v) ((v).orb_low)#define STATUS_GET_DATA(v) ((v).data) struct sbp2_status { u32 status; u32 orb_low; u8 data[24];}; struct sbp2_pointer { __be32 high; __be32 low;}; struct sbp2_orb { struct fw_transaction t; struct kref kref; dma_addr_t request_bus; int rcode; void (*callback)(struct sbp2_orb * orb, struct sbp2_status * status); struct sbp2_logical_unit *lu; struct list_head link;}; #define MANAGEMENT_ORB_LUN(v) ((v))#define MANAGEMENT_ORB_FUNCTION(v) ((v) << 16)#define MANAGEMENT_ORB_RECONNECT(v) ((v) << 20)#define MANAGEMENT_ORB_EXCLUSIVE(v) ((v) ? 1 << 28 : 0)#define MANAGEMENT_ORB_REQUEST_FORMAT(v) ((v) << 29)#define MANAGEMENT_ORB_NOTIFY ((1) << 31) #define MANAGEMENT_ORB_RESPONSE_LENGTH(v) ((v))#define MANAGEMENT_ORB_PASSWORD_LENGTH(v) ((v) << 16) struct sbp2_management_orb { struct sbp2_orb base; struct { struct sbp2_pointer password; struct sbp2_pointer response; __be32 misc; __be32 length; struct sbp2_pointer status_fifo; } request; __be32 response[4]; dma_addr_t response_bus; struct completion done; struct sbp2_status status;}; struct sbp2_login_response { __be32 misc; struct sbp2_pointer command_block_agent; __be32 reconnect_hold;};#define COMMAND_ORB_DATA_SIZE(v) ((v))#define COMMAND_ORB_PAGE_SIZE(v) ((v) << 16)#define COMMAND_ORB_PAGE_TABLE_PRESENT ((1) << 19)#define COMMAND_ORB_MAX_PAYLOAD(v) ((v) << 20)#define COMMAND_ORB_SPEED(v) ((v) << 24)#define COMMAND_ORB_DIRECTION ((1) << 27)#define COMMAND_ORB_REQUEST_FORMAT(v) ((v) << 29)#define COMMAND_ORB_NOTIFY ((1) << 31) struct sbp2_command_orb { struct sbp2_orb base; struct { struct sbp2_pointer next; struct sbp2_pointer data_descriptor; __be32 misc; u8 command_block[SBP2_MAX_CDB_SIZE]; } request; struct scsi_cmnd *cmd; struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8))); dma_addr_t page_table_bus;}; #define SBP2_ROM_VALUE_WILDCARD ~0 /* match all */#define SBP2_ROM_VALUE_MISSING 0xff000000 /* not present in the unit dir. */ /* * List of devices with known bugs. * * The firmware_revision field, masked with 0xffff00, is the best * indicator for the type of bridge chip of a device. It yields a few * false positives but this did not break correctly behaving devices * so far. */static const struct { u32 firmware_revision; u32 model; unsigned int workarounds;} sbp2_workarounds_table[] = { /* DViCO Momobay CX-1 with TSB42AA9 bridge */ { .firmware_revision = 0x002800, .model = 0x001010, .workarounds = SBP2_WORKAROUND_INQUIRY_36 | SBP2_WORKAROUND_MODE_SENSE_8 | SBP2_WORKAROUND_POWER_CONDITION, }, /* DViCO Momobay FX-3A with TSB42AA9A bridge */ { .firmware_revision = 0x002800, .model = 0x000000, .workarounds = SBP2_WORKAROUND_POWER_CONDITION, }, /* Initio bridges, actually only needed for some older ones */ { .firmware_revision = 0x000200, .model = SBP2_ROM_VALUE_WILDCARD, .workarounds = SBP2_WORKAROUND_INQUIRY_36, }, /* PL-3507 bridge with Prolific firmware */ { .firmware_revision = 0x012800, .model = SBP2_ROM_VALUE_WILDCARD, .workarounds = SBP2_WORKAROUND_POWER_CONDITION, }, /* Symbios bridge */ { .firmware_revision = 0xa0b800, .model = SBP2_ROM_VALUE_WILDCARD, .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, }, /* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ { .firmware_revision = 0x002600, .model = SBP2_ROM_VALUE_WILDCARD, .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, }, /* * iPod 2nd generation: needs 128k max transfer size workaround * iPod 3rd generation: needs fix capacity workaround */ { .firmware_revision = 0x0a2700, .model = 0x000000, .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS | SBP2_WORKAROUND_FIX_CAPACITY, }, /* iPod 4th generation */ { .firmware_revision = 0x0a2700, .model = 0x000021, .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, }, /* iPod mini */ { .firmware_revision = 0x0a2700, .model = 0x000022, .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, }, /* iPod mini */ { .firmware_revision = 0x0a2700, .model = 0x000023, .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, }, /* iPod Photo */ { .firmware_revision = 0x0a2700, .model = 0x00007e, .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, }}; static void free_orb(struct kref *kref){ struct sbp2_orb *orb = container_of(kref, struct sbp2_orb, kref); kfree(orb);} static void sbp2_status_write(struct fw_card *card, struct fw_request *request, int tcode, int destination, int source, int generation, unsigned long long offset, void *payload, size_t length, void *callback_data){ struct sbp2_logical_unit *lu = callback_data; struct sbp2_orb *orb = NULL, *iter; struct sbp2_status status; unsigned long flags; if (tcode != TCODE_WRITE_BLOCK_REQUEST || length < 8 || length > sizeof(status)) { fw_send_response(card, request, RCODE_TYPE_ERROR); return; } 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) { dev_notice(lu_dev(lu), "non-ORB related status write, not handled\n"); fw_send_response(card, request, RCODE_COMPLETE); return; } /* Lookup the orb corresponding to this status write. */ spin_lock_irqsave(&lu->tgt->lock, flags); list_for_each_entry(iter, &lu->orb_list, link) { if (STATUS_GET_ORB_HIGH(status) == 0 && STATUS_GET_ORB_LOW(status) == iter->request_bus) { iter->rcode = RCODE_COMPLETE; list_del(&iter->link); orb = iter; break; } } spin_unlock_irqrestore(&lu->tgt->lock, flags); if (orb) { orb->callback(orb, &status); kref_put(&orb->kref, free_orb); /* orb callback reference */ } else { dev_err(lu_dev(lu), "status write for unknown ORB\n"); } fw_send_response(card, request, RCODE_COMPLETE);} static void complete_transaction(struct fw_card *card, int rcode, void *payload, size_t length, void *data){ struct sbp2_orb *orb = data; unsigned long flags; /* * This is a little tricky. We can get the status write for * the orb before we get this callback. The status write * handler above will assume the orb pointer transaction was * successful and set the rcode to RCODE_COMPLETE for the orb. * So this callback only sets the rcode if it hasn't already * been set and only does the cleanup if the transaction * failed and we didn't already get a status write. */ spin_lock_irqsave(&orb->lu->tgt->lock, flags); if (orb->rcode == -1) orb->rcode = rcode; if (orb->rcode != RCODE_COMPLETE) { list_del(&orb->link); spin_unlock_irqrestore(&orb->lu->tgt->lock, flags); orb->callback(orb, NULL); kref_put(&orb->kref, free_orb); /* orb callback reference */ } else { spin_unlock_irqrestore(&orb->lu->tgt->lock, flags); } kref_put(&orb->kref, free_orb); /* transaction callback reference */} static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, int node_id, int generation, u64 offset){ struct fw_device *device = target_parent_device(lu->tgt); struct sbp2_pointer orb_pointer; unsigned long flags; orb_pointer.high = 0; orb_pointer.low = cpu_to_be32(orb->request_bus); orb->lu = lu; spin_lock_irqsave(&lu->tgt->lock, flags);Lines 1–500 of 1622. Load more
// SPDX-License-Identifier: GPL-2.0-or-later /* * SBP2 driver (SCSI over IEEE1394) * * Copyright (C) 2005-2007 Kristian Hoegsberg <krh@bitplanet.net> */ /* * The basic structure of this driver is based on the old storage driver, * drivers/ieee1394/sbp2.c, originally written by * James Goodwin <jamesg@filanet.com> * with later contributions and ongoing maintenance from * Ben Collins <bcollins@debian.org>, * Stefan Richter <stefanr@s5r6.in-berlin.de> * and many others. */ #include <linux/blkdev.h> #include <linux/bug.h> #include <linux/completion.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/firewire.h> #include <linux/firewire-constants.h> #include <linux/init.h> #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/kref.h> #include <linux/list.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/scatterlist.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/string.h> #include <linux/stringify.h> #include <linux/workqueue.h> #include <asm/byteorder.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> /* * So far only bridges from Oxford Semiconductor are known to support * concurrent logins. Depending on firmware, four or two concurrent logins * are possible on OXFW911 and newer Oxsemi bridges. * * Concurrent logins are useful together with cluster filesystems. */ static bool sbp2_param_exclusive_login = 1; module_param_named(exclusive_login, sbp2_param_exclusive_login, bool, 0644); MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " "(default = Y, use N for concurrent initiators)"); /* * Flags for firmware oddities * * - 128kB max transfer * Limit transfer size. Necessary for some old bridges. * * - 36 byte inquiry * When scsi_mod probes the device, let the inquiry command look like that * from MS Windows. * * - skip mode page 8 * Suppress sending of mode_sense for mode page 8 if the device pretends to * support the SCSI Primary Block commands instead of Reduced Block Commands. * * - fix capacity * Tell sd_mod to correct the last sector number reported by read_capacity. * Avoids access beyond actual disk limits on devices with an off-by-one bug. * Don't use this with devices which don't have this bug. * * - delay inquiry * Wait extra SBP2_INQUIRY_DELAY seconds after login before SCSI inquiry. * * - power condition * Set the power condition field in the START STOP UNIT commands sent by * sd_mod on suspend, resume, and shutdown (if manage_system_start_stop or * manage_runtime_start_stop is on). * Some disks need this to spin down or to resume properly. * * - override internal blacklist * Instead of adding to the built-in blacklist, use only the workarounds * specified in the module load parameter. * Useful if a blacklist entry interfered with a non-broken device. */ #define SBP2_WORKAROUND_128K_MAX_TRANS 0x1 #define SBP2_WORKAROUND_INQUIRY_36 0x2 #define SBP2_WORKAROUND_MODE_SENSE_8 0x4 #define SBP2_WORKAROUND_FIX_CAPACITY 0x8 #define SBP2_WORKAROUND_DELAY_INQUIRY 0x10 #define SBP2_INQUIRY_DELAY 12 #define SBP2_WORKAROUND_POWER_CONDITION 0x20 #define SBP2_WORKAROUND_OVERRIDE 0x100 static int sbp2_param_workarounds; module_param_named(workarounds, sbp2_param_workarounds, int, 0644); MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" ", 128kB max transfer = " __stringify(SBP2_WORKAROUND_128K_MAX_TRANS) ", 36 byte inquiry = " __stringify(SBP2_WORKAROUND_INQUIRY_36) ", skip mode page 8 = " __stringify(SBP2_WORKAROUND_MODE_SENSE_8) ", fix capacity = " __stringify(SBP2_WORKAROUND_FIX_CAPACITY) ", delay inquiry = " __stringify(SBP2_WORKAROUND_DELAY_INQUIRY) ", set power condition in start stop unit = " __stringify(SBP2_WORKAROUND_POWER_CONDITION) ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) ", or a combination)"); /* * We create one struct sbp2_logical_unit per SBP-2 Logical Unit Number Entry * and one struct scsi_device per sbp2_logical_unit. */ struct sbp2_logical_unit { struct sbp2_target *tgt; struct list_head link; struct fw_address_handler address_handler; struct list_head orb_list; u64 command_block_agent_address; u16 lun; int login_id; /* * The generation is updated once we've logged in or reconnected * to the logical unit. Thus, I/O to the device will automatically * fail and get retried if it happens in a window where the device * is not ready, e.g. after a bus reset but before we reconnect. */ int generation; int retries; work_func_t workfn; struct delayed_work work; bool has_sdev; bool blocked; }; static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay) { queue_delayed_work(fw_workqueue, &lu->work, delay); } /* * We create one struct sbp2_target per IEEE 1212 Unit Directory * and one struct Scsi_Host per sbp2_target. */ struct sbp2_target { struct fw_unit *unit; struct list_head lu_list; u64 management_agent_address; u64 guid; int directory_id; int node_id; int address_high; unsigned int workarounds; unsigned int mgt_orb_timeout; unsigned int max_payload; spinlock_t lock; int dont_block; /* counter for each logical unit */ int blocked; /* ditto */ }; static struct fw_device *target_parent_device(struct sbp2_target *tgt) { return fw_parent_device(tgt->unit); } static const struct device *tgt_dev(const struct sbp2_target *tgt) { return &tgt->unit->device; } static const struct device *lu_dev(const struct sbp2_logical_unit *lu) { return &lu->tgt->unit->device; } /* Impossible login_id, to detect logout attempt before successful login */ #define INVALID_LOGIN_ID 0x10000 #define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */ #define SBP2_ORB_NULL 0x80000000 #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 maximum SBP-2 data buffer size is 0xffff. We quadlet-align this * for compatibility with earlier versions of this driver. */ #define SBP2_MAX_SEG_SIZE 0xfffc /* Unit directory keys */ #define SBP2_CSR_UNIT_CHARACTERISTICS 0x3a #define SBP2_CSR_FIRMWARE_REVISION 0x3c #define SBP2_CSR_LOGICAL_UNIT_NUMBER 0x14 #define SBP2_CSR_UNIT_UNIQUE_ID 0x8d #define SBP2_CSR_LOGICAL_UNIT_DIRECTORY 0xd4 /* Management orb opcodes */ #define SBP2_LOGIN_REQUEST 0x0 #define SBP2_QUERY_LOGINS_REQUEST 0x1 #define SBP2_RECONNECT_REQUEST 0x3 #define SBP2_SET_PASSWORD_REQUEST 0x4 #define SBP2_LOGOUT_REQUEST 0x7 #define SBP2_ABORT_TASK_REQUEST 0xb #define SBP2_ABORT_TASK_SET 0xc #define SBP2_LOGICAL_UNIT_RESET 0xe #define SBP2_TARGET_RESET_REQUEST 0xf /* Offsets for command block agent registers */ #define SBP2_AGENT_STATE 0x00 #define SBP2_AGENT_RESET 0x04 #define SBP2_ORB_POINTER 0x08 #define SBP2_DOORBELL 0x10 #define SBP2_UNSOLICITED_STATUS_ENABLE 0x14 /* Status write response codes */ #define SBP2_STATUS_REQUEST_COMPLETE 0x0 #define SBP2_STATUS_TRANSPORT_FAILURE 0x1 #define SBP2_STATUS_ILLEGAL_REQUEST 0x2 #define SBP2_STATUS_VENDOR_DEPENDENT 0x3 #define STATUS_GET_ORB_HIGH(v) ((v).status & 0xffff) #define STATUS_GET_SBP_STATUS(v) (((v).status >> 16) & 0xff) #define STATUS_GET_LEN(v) (((v).status >> 24) & 0x07) #define STATUS_GET_DEAD(v) (((v).status >> 27) & 0x01) #define STATUS_GET_RESPONSE(v) (((v).status >> 28) & 0x03) #define STATUS_GET_SOURCE(v) (((v).status >> 30) & 0x03) #define STATUS_GET_ORB_LOW(v) ((v).orb_low) #define STATUS_GET_DATA(v) ((v).data) struct sbp2_status { u32 status; u32 orb_low; u8 data[24]; }; struct sbp2_pointer { __be32 high; __be32 low; }; struct sbp2_orb { struct fw_transaction t; struct kref kref; dma_addr_t request_bus; int rcode; void (*callback)(struct sbp2_orb * orb, struct sbp2_status * status); struct sbp2_logical_unit *lu; struct list_head link; }; #define MANAGEMENT_ORB_LUN(v) ((v)) #define MANAGEMENT_ORB_FUNCTION(v) ((v) << 16) #define MANAGEMENT_ORB_RECONNECT(v) ((v) << 20) #define MANAGEMENT_ORB_EXCLUSIVE(v) ((v) ? 1 << 28 : 0) #define MANAGEMENT_ORB_REQUEST_FORMAT(v) ((v) << 29) #define MANAGEMENT_ORB_NOTIFY ((1) << 31) #define MANAGEMENT_ORB_RESPONSE_LENGTH(v) ((v)) #define MANAGEMENT_ORB_PASSWORD_LENGTH(v) ((v) << 16) struct sbp2_management_orb { struct sbp2_orb base; struct { struct sbp2_pointer password; struct sbp2_pointer response; __be32 misc; __be32 length; struct sbp2_pointer status_fifo; } request; __be32 response[4]; dma_addr_t response_bus; struct completion done; struct sbp2_status status; }; struct sbp2_login_response { __be32 misc; struct sbp2_pointer command_block_agent; __be32 reconnect_hold; }; #define COMMAND_ORB_DATA_SIZE(v) ((v)) #define COMMAND_ORB_PAGE_SIZE(v) ((v) << 16) #define COMMAND_ORB_PAGE_TABLE_PRESENT ((1) << 19) #define COMMAND_ORB_MAX_PAYLOAD(v) ((v) << 20) #define COMMAND_ORB_SPEED(v) ((v) << 24) #define COMMAND_ORB_DIRECTION ((1) << 27) #define COMMAND_ORB_REQUEST_FORMAT(v) ((v) << 29) #define COMMAND_ORB_NOTIFY ((1) << 31) struct sbp2_command_orb { struct sbp2_orb base; struct { struct sbp2_pointer next; struct sbp2_pointer data_descriptor; __be32 misc; u8 command_block[SBP2_MAX_CDB_SIZE]; } request; struct scsi_cmnd *cmd; struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8))); dma_addr_t page_table_bus; }; #define SBP2_ROM_VALUE_WILDCARD ~0 /* match all */ #define SBP2_ROM_VALUE_MISSING 0xff000000 /* not present in the unit dir. */ /* * List of devices with known bugs. * * The firmware_revision field, masked with 0xffff00, is the best * indicator for the type of bridge chip of a device. It yields a few * false positives but this did not break correctly behaving devices * so far. */ static const struct { u32 firmware_revision; u32 model; unsigned int workarounds; } sbp2_workarounds_table[] = { /* DViCO Momobay CX-1 with TSB42AA9 bridge */ { .firmware_revision = 0x002800, .model = 0x001010, .workarounds = SBP2_WORKAROUND_INQUIRY_36 | SBP2_WORKAROUND_MODE_SENSE_8 | SBP2_WORKAROUND_POWER_CONDITION, }, /* DViCO Momobay FX-3A with TSB42AA9A bridge */ { .firmware_revision = 0x002800, .model = 0x000000, .workarounds = SBP2_WORKAROUND_POWER_CONDITION, }, /* Initio bridges, actually only needed for some older ones */ { .firmware_revision = 0x000200, .model = SBP2_ROM_VALUE_WILDCARD, .workarounds = SBP2_WORKAROUND_INQUIRY_36, }, /* PL-3507 bridge with Prolific firmware */ { .firmware_revision = 0x012800, .model = SBP2_ROM_VALUE_WILDCARD, .workarounds = SBP2_WORKAROUND_POWER_CONDITION, }, /* Symbios bridge */ { .firmware_revision = 0xa0b800, .model = SBP2_ROM_VALUE_WILDCARD, .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, }, /* Datafab MD2-FW2 with Symbios/LSILogic SYM13FW500 bridge */ { .firmware_revision = 0x002600, .model = SBP2_ROM_VALUE_WILDCARD, .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, }, /* * iPod 2nd generation: needs 128k max transfer size workaround * iPod 3rd generation: needs fix capacity workaround */ { .firmware_revision = 0x0a2700, .model = 0x000000, .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS | SBP2_WORKAROUND_FIX_CAPACITY, }, /* iPod 4th generation */ { .firmware_revision = 0x0a2700, .model = 0x000021, .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, }, /* iPod mini */ { .firmware_revision = 0x0a2700, .model = 0x000022, .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, }, /* iPod mini */ { .firmware_revision = 0x0a2700, .model = 0x000023, .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, }, /* iPod Photo */ { .firmware_revision = 0x0a2700, .model = 0x00007e, .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, } }; static void free_orb(struct kref *kref) { struct sbp2_orb *orb = container_of(kref, struct sbp2_orb, kref); kfree(orb); } static void sbp2_status_write(struct fw_card *card, struct fw_request *request, int tcode, int destination, int source, int generation, unsigned long long offset, void *payload, size_t length, void *callback_data) { struct sbp2_logical_unit *lu = callback_data; struct sbp2_orb *orb = NULL, *iter; struct sbp2_status status; unsigned long flags; if (tcode != TCODE_WRITE_BLOCK_REQUEST || length < 8 || length > sizeof(status)) { fw_send_response(card, request, RCODE_TYPE_ERROR); return; } 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) { dev_notice(lu_dev(lu), "non-ORB related status write, not handled\n"); fw_send_response(card, request, RCODE_COMPLETE); return; } /* Lookup the orb corresponding to this status write. */ spin_lock_irqsave(&lu->tgt->lock, flags); list_for_each_entry(iter, &lu->orb_list, link) { if (STATUS_GET_ORB_HIGH(status) == 0 && STATUS_GET_ORB_LOW(status) == iter->request_bus) { iter->rcode = RCODE_COMPLETE; list_del(&iter->link); orb = iter; break; } } spin_unlock_irqrestore(&lu->tgt->lock, flags); if (orb) { orb->callback(orb, &status); kref_put(&orb->kref, free_orb); /* orb callback reference */ } else { dev_err(lu_dev(lu), "status write for unknown ORB\n"); } fw_send_response(card, request, RCODE_COMPLETE); } static void complete_transaction(struct fw_card *card, int rcode, void *payload, size_t length, void *data) { struct sbp2_orb *orb = data; unsigned long flags; /* * This is a little tricky. We can get the status write for * the orb before we get this callback. The status write * handler above will assume the orb pointer transaction was * successful and set the rcode to RCODE_COMPLETE for the orb. * So this callback only sets the rcode if it hasn't already * been set and only does the cleanup if the transaction * failed and we didn't already get a status write. */ spin_lock_irqsave(&orb->lu->tgt->lock, flags); if (orb->rcode == -1) orb->rcode = rcode; if (orb->rcode != RCODE_COMPLETE) { list_del(&orb->link); spin_unlock_irqrestore(&orb->lu->tgt->lock, flags); orb->callback(orb, NULL); kref_put(&orb->kref, free_orb); /* orb callback reference */ } else { spin_unlock_irqrestore(&orb->lu->tgt->lock, flags); } kref_put(&orb->kref, free_orb); /* transaction callback reference */ } static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, int node_id, int generation, u64 offset) { struct fw_device *device = target_parent_device(lu->tgt); struct sbp2_pointer orb_pointer; unsigned long flags; orb_pointer.high = 0; orb_pointer.low = cpu_to_be32(orb->request_bus); orb->lu = lu; spin_lock_irqsave(&lu->tgt->lock, flags);