📄 sbp2.c.htm.bak
字号:
<html><head><title>ieee1394.rar sbp2.c</title>
<LINK href="/inc/read_style.css" type=text/css rel=stylesheet></head>
<body>
<p><a href=http://www.pudn.com>www.pudn.com</a> > <a href="http://www.pudn.com/downloads94/sourcecode/embed/detail371529.html">ieee1394.rar</a> > sbp2.c</p><!-- saved from http://www.pudn.com -->
<script src="/inc/gg_read1.js"></script><BR>
<pre name="code" class="c">
/*
* 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_DMA
static struct hpsb_address_ops sbp2_physdma_ops = {
.read = sbp2_handle_physdma_read,
.write = sbp2_handle_physdma_write,
};
#endif
static 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -