patch-2.4.9 linux/drivers/ieee1394/sbp2.c
Next file: linux/drivers/ieee1394/sbp2.h
Previous file: linux/drivers/ieee1394/raw1394.c
Back to the patch index
Back to the overall index
- Lines: 429
- Date:
Thu Aug 16 09:49:49 2001
- Orig file:
v2.4.8/linux/drivers/ieee1394/sbp2.c
- Orig date:
Wed Jul 25 17:10:20 2001
diff -u --recursive --new-file v2.4.8/linux/drivers/ieee1394/sbp2.c linux/drivers/ieee1394/sbp2.c
@@ -76,29 +76,6 @@
* fdisk, mkfs, etc.).
*
*
- * Module Load Options:
- *
- * The SBP-2 driver now has a number of module load parameters available for use
- * in debugging/testing. Following are the valid parameters
- *
- * no_bus_scan - Skip the initial scsi bus scan during module load
- * (1 = skip bus scan, 0 = perform bus scan, default = 0)
- *
- * mode_sense_hack - Emulate mode sense for devices like 1394 memory stick readers
- * (1 = emulate/fake mode sense, 0 = do not emulate/fake mode sense, default = 0)
- *
- * max_speed - Force max speed allowed
- * (0 = 100mb, 1 = 200mb, 2 = 400mb, default = auto configure)
- *
- * serialize_io - Force scsi stack to send down one command at a time, for debugging
- * (1 = serialize all I/O, 0 = do not serialize I/O, default = 1)
- *
- * no_large_packets - Force scsi stack to limit max packet size sent down, for debugging
- * (1 = limit max transfer size, 0 = do not limit max packet size, default = 0)
- *
- * (e.g. insmod sbp2 no_bus_scan=1)
- *
- *
* Current Support:
*
* The SBP-2 driver is still in an early state, but supports a variety of devices.
@@ -166,20 +143,6 @@
* define below).
*
*
- * Core IEEE-1394 Stack Changes:
- *
- * - The IEEE-1394 core stack guid code attempts to read the node unique id from
- * each attached device after a bus reset. It currently uses a block read
- * request to do this, which "upsets" certain not-well-behaved devices, such as
- * some drives from QPS. If you have trouble with your IEEE-1394 storage
- * device being detected after loading sbp2, try commenting out the
- * init_ieee1394_guid() and cleanup_ieee1394_guid() lines at the bottom of
- * ieee1394_core.c (and rebuild ieee1394.o).
- *
- * - In ohci1394.h, remove the IEEE1394_USE_BOTTOM_HALVES #define, and rebuild.
- * This will give you around 30% to 40% performance increase.
- *
- *
* History:
*
* 07/25/00 - Initial revision (JSG)
@@ -257,6 +220,8 @@
* 128KB max transfer limit.
* 06/16/01 - Converted DMA interfaces to pci_dma - Ben Collins
* <bcollins@debian.org
+ * 07/22/01 - Use NodeMngr to get info about the local host and
+ * attached devices. Ben Collins
*/
/*
@@ -289,8 +254,10 @@
#include "ieee1394_types.h"
#include "ieee1394_core.h"
#include "hosts.h"
+#include "nodemgr.h"
#include "highlevel.h"
#include "ieee1394_transactions.h"
+#include "ieee1394_hotplug.h"
#include "../scsi/scsi.h"
#include "../scsi/hosts.h"
#include "../scsi/sd.h"
@@ -349,7 +316,7 @@
*/
MODULE_PARM(max_speed,"i");
MODULE_PARM_DESC(max_speed, "Force down max speed (2 = 400mb default, 1 = 200mb, 0 = 100mb)");
-static int max_speed = SPEED_S400;
+static int max_speed = SPEED_400;
/*
* Set serialize_io to 1 if you'd like only one scsi command sent down to us at a time (debugging).
@@ -366,14 +333,24 @@
MODULE_PARM(no_large_packets,"i");
MODULE_PARM_DESC(no_large_packets, "Do not allow large transfers from scsi drivers (debugging)");
static int no_large_packets = 0;
-
+
+/*
+ * Export information about protocols/devices supported by this driver
+ */
+static struct ieee1394_device_id sbp2_id_table[] = {
+ IEEE1394_PROTOCOL(SBP2_UNIT_SPEC_ID_ENTRY, SBP2_SW_VERSION_ENTRY),
+ { }
+};
+
+MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
+
/*
* Debug levels, configured via kernel config.
*/
#ifdef CONFIG_IEEE1394_SBP2_DEBUG_ORBS
#define SBP2_ORB_DEBUG(fmt, args...) HPSB_ERR("sbp2("__FUNCTION__"): "fmt, ## args)
-u32 global_outstanding_command_orbs = 0;
+static u32 global_outstanding_command_orbs = 0;
#define outstanding_orb_incr global_outstanding_command_orbs++
#define outstanding_orb_decr global_outstanding_command_orbs--
#else
@@ -389,7 +366,7 @@
#define SBP2_DMA_FREE(fmt, args...) \
HPSB_ERR("sbp2("__FUNCTION__")free(%d): "fmt, \
--global_outstanding_dmas, ## args)
-u32 global_outstanding_dmas = 0;
+static u32 global_outstanding_dmas = 0;
#else
#define SBP2_DMA_ALLOC(fmt, args...)
#define SBP2_DMA_FREE(fmt, args...)
@@ -432,9 +409,9 @@
Scsi_Host_Template *global_scsi_tpnt = NULL;
-LIST_HEAD(sbp2_host_info_list);
+static LIST_HEAD(sbp2_host_info_list);
static int sbp2_host_count = 0;
-spinlock_t sbp2_host_info_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t sbp2_host_info_lock = SPIN_LOCK_UNLOCKED;
static struct hpsb_highlevel *sbp2_hl_handle = NULL;
@@ -681,7 +658,7 @@
INIT_LIST_HEAD(&packet->list);
sema_init(&packet->state_change, 0);
packet->state = unused;
- packet->generation = get_hpsb_generation();
+ packet->generation = get_hpsb_generation(hi->host);
packet->data_be = 1;
packet->host = hi->host;
@@ -988,7 +965,7 @@
static void sbp2_add_host(struct hpsb_host *host)
{
struct sbp2scsi_host_info *hi;
- unsigned int flags;
+ unsigned long flags;
SBP2_DEBUG("sbp2: sbp2_add_host");
@@ -1021,7 +998,7 @@
sbp2_spin_lock(&sbp2_host_info_lock, flags);
list_add_tail(&hi->list, &sbp2_host_info_list);
sbp2_host_count++;
- sbp2_spin_lock(&sbp2_host_info_lock, flags);
+ sbp2_spin_unlock(&sbp2_host_info_lock, flags);
/*
* Initialize us to bus reset in progress
@@ -1046,19 +1023,19 @@
}
/*
- * This fuction returns a host info structure from the host structure, in case we have multiple hosts
+ * This fuction returns a host info structure from the host structure,
+ * in case we have multiple hosts
*/
-static struct sbp2scsi_host_info *sbp2_find_host_info(struct hpsb_host *host) {
+static struct sbp2scsi_host_info *sbp2_find_host_info(struct hpsb_host *host)
+{
struct list_head *lh;
struct sbp2scsi_host_info *hi;
- lh = sbp2_host_info_list.next;
- while (lh != &sbp2_host_info_list) {
+ list_for_each (lh, &sbp2_host_info_list) {
hi = list_entry(lh, struct sbp2scsi_host_info, list);
if (hi->host == host) {
return hi;
}
- lh = lh->next;
}
return(NULL);
@@ -1071,7 +1048,7 @@
{
struct sbp2scsi_host_info *hi;
int i;
- unsigned int flags;
+ unsigned long flags;
SBP2_DEBUG("sbp2: sbp2_remove_host");
@@ -1142,12 +1119,14 @@
* This thread doesn't need any user-level access,
* so get rid of all our resources
*/
+#if LINUX_VERSION_CODE > 0x20300
daemonize();
+#endif
/*
* Set-up a nice name
*/
- strcpy(current->comm, "sbp2");
+ strcpy(current->comm, SBP2_DEVICE_NAME);
unlock_kernel();
@@ -1179,35 +1158,22 @@
*/
static int sbp2_start_device(struct sbp2scsi_host_info *hi, int node_id)
{
- quadlet_t node_unique_id_lo, node_unique_id_hi;
u64 node_unique_id;
struct scsi_id_instance_data *scsi_id = NULL;
+ struct node_entry *ne;
int i;
SBP2_DEBUG("sbp2: sbp2_start_device");
- /*
- * Let's read the node unique id off of the device (using two quadlet reads for hi and lo)
- */
- if (sbp2util_read_quadlet(hi, LOCAL_BUS | node_id, CONFIG_ROM_NODE_UNIQUE_ID_HI_ADDRESS,
- &node_unique_id_hi)) {
- SBP2_DEBUG("sbp2: Error reading node unique id - bad status");
- return(-EIO);
- }
-
- if (sbp2util_read_quadlet(hi, LOCAL_BUS | node_id, CONFIG_ROM_NODE_UNIQUE_ID_LO_ADDRESS,
- &node_unique_id_lo)) {
- SBP2_DEBUG("sbp2: Error reading node unique id - bad status");
- return(-EIO);
+ /* XXX: This will go away once we start using the nodemgr's
+ * feature subscription API. */
+ ne = hpsb_nodeid_get_entry(node_id|(hi->host->node_id & BUS_MASK));
+ if (!ne) {
+ HPSB_ERR("sbp2: Could not find device node");
+ return -ENXIO;
}
- /*
- * Spit out the node unique ids we got
- */
- SBP2_DEBUG("sbp2: Node %x, node unique id hi = %x", (LOCAL_BUS | node_id), (unsigned int) node_unique_id_hi);
- SBP2_DEBUG("sbp2: Node %x, node unique id lo = %x", (LOCAL_BUS | node_id), (unsigned int) node_unique_id_lo);
-
- node_unique_id = (((u64)node_unique_id_hi) << 32) | ((u64)node_unique_id_lo);
+ node_unique_id = ne->guid;
/*
* First, we need to find out whether this is a "new" SBP-2 device plugged in, or one that already
@@ -1355,7 +1321,7 @@
scsi_id->node_id = node_id;
scsi_id->node_unique_id = node_unique_id;
scsi_id->validated = 1;
- scsi_id->speed_code = SPEED_S100;
+ scsi_id->speed_code = SPEED_100;
scsi_id->max_payload_size = MAX_PAYLOAD_S100;
init_waitqueue_head(&scsi_id->sbp2_login_wait);
@@ -1458,7 +1424,7 @@
}
/*
- * This function trys to determine if a device is a valid SBP-2 device
+ * This function tries to determine if a device is a valid SBP-2 device
*/
static int sbp2_check_device(struct sbp2scsi_host_info *hi, int node_id)
{
@@ -2249,65 +2215,43 @@
*/
static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id)
{
- quadlet_t node_options, max_rec;
u8 speed_code;
+ struct node_entry *ne;
SBP2_DEBUG("sbp2: sbp2_max_speed_and_size");
- /*
- * Get speed code from internal host structure. There should be a better way to obtain this.
- */
- speed_code = hi->host->speed_map[(hi->host->node_id & NODE_MASK) * 64 + (scsi_id->node_id & NODE_MASK)];
+ /* Get this nodes information */
+ ne = hpsb_nodeid_get_entry(hi->host->node_id);
- /*
- * Bump down our speed if there is a module parameter forcing us slower
- */
+ if (!ne) {
+ HPSB_ERR("sbp2: Unknown device, using S100, payload 512 bytes");
+ scsi_id->speed_code = SPEED_100;
+ scsi_id->max_payload_size = MAX_PAYLOAD_S100;
+ return(0);
+ }
+
+ speed_code = ne->busopt.lnkspd;
+
+ /* Bump down our speed if there is a module parameter forcing us slower */
if (speed_code > max_speed) {
speed_code = max_speed;
SBP2_ERR("sbp2: Reducing SBP-2 max speed allowed (%x)", max_speed);
}
- switch (speed_code) {
- case SPEED_S100:
- scsi_id->speed_code = SPEED_S100;
- scsi_id->max_payload_size = MAX_PAYLOAD_S100;
- SBP2_INFO("sbp2: SBP-2 device max speed S100 and payload 512 bytes");
- break;
- case SPEED_S200:
- scsi_id->speed_code = SPEED_S200;
- scsi_id->max_payload_size = MAX_PAYLOAD_S200;
- SBP2_INFO("sbp2: SBP-2 device max speed S200 and payload 1KB");
- break;
- case SPEED_S400:
- scsi_id->speed_code = SPEED_S400;
- scsi_id->max_payload_size = MAX_PAYLOAD_S400;
- SBP2_INFO("sbp2: SBP-2 device max speed S400 and payload 2KB");
- break;
- default:
- scsi_id->speed_code = SPEED_S100;
- scsi_id->max_payload_size = MAX_PAYLOAD_S100;
- SBP2_ERR("sbp2: Undefined speed: Using SBP-2 device max speed S100 and payload 512 bytes");
- break;
- }
-
- /*
- * Finally, check the adapter's capabilities to further bump down our max payload size
- * if necessary. For instance, TILynx may not support the default max payload at a
- * particular speed.
- */
- if (!hpsb_read(hi->host, hi->host->node_id | LOCAL_BUS, CONFIG_ROM_NODE_OPTIONS, &node_options, 4)) {
-
- /*
- * Grab max_rec (max payload = 2 ^ (max_rec+1)) from node options. Sbp2 max payload is
- * defined as 2 ^ (max_pay+2)... so, have to subtract one from max rec for comparison...
- * confusing, eh? ;-)
- */
- max_rec = (be32_to_cpu(node_options) & 0x0000f000) >> 12;
- if (scsi_id->max_payload_size > (max_rec - 1)) {
- scsi_id->max_payload_size = (max_rec - 1);
- SBP2_ERR("sbp2: Reducing SBP-2 max payload allowed (%x)", (max_rec - 1));
- }
-
+ /* Support the devices max_rec and max speed. We choose a setting
+ * that fits both values, since they may differ. */
+ if (speed_code >= SPEED_400 && ne->busopt.max_rec >= MAX_REC_S400) {
+ HPSB_INFO("sbp2: SBP-2 device max speed S400 and payload 2KB");
+ scsi_id->speed_code = SPEED_400;
+ scsi_id->max_payload_size = MAX_PAYLOAD_S400;
+ } else if (speed_code >= SPEED_200 && ne->busopt.max_rec >= MAX_REC_S200) {
+ HPSB_INFO("sbp2: SBP-2 device max speed S200 and payload 1KB");
+ scsi_id->speed_code = SPEED_200;
+ scsi_id->max_payload_size = MAX_PAYLOAD_S200;
+ } else {
+ HPSB_INFO("sbp2: SBP-2 device max speed S100 and payload 512 bytes");
+ scsi_id->speed_code = SPEED_100;
+ scsi_id->max_payload_size = MAX_PAYLOAD_S100;
}
return(0);
@@ -3480,9 +3424,9 @@
SBP2_DEBUG("sbp2: sbp2scsi_detect");
global_scsi_tpnt = tpnt;
-
- global_scsi_tpnt->proc_name = "sbp2";
-
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,26)
+ global_scsi_tpnt->proc_name = SBP2_DEVICE_NAME;
+#endif
/*
* Module load option for force one command at a time
*/
@@ -3554,9 +3498,7 @@
return;
}
-/*
- * Called when our module is released
- */
+/* Called when our module is released */
static int sbp2scsi_release(struct Scsi_Host *host)
{
SBP2_DEBUG("sbp2: sbp2scsi_release");
@@ -3564,25 +3506,32 @@
return(0);
}
-/*
- * Called for contents of procfs
- */
+/* Called for contents of procfs */
static const char *sbp2scsi_info (struct Scsi_Host *host)
{
return "IEEE-1394 SBP-2 protocol driver";
}
-/*
- * Module related section
- */
-
MODULE_AUTHOR("James Goodwin <jamesg@filanet.com>");
MODULE_DESCRIPTION("IEEE-1394 SBP-2 protocol driver");
-MODULE_SUPPORTED_DEVICE("sbp2");
+MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
-/*
- * SCSI host template
- */
-static Scsi_Host_Template driver_template = SBP2SCSI;
+/* SCSI host template */
+static Scsi_Host_Template driver_template = {
+ name: "IEEE1394 SBP-2",
+ detect: sbp2scsi_detect,
+ release: sbp2scsi_release,
+ info: sbp2scsi_info,
+ queuecommand: sbp2scsi_queuecommand,
+ abort: sbp2scsi_abort,
+ reset: sbp2scsi_reset,
+ bios_param: sbp2scsi_biosparam,
+ can_queue: SBP2SCSI_MAX_OUTSTANDING_CMDS,
+ this_id: -1,
+ sg_tablesize: SBP2_MAX_SG_ELEMENTS,
+ cmd_per_lun: SBP2SCSI_MAX_CMDS_PER_LUN,
+ use_clustering: SBP2_CLUSTERING,
+ emulated: 1
+};
#include "../scsi/scsi_module.c"
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)