GIT a3969631e1eaf16ef67e9da2b601cac63c2c1b43 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/scjody/ieee1394.git#for-mm commit a3969631e1eaf16ef67e9da2b601cac63c2c1b43 Author: Stefan Richter Date: Sat May 13 14:36:54 2006 +0200 drivers/ieee1394/ohci1394.c: function calls without effect ohci1394: Remove superfluous call to free_dma_rcv_ctx, spotted by Adrian Bunk. Also remove some superfluous comments. Signed-off-by: Stefan Richter Cc: Jody McIntyre Cc: Ben Collins Signed-off-by: Andrew Morton Signed-off-by: Jody McIntyre commit 039848d523e958586ce6047d228ea1317f261524 Author: Arjan van de Ven Date: Sat May 13 14:36:47 2006 +0200 sem2mutex: drivers/ieee1394 Semaphore to mutex conversion. The conversion was generated via scripts, and the result was validated automatically via a script as well. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Cc: Ben Collins Cc: Jody McIntyre Signed-off-by: Andrew Morton Signed-off-by: Jody McIntyre commit 0a92bf6a7b03772d03db1f308400c7a1f1ddb8e4 Author: Jody McIntyre Date: Tue Apr 18 05:46:54 2006 -0400 Update feature removal of obsolete raw1394 ISO requests. Signed-off-by: Jody McIntyre commit 6b7e9fd1d2f2def1bf4149ea450d9c21dcfed2d1 Author: Stefan Richter Date: Tue Apr 18 05:38:20 2006 -0400 This code became ineffective a few Linux releases ago and is apparently not required anyway. Signed-off-by: Stefan Richter Signed-off-by: Jody McIntyre commit d3c0b1a18a20d69c12039d6b5bd517d8be320558 Author: Christoph Hellwig Date: Tue Apr 18 05:38:14 2006 -0400 ieee1394_core: switch to kthread API Signed-off-by: Christoph Hellwig Signed-off-by: Jody McIntyre commit 044ca458efbc75dc6ea4bdc1a8cd8e717a225168 Author: Stefan Richter Date: Tue Apr 18 05:38:10 2006 -0400 sbp2: log number of supported concurrent logins Since this is useful information, promote it from a debug macro to a regular log message. The message appears only if the user set exclusive_login=0, therefore won't clutter the logs in normal use. Also update the comment on exclusive_login. Signed-off-by: Stefan Richter Signed-off-by: Jody McIntyre commit 49f43c3db6eba0f2801905dfd74e460fd553004a Author: Stefan Richter Date: Tue Apr 18 05:38:06 2006 -0400 sbp2: add ability to override hardwired blacklist In case the blacklist with workarounds for device bugs yields a false positive, the module load parameter can now also be used as an override instead of an addition to the blacklist. Signed-off-by: Stefan Richter Signed-off-by: Jody McIntyre commit 57d0ce47c23be49c4a49209fd50ca39c3e9589db Author: Stefan Richter Date: Tue Apr 18 05:38:02 2006 -0400 sbp2: make TSB42AA9 workaround specific to Momobay CX-1 The workarounds are not required for DViCO Momobay FX-3A and AFAIR not for Momobay CX-2. These contain an TSB42AA9A but feature the same firmware_revision value as the older DViCO Momobay CX-1. Signed-off-by: Stefan Richter Signed-off-by: Jody McIntyre commit b40ff0adc1ceae7489a9f72fae0820be0ef2fd75 Author: Stefan Richter Date: Tue Apr 18 05:37:19 2006 -0400 sbp2: add read_capacity workaround for iPod Apple decided to copy some USB stupidity over to FireWire. The sector number returned by iPods from read_capacity is one too many. This may cause I/O errors, especially if the kernel is configured for EFI partition support. We use the same workaround as usb-storage but have to check for different model IDs. http://marc.theaimsgroup.com/?t=114233262300001 https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=187409 Acknowledgements: Diagnosis and therapy by Mathieu Chouquet-Stringer , additional data about affected and unaffected Apple hardware from Vladimir Kotal, Sander De Graaf, Bryan Olmstead, Hugh Dixon. Signed-off-by: Stefan Richter Signed-off-by: Jody McIntyre commit 43a50be96266f6436bec710b176fac033528afaa Author: Stefan Richter Date: Tue Apr 18 05:36:41 2006 -0400 sbp2: consolidate workarounds Grand unification of the three types of workarounds we have so far. The "skip mode page 8" workaround is now limited to devices which pretend to be of TYPE_DISK instead of TYPE_RBC. This workaround is no longer enabled for Initio bridges since scsi_lib has an own fix. Patch update in anticipation of more workarounds: - Add module parameter "workarounds". - Deprecate parameter "force_inquiry_hack". - Compose the blacklist of a compound type for better readability and extensibility. - Remove a now unused #define. Signed-off-by: Stefan Richter Signed-off-by: Jody McIntyre --- diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 293fed1..4d52195 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -48,11 +48,20 @@ Who: Paul E. McKenney +Who: Jody McIntyre + +--------------------------- + +What: sbp2: module parameter "force_inquiry_hack" +When: July 2006 +Why: Superceded by parameter "workarounds". Both parameters are meant to be + used ad-hoc and for single devices only, i.e. not in modprobe.conf, + therefore the impact of this feature replacement should be low. +Who: Stefan Richter --------------------------- diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index ba09741..2d47b11 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "csr1212.h" #include "ieee1394.h" @@ -105,7 +106,7 @@ static int alloc_hostnum_cb(struct hpsb_ * Return Value: a pointer to the &hpsb_host if succesful, %NULL if * no memory was available. */ -static DECLARE_MUTEX(host_num_alloc); +static DEFINE_MUTEX(host_num_alloc); struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, struct device *dev) @@ -148,7 +149,7 @@ struct hpsb_host *hpsb_alloc_host(struct h->topology_map = h->csr.topology_map + 3; h->speed_map = (u8 *)(h->csr.speed_map + 2); - down(&host_num_alloc); + mutex_lock(&host_num_alloc); while (nodemgr_for_each_host(&hostnum, alloc_hostnum_cb)) hostnum++; @@ -167,7 +168,7 @@ struct hpsb_host *hpsb_alloc_host(struct class_device_register(&h->class_dev); get_device(&h->device); - up(&host_num_alloc); + mutex_unlock(&host_num_alloc); return h; } diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index be6854e..a4f492c 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -997,10 +998,8 @@ void abort_timedouts(unsigned long __opa * packets that have a "complete" function are sent here. This way, the * completion is run out of kernel context, and doesn't block the rest of * the stack. */ -static int khpsbpkt_pid = -1, khpsbpkt_kill; -static DECLARE_COMPLETION(khpsbpkt_complete); +static struct task_struct *khpsbpkt_thread; static struct sk_buff_head hpsbpkt_queue; -static DECLARE_MUTEX_LOCKED(khpsbpkt_sig); static void queue_packet_complete(struct hpsb_packet *packet) @@ -1011,9 +1010,7 @@ static void queue_packet_complete(struct } if (packet->complete_routine != NULL) { skb_queue_tail(&hpsbpkt_queue, packet->skb); - - /* Signal the kernel thread to handle this */ - up(&khpsbpkt_sig); + wake_up_process(khpsbpkt_thread); } return; } @@ -1025,19 +1022,9 @@ static int hpsbpkt_thread(void *__hi) void (*complete_routine)(void*); void *complete_data; - daemonize("khpsbpkt"); - current->flags |= PF_NOFREEZE; - while (1) { - if (down_interruptible(&khpsbpkt_sig)) { - printk("khpsbpkt: received unexpected signal?!\n" ); - break; - } - - if (khpsbpkt_kill) - break; - + while (!kthread_should_stop()) { while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) { packet = (struct hpsb_packet *)skb->data; @@ -1048,9 +1035,12 @@ static int hpsbpkt_thread(void *__hi) complete_routine(complete_data); } + + set_current_state(TASK_INTERRUPTIBLE ); + schedule(); } - complete_and_exit(&khpsbpkt_complete, 0); + return 0; } static int __init ieee1394_init(void) @@ -1065,10 +1055,10 @@ static int __init ieee1394_init(void) HPSB_ERR("Some features may not be available\n"); } - khpsbpkt_pid = kernel_thread(hpsbpkt_thread, NULL, CLONE_KERNEL); - if (khpsbpkt_pid < 0) { + khpsbpkt_thread = kthread_run(hpsbpkt_thread, NULL, "khpsbpkt"); + if (IS_ERR(khpsbpkt_thread)) { HPSB_ERR("Failed to start hpsbpkt thread!\n"); - ret = -ENOMEM; + ret = PTR_ERR(khpsbpkt_thread); goto exit_cleanup_config_roms; } @@ -1148,10 +1138,7 @@ release_all_bus: release_chrdev: unregister_chrdev_region(IEEE1394_CORE_DEV, 256); exit_release_kernel_thread: - if (khpsbpkt_pid >= 0) { - kill_proc(khpsbpkt_pid, SIGTERM, 1); - wait_for_completion(&khpsbpkt_complete); - } + kthread_stop(khpsbpkt_thread); exit_cleanup_config_roms: hpsb_cleanup_config_roms(); return ret; @@ -1172,12 +1159,7 @@ static void __exit ieee1394_cleanup(void bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); bus_unregister(&ieee1394_bus_type); - if (khpsbpkt_pid >= 0) { - khpsbpkt_kill = 1; - mb(); - up(&khpsbpkt_sig); - wait_for_completion(&khpsbpkt_complete); - } + kthread_stop(khpsbpkt_thread); hpsb_cleanup_config_roms(); diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 1922287..4ee98e0 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -3462,24 +3462,13 @@ static void ohci1394_pci_remove(struct p case OHCI_INIT_HAVE_TXRX_BUFFERS__MAYBE: /* The ohci_soft_reset() stops all DMA contexts, so we * dont need to do this. */ - /* Free AR dma */ free_dma_rcv_ctx(&ohci->ar_req_context); free_dma_rcv_ctx(&ohci->ar_resp_context); - - /* Free AT dma */ free_dma_trm_ctx(&ohci->at_req_context); free_dma_trm_ctx(&ohci->at_resp_context); - - /* Free IR dma */ free_dma_rcv_ctx(&ohci->ir_legacy_context); - - /* Free IT dma */ free_dma_trm_ctx(&ohci->it_legacy_context); - /* Free IR legacy dma */ - free_dma_rcv_ctx(&ohci->ir_legacy_context); - - case OHCI_INIT_HAVE_SELFID_BUFFER: pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, ohci->selfid_buf_cpu, diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index f420660..004485b 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -117,7 +118,8 @@ MODULE_PARM_DESC(serialize_io, "Serializ */ static int max_sectors = SBP2_MAX_SECTORS; module_param(max_sectors, int, 0444); -MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported (default = 255)"); +MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported (default = " + __stringify(SBP2_MAX_SECTORS) ")"); /* * Exclusive login to sbp2 device? In most cases, the sbp2 driver should @@ -125,28 +127,57 @@ MODULE_PARM_DESC(max_sectors, "Change ma * talking to a single sbp2 device at the same time (filesystem coherency, * etc.). If you're running an sbp2 device that supports multiple logins, * and you're either running read-only filesystems or some sort of special - * filesystem supporting multiple hosts (one such filesystem is OpenGFS, - * see opengfs.sourceforge.net for more info), then set exclusive_login - * to zero. Note: The Oxsemi OXFW911 sbp2 chipset supports up to four - * concurrent logins. + * filesystem supporting multiple hosts, e.g. OpenGFS, Oracle Cluster + * File System, or Lustre, then set exclusive_login to zero. + * + * 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. */ static int exclusive_login = 1; module_param(exclusive_login, int, 0644); MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device (default = 1)"); /* - * SCSI inquiry hack for really badly behaved sbp2 devices. Turn this on - * if your sbp2 device is not properly handling the SCSI inquiry command. - * This hack makes the inquiry look more like a typical MS Windows inquiry - * by enforcing 36 byte inquiry and avoiding access to mode_sense page 8. + * If any of the following workarounds is required for your device to work, + * please submit the kernel messages logged by sbp2 to the linux1394-devel + * mailing list. * - * If force_inquiry_hack=1 is required for your device to work, - * please submit the logged sbp2_firmware_revision value of this device to - * the linux1394-devel mailing list. - */ + * - 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. + * + * - 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. + */ +static int sbp2_default_workarounds; +module_param_named(workarounds, sbp2_default_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) + ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) + ", or a combination)"); + +/* legacy parameter */ static int force_inquiry_hack; module_param(force_inquiry_hack, int, 0644); -MODULE_PARM_DESC(force_inquiry_hack, "Force SCSI inquiry hack (default = 0)"); +MODULE_PARM_DESC(force_inquiry_hack, "Deprecated, use 'workarounds'"); /* * Export information about protocols/devices supported by this driver. @@ -266,14 +297,56 @@ static struct hpsb_protocol_driver sbp2_ }; /* - * List of device firmwares that require the inquiry hack. - * Yields a few false positives but did not break other devices so far. - */ -static u32 sbp2_broken_inquiry_list[] = { - 0x00002800, /* Stefan Richter */ - /* DViCO Momobay CX-1 */ - 0x00000200 /* Andreas Plesch */ - /* QPS Fire DVDBurner */ + * 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_id; + unsigned workarounds; +} sbp2_workarounds_table[] = { + /* DViCO Momobay CX-1 with TSB42AA9 bridge */ { + .firmware_revision = 0x002800, + .model_id = 0x001010, + .workarounds = SBP2_WORKAROUND_INQUIRY_36 | + SBP2_WORKAROUND_MODE_SENSE_8, + }, + /* Initio bridges, actually only needed for some older ones */ { + .firmware_revision = 0x000200, + .workarounds = SBP2_WORKAROUND_INQUIRY_36, + }, + /* Symbios bridge */ { + .firmware_revision = 0xa0b800, + .workarounds = SBP2_WORKAROUND_128K_MAX_TRANS, + }, + /* + * Note about the following Apple iPod blacklist entries: + * + * There are iPods (2nd gen, 3rd gen) with model_id==0. Since our + * matching logic treats 0 as a wildcard, we cannot match this ID + * without rewriting the matching routine. Fortunately these iPods + * do not feature the read_capacity bug according to one report. + * Read_capacity behaviour as well as model_id could change due to + * Apple-supplied firmware updates though. + */ + /* iPod 4th generation */ { + .firmware_revision = 0x0a2700, + .model_id = 0x000021, + .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, + }, + /* iPod mini */ { + .firmware_revision = 0x0a2700, + .model_id = 0x000023, + .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, + }, + /* iPod Photo */ { + .firmware_revision = 0x0a2700, + .model_id = 0x00007e, + .workarounds = SBP2_WORKAROUND_FIX_CAPACITY, + } }; /************************************** @@ -1138,13 +1211,11 @@ static int sbp2_query_logins(struct scsi SBP2_DEBUG("length_max_logins = %x", (unsigned int)scsi_id->query_logins_response->length_max_logins); - SBP2_DEBUG("Query logins to SBP-2 device successful"); - max_logins = RESPONSE_GET_MAX_LOGINS(scsi_id->query_logins_response->length_max_logins); - SBP2_DEBUG("Maximum concurrent logins supported: %d", max_logins); + SBP2_INFO("Maximum concurrent logins supported: %d", max_logins); active_logins = RESPONSE_GET_ACTIVE_LOGINS(scsi_id->query_logins_response->length_max_logins); - SBP2_DEBUG("Number of active logins: %d", active_logins); + SBP2_INFO("Number of active logins: %d", active_logins); if (active_logins >= max_logins) { return -EIO; @@ -1450,7 +1521,8 @@ static void sbp2_parse_unit_directory(st struct csr1212_dentry *dentry; u64 management_agent_addr; u32 command_set_spec_id, command_set, unit_characteristics, - firmware_revision, workarounds; + firmware_revision; + unsigned workarounds; int i; SBP2_DEBUG_ENTER(); @@ -1506,12 +1578,8 @@ static void sbp2_parse_unit_directory(st case SBP2_FIRMWARE_REVISION_KEY: /* Firmware revision */ firmware_revision = kv->value.immediate; - if (force_inquiry_hack) - SBP2_INFO("sbp2_firmware_revision = %x", - (unsigned int)firmware_revision); - else - SBP2_DEBUG("sbp2_firmware_revision = %x", - (unsigned int)firmware_revision); + SBP2_DEBUG("sbp2_firmware_revision = %x", + (unsigned int)firmware_revision); break; default: @@ -1519,41 +1587,44 @@ static void sbp2_parse_unit_directory(st } } - /* This is the start of our broken device checking. We try to hack - * around oddities and known defects. */ - workarounds = 0x0; - - /* If the vendor id is 0xa0b8 (Symbios vendor id), then we have a - * bridge with 128KB max transfer size limitation. For sanity, we - * only voice this when the current max_sectors setting - * exceeds the 128k limit. By default, that is not the case. - * - * It would be really nice if we could detect this before the scsi - * host gets initialized. That way we can down-force the - * max_sectors to account for it. That is not currently - * possible. */ - if ((firmware_revision & 0xffff00) == - SBP2_128KB_BROKEN_FIRMWARE && - (max_sectors * 512) > (128*1024)) { - SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB max transfer size.", - NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid)); - SBP2_WARN("WARNING: Current max_sectors setting is larger than 128KB (%d sectors)!", - max_sectors); - workarounds |= SBP2_BREAKAGE_128K_MAX_TRANSFER; - } - - /* Check for a blacklisted set of devices that require us to force - * a 36 byte host inquiry. This can be overriden as a module param - * (to force all hosts). */ - for (i = 0; i < ARRAY_SIZE(sbp2_broken_inquiry_list); i++) { - if ((firmware_revision & 0xffff00) == - sbp2_broken_inquiry_list[i]) { - SBP2_WARN("Node " NODE_BUS_FMT ": Using 36byte inquiry workaround", - NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid)); - workarounds |= SBP2_BREAKAGE_INQUIRY_HACK; - break; /* No need to continue. */ + workarounds = sbp2_default_workarounds; + if (force_inquiry_hack) { + SBP2_WARN("force_inquiry_hack is deprecated. " + "Use parameter 'workarounds' instead."); + workarounds |= SBP2_WORKAROUND_INQUIRY_36; + } + + if (!(workarounds & SBP2_WORKAROUND_OVERRIDE)) + for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) { + if (sbp2_workarounds_table[i].firmware_revision && + sbp2_workarounds_table[i].firmware_revision != + (firmware_revision & 0xffff00)) + continue; + if (sbp2_workarounds_table[i].model_id && + sbp2_workarounds_table[i].model_id != ud->model_id) + continue; + workarounds |= sbp2_workarounds_table[i].workarounds; + break; } - } + + if (workarounds) + SBP2_INFO("Workarounds for node " NODE_BUS_FMT ": 0x%x " + "(firmware_revision 0x%06x, vendor_id 0x%06x," + " model_id 0x%06x)", + NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid), + workarounds, firmware_revision, + ud->vendor_id ? ud->vendor_id : ud->ne->vendor_id, + ud->model_id); + + /* We would need one SCSI host template for each target to adjust + * max_sectors on the fly, therefore warn only. */ + if (workarounds & SBP2_WORKAROUND_128K_MAX_TRANS && + (max_sectors * 512) > (128 * 1024)) + SBP2_WARN("Node " NODE_BUS_FMT ": Bridge only supports 128KB " + "max transfer size. WARNING: Current max_sectors " + "setting is larger than 128KB (%d sectors)", + NODE_BUS_ARGS(ud->ne->host, ud->ne->nodeid), + max_sectors); /* If this is a logical unit directory entry, process the parent * to get the values. */ @@ -2038,33 +2109,6 @@ static unsigned int sbp2_status_to_sense } /* - * This function is called after a command is completed, in order to do any necessary SBP-2 - * response data translations for the SCSI stack - */ -static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, - struct scsi_cmnd *SCpnt) -{ - u8 *scsi_buf = SCpnt->request_buffer; - - SBP2_DEBUG_ENTER(); - - if (SCpnt->cmnd[0] == INQUIRY && (SCpnt->cmnd[1] & 3) == 0) { - /* - * Make sure data length is ok. Minimum length is 36 bytes - */ - if (scsi_buf[4] == 0) { - scsi_buf[4] = 36 - 5; - } - - /* - * Fix ansi revision and response data format - */ - scsi_buf[2] |= 2; - scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2; - } -} - -/* * This function deals with status writes from the SBP-2 device */ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid, @@ -2403,13 +2447,6 @@ static void sbp2scsi_complete_command(st } /* - * Take care of any sbp2 response data mucking here (RBC stuff, etc.) - */ - if (SCpnt->result == DID_OK << 16) { - sbp2_check_sbp2_response(scsi_id, SCpnt); - } - - /* * If a bus reset is in progress and there was an error, complete * the command as busy so that it will get retried. */ @@ -2447,19 +2484,25 @@ static int sbp2scsi_slave_alloc(struct s scsi_id->sdev = sdev; - if (force_inquiry_hack || - scsi_id->workarounds & SBP2_BREAKAGE_INQUIRY_HACK) { + if (scsi_id->workarounds & SBP2_WORKAROUND_INQUIRY_36) sdev->inquiry_len = 36; - sdev->skip_ms_page_8 = 1; - } return 0; } static int sbp2scsi_slave_configure(struct scsi_device *sdev) { + struct scsi_id_instance_data *scsi_id = + (struct scsi_id_instance_data *)sdev->host->hostdata[0]; + blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); sdev->use_10_for_rw = 1; sdev->use_10_for_ms = 1; + + if (sdev->type == TYPE_DISK && + scsi_id->workarounds & SBP2_WORKAROUND_MODE_SENSE_8) + sdev->skip_ms_page_8 = 1; + if (scsi_id->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) + sdev->fix_capacity = 1; return 0; } @@ -2603,7 +2646,9 @@ static int sbp2_module_init(void) scsi_driver_template.cmd_per_lun = 1; } - /* Set max sectors (module load option). Default is 255 sectors. */ + if (sbp2_default_workarounds & SBP2_WORKAROUND_128K_MAX_TRANS && + (max_sectors * 512) > (128 * 1024)) + max_sectors = 128 * 1024 / 512; scsi_driver_template.max_sectors = max_sectors; /* Register our high level driver with 1394 stack */ diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index e2d357a..2f53b16 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h @@ -227,11 +227,6 @@ struct sbp2_status_block { #define SBP2_SW_VERSION_ENTRY 0x00010483 /* - * Other misc defines - */ -#define SBP2_128KB_BROKEN_FIRMWARE 0xa0b800 - -/* * SCSI specific stuff */ @@ -239,6 +234,13 @@ struct sbp2_status_block { #define SBP2_MAX_SECTORS 255 /* Max sectors supported */ #define SBP2_MAX_CMDS 8 /* This should be safe */ +/* Flags for detected oddities and brokeness */ +#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_OVERRIDE 0x100 + /* This is the two dma types we use for cmd_dma below */ enum cmd_dma_types { CMD_DMA_NONE, @@ -268,10 +270,6 @@ struct sbp2_command_info { }; -/* A list of flags for detected oddities and brokeness. */ -#define SBP2_BREAKAGE_128K_MAX_TRANSFER 0x1 -#define SBP2_BREAKAGE_INQUIRY_HACK 0x2 - struct sbp2scsi_host_info; /* @@ -345,7 +343,7 @@ struct scsi_id_instance_data { struct Scsi_Host *scsi_host; /* Device specific workarounds/brokeness */ - u32 workarounds; + unsigned workarounds; }; /* Sbp2 host data structure (one per IEEE1394 host) */ @@ -397,9 +395,8 @@ static int sbp2_link_orb_command(struct static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)); -static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data); -static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, - struct scsi_cmnd *SCpnt); +static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, + unchar *sense_data); static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id, struct unit_directory *ud); static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id);