⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbp2.c

📁 这是关于ieee1394的最新源码,上面包含了所有更新的部分!
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * sbp2.c - SBP-2 protocol driver for IEEE-1394 * * Copyright (C) 2000 James Goodwin, Filanet Corporation (www.filanet.com) * jamesg@filanet.com (JSG) * * Copyright (C) 2003 Ben Collins <bcollins@debian.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *//* * Brief Description: * * This driver implements the Serial Bus Protocol 2 (SBP-2) over IEEE-1394 * under Linux. The SBP-2 driver is implemented as an IEEE-1394 high-level * driver. It also registers as a SCSI lower-level driver in order to accept * SCSI commands for transport using SBP-2. * * You may access any attached SBP-2 storage devices as if they were SCSI * devices (e.g. mount /dev/sda1,  fdisk, mkfs, etc.). * * Current Issues: * *	- Error Handling: SCSI aborts and bus reset requests are handled somewhat *	  but the code needs additional debugging. */#include <linux/blkdev.h>#include <linux/compiler.h>#include <linux/delay.h>#include <linux/device.h>#include <linux/dma-mapping.h>#include <linux/gfp.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/list.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/pci.h>#include <linux/slab.h>#include <linux/spinlock.h>#include <linux/stat.h>#include <linux/string.h>#include <linux/stringify.h>#include <linux/types.h>#include <linux/wait.h>#include <asm/byteorder.h>#include <asm/errno.h>#include <asm/param.h>#include <asm/scatterlist.h>#include <asm/system.h>#include <asm/types.h>#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA#include <asm/io.h> /* for bus_to_virt */#endif#include <scsi/scsi.h>#include <scsi/scsi_cmnd.h>#include <scsi/scsi_dbg.h>#include <scsi/scsi_device.h>#include <scsi/scsi_host.h>#include "csr1212.h"#include "highlevel.h"#include "hosts.h"#include "ieee1394.h"#include "ieee1394_core.h"#include "ieee1394_hotplug.h"#include "ieee1394_transactions.h"#include "ieee1394_types.h"#include "nodemgr.h"#include "sbp2.h"/* * Module load parameter definitions *//* * Change max_speed on module load if you have a bad IEEE-1394 * controller that has trouble running 2KB packets at 400mb. * * NOTE: On certain OHCI parts I have seen short packets on async transmit * (probably due to PCI latency/throughput issues with the part). You can * bump down the speed if you are running into problems. */static int max_speed = IEEE1394_SPEED_MAX;module_param(max_speed, int, 0644);MODULE_PARM_DESC(max_speed, "Force max speed (3 = 800mb, 2 = 400mb, 1 = 200mb, 0 = 100mb)");/* * Set serialize_io to 1 if you'd like only one scsi command sent * down to us at a time (debugging). This might be necessary for very * badly behaved sbp2 devices. * * TODO: Make this configurable per device. */static int serialize_io = 1;module_param(serialize_io, int, 0444);MODULE_PARM_DESC(serialize_io, "Serialize I/O coming from scsi drivers (default = 1, faster = 0)");/* * Bump up max_sectors if you'd like to support very large sized * transfers. Please note that some older sbp2 bridge chips are broken for * transfers greater or equal to 128KB.  Default is a value of 255 * sectors, or just under 128KB (at 512 byte sector size). I can note that * the Oxsemi sbp2 chipsets have no problems supporting very large * transfer sizes. */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 = "		 __stringify(SBP2_MAX_SECTORS) ")");/* * Exclusive login to sbp2 device? In most cases, the sbp2 driver should * do an exclusive login, as it's generally unsafe to have two hosts * 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, 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)");/* * 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. * * - 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)");/* * Export information about protocols/devices supported by this driver. */static struct ieee1394_device_id sbp2_id_table[] = {	{	 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,	 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,	 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},	{}};MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);/* * Debug levels, configured via kernel config, or enable here. */#define CONFIG_IEEE1394_SBP2_DEBUG 0/* #define CONFIG_IEEE1394_SBP2_DEBUG_ORBS *//* #define CONFIG_IEEE1394_SBP2_DEBUG_DMA *//* #define CONFIG_IEEE1394_SBP2_DEBUG 1 *//* #define CONFIG_IEEE1394_SBP2_DEBUG 2 *//* #define CONFIG_IEEE1394_SBP2_PACKET_DUMP */#ifdef CONFIG_IEEE1394_SBP2_DEBUG_ORBS#define SBP2_ORB_DEBUG(fmt, args...)	HPSB_ERR("sbp2(%s): "fmt, __FUNCTION__, ## args)static u32 global_outstanding_command_orbs = 0;#define outstanding_orb_incr global_outstanding_command_orbs++#define outstanding_orb_decr global_outstanding_command_orbs--#else#define SBP2_ORB_DEBUG(fmt, args...)	do {} while (0)#define outstanding_orb_incr		do {} while (0)#define outstanding_orb_decr		do {} while (0)#endif#ifdef CONFIG_IEEE1394_SBP2_DEBUG_DMA#define SBP2_DMA_ALLOC(fmt, args...) \	HPSB_ERR("sbp2(%s)alloc(%d): "fmt, __FUNCTION__, \		 ++global_outstanding_dmas, ## args)#define SBP2_DMA_FREE(fmt, args...) \	HPSB_ERR("sbp2(%s)free(%d): "fmt, __FUNCTION__, \		 --global_outstanding_dmas, ## args)static u32 global_outstanding_dmas = 0;#else#define SBP2_DMA_ALLOC(fmt, args...)	do {} while (0)#define SBP2_DMA_FREE(fmt, args...)	do {} while (0)#endif#if CONFIG_IEEE1394_SBP2_DEBUG >= 2#define SBP2_DEBUG(fmt, args...)	HPSB_ERR("sbp2: "fmt, ## args)#define SBP2_INFO(fmt, args...)		HPSB_ERR("sbp2: "fmt, ## args)#define SBP2_NOTICE(fmt, args...)	HPSB_ERR("sbp2: "fmt, ## args)#define SBP2_WARN(fmt, args...)		HPSB_ERR("sbp2: "fmt, ## args)#elif CONFIG_IEEE1394_SBP2_DEBUG == 1#define SBP2_DEBUG(fmt, args...)	HPSB_DEBUG("sbp2: "fmt, ## args)#define SBP2_INFO(fmt, args...)		HPSB_INFO("sbp2: "fmt, ## args)#define SBP2_NOTICE(fmt, args...)	HPSB_NOTICE("sbp2: "fmt, ## args)#define SBP2_WARN(fmt, args...)		HPSB_WARN("sbp2: "fmt, ## args)#else#define SBP2_DEBUG(fmt, args...)	do {} while (0)#define SBP2_INFO(fmt, args...)		HPSB_INFO("sbp2: "fmt, ## args)#define SBP2_NOTICE(fmt, args...)       HPSB_NOTICE("sbp2: "fmt, ## args)#define SBP2_WARN(fmt, args...)         HPSB_WARN("sbp2: "fmt, ## args)#endif#define SBP2_ERR(fmt, args...)		HPSB_ERR("sbp2: "fmt, ## args)#define SBP2_DEBUG_ENTER()		SBP2_DEBUG("%s", __FUNCTION__)/* * Globals */static void sbp2scsi_complete_all_commands(struct scsi_id_instance_data *scsi_id,					   u32 status);static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,				      u32 scsi_status, struct scsi_cmnd *SCpnt,				      void (*done)(struct scsi_cmnd *));static struct scsi_host_template scsi_driver_template;static const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC };static void sbp2_host_reset(struct hpsb_host *host);static int sbp2_probe(struct device *dev);static int sbp2_remove(struct device *dev);static int sbp2_update(struct unit_directory *ud);static struct hpsb_highlevel sbp2_highlevel = {	.name =		SBP2_DEVICE_NAME,	.host_reset =	sbp2_host_reset,};static struct hpsb_address_ops sbp2_ops = {	.write = sbp2_handle_status_write};#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMAstatic struct hpsb_address_ops sbp2_physdma_ops = {	.read = sbp2_handle_physdma_read,	.write = sbp2_handle_physdma_write,};#endifstatic struct hpsb_protocol_driver sbp2_driver = {	.name		= "SBP2 Driver",	.id_table	= sbp2_id_table,	.update		= sbp2_update,	.driver		= {		.name		= SBP2_DEVICE_NAME,		.bus		= &ieee1394_bus_type,		.probe		= sbp2_probe,		.remove		= sbp2_remove,	},};/* * 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,	}};/************************************** * General utility functions **************************************/#ifndef __BIG_ENDIAN/* * Converts a buffer from be32 to cpu byte ordering. Length is in bytes. */static inline void sbp2util_be32_to_cpu_buffer(void *buffer, int length){	u32 *temp = buffer;	for (length = (length >> 2); length--; )		temp[length] = be32_to_cpu(temp[length]);	return;}/* * Converts a buffer from cpu to be32 byte ordering. Length is in bytes. */static inline void sbp2util_cpu_to_be32_buffer(void *buffer, int length){	u32 *temp = buffer;	for (length = (length >> 2); length--; )		temp[length] = cpu_to_be32(temp[length]);	return;}#else /* BIG_ENDIAN *//* Why waste the cpu cycles? */#define sbp2util_be32_to_cpu_buffer(x,y) do {} while (0)#define sbp2util_cpu_to_be32_buffer(x,y) do {} while (0)#endif#ifdef CONFIG_IEEE1394_SBP2_PACKET_DUMP/* * Debug packet dump routine. Length is in bytes. */static void sbp2util_packet_dump(void *buffer, int length, char *dump_name,				 u32 dump_phys_addr){	int i;	unsigned char *dump = buffer;	if (!dump || !length || !dump_name)		return;	if (dump_phys_addr)		printk("[%s, 0x%x]", dump_name, dump_phys_addr);	else		printk("[%s]", dump_name);	for (i = 0; i < length; i++) {		if (i > 0x3f) {			printk("\n   ...");			break;		}		if ((i & 0x3) == 0)			printk("  ");		if ((i & 0xf) == 0)			printk("\n   ");		printk("%02x ", (int)dump[i]);	}	printk("\n");	return;}#else#define sbp2util_packet_dump(w,x,y,z) do {} while (0)#endifstatic DECLARE_WAIT_QUEUE_HEAD(access_wq);/* * Waits for completion of an SBP-2 access request.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -