[Linux1394-cvslog] rev 847 - branches/linux-2.4
Brought to you by:
aeb,
bencollins
From: SVN U. <dde...@li...> - 2003-03-20 19:44:49
|
Author: ddennedy Date: 2003-03-20 14:43:48 -0500 (Thu, 20 Mar 2003) New Revision: 847 Modified: branches/linux-2.4/nodemgr.c branches/linux-2.4/nodemgr.h branches/linux-2.4/sbp2.c Log: sbp2 multi-logical-unit support and better software_version checking on hotplug Modified: branches/linux-2.4/nodemgr.c ============================================================================== --- branches/linux-2.4/nodemgr.c (original) +++ branches/linux-2.4/nodemgr.c 2003-03-20 14:43:49.000000000 -0500 @@ -92,7 +92,7 @@ list_for_each(lh, &node_list) { struct list_head *l; - int ud_count = 0; + int ud_count = 0, lud_count = 0; ne = list_entry(lh, struct node_entry, list); if (!ne) @@ -135,7 +135,10 @@ struct unit_directory *ud = list_entry (l, struct unit_directory, node_list); int printed = 0; // small hack - PUTF(" Unit Directory %d:\n", ud_count++); + if (ud->parent == NULL) + PUTF(" Unit Directory %d:\n", lud_count++); + else + PUTF(" Logical Unit Directory %d:\n", ud_count++); if (ud->flags & UNIT_DIRECTORY_VENDOR_ID) { PUTF(" Vendor/Model ID: %s [%06x]", ud->vendor_name ?: "Unknown", ud->vendor_id); @@ -433,7 +436,7 @@ store? Only count immediate values and CSR offsets for now. */ code &= CONFIG_ROM_KEY_TYPE_MASK; - if ((code & 0x80) == 0) + if ((code & CONFIG_ROM_KEY_TYPE_LEAF) == 0) count++; break; } @@ -481,19 +484,23 @@ * software_version entries, in order to get driver autoloading working. */ -static void nodemgr_process_unit_directory(struct node_entry *ne, - octlet_t address) +static struct unit_directory * nodemgr_process_unit_directory + (struct node_entry *ne, octlet_t address, struct unit_directory *parent) { struct unit_directory *ud; quadlet_t quad; quadlet_t *infop; int length; - + struct unit_directory *ud_temp = NULL; + if (!(ud = nodemgr_scan_unit_directory(ne, address))) goto unit_directory_error; ud->ne = ne; ud->address = address; + + if (parent != NULL) + ud->parent = parent; if (nodemgr_read_quadlet(ne->host, ne->nodeid, ne->generation, address, &quad)) @@ -569,12 +576,48 @@ /* TODO: read strings... icons? */ break; + case CONFIG_ROM_LOGICAL_UNIT_DIRECTORY: + { + ud_temp = nodemgr_process_unit_directory(ne, address + value * 4, ud); + /* inherit unspecified values */ + if (ud_temp != NULL ) + { + ud->n_children++; + if ((ud->flags & UNIT_DIRECTORY_VENDOR_ID) && + !(ud_temp->flags & UNIT_DIRECTORY_VENDOR_ID)) + { + ud_temp->flags |= UNIT_DIRECTORY_VENDOR_ID; + ud_temp->vendor_id = ud->vendor_id; + } + if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) && + !(ud_temp->flags & UNIT_DIRECTORY_MODEL_ID)) + { + ud_temp->flags |= UNIT_DIRECTORY_MODEL_ID; + ud_temp->model_id = ud->model_id; + } + if ((ud->flags & UNIT_DIRECTORY_SPECIFIER_ID) && + !(ud_temp->flags & UNIT_DIRECTORY_SPECIFIER_ID)) + { + ud_temp->flags |= UNIT_DIRECTORY_SPECIFIER_ID; + ud_temp->specifier_id = ud->specifier_id; + } + if ((ud->flags & UNIT_DIRECTORY_VERSION) && + !(ud_temp->flags & UNIT_DIRECTORY_VERSION)) + { + ud_temp->flags |= UNIT_DIRECTORY_VERSION; + ud_temp->version = ud->version; + } + } + + } + break; + default: /* Which types of quadlets do we want to store? Only count immediate values and CSR offsets for now. */ code &= CONFIG_ROM_KEY_TYPE_MASK; - if ((code & 0x80) == 0) + if ((code & CONFIG_ROM_KEY_TYPE_LEAF) == 0) *infop = quad; break; } @@ -583,11 +626,12 @@ list_add_tail(&ud->node_list, &ne->unit_directories); list_add_tail(&ud->driver_list, &unit_directory_list); - return; + return ud; unit_directory_error: if (ud != NULL) kfree(ud); + return NULL; } static void dump_directories (struct node_entry *ne) @@ -670,7 +714,7 @@ break; case CONFIG_ROM_UNIT_DIRECTORY: - nodemgr_process_unit_directory(ne, address + value * 4); + nodemgr_process_unit_directory(ne, address + value * 4, NULL); break; case CONFIG_ROM_DESCRIPTOR_LEAF: @@ -821,8 +865,9 @@ id->specifier_id != ud->specifier_id) continue; + /* software version does a bitwise comparison instead of equality */ if ((id->match_flags & IEEE1394_MATCH_VERSION) && - id->version != ud->version) + !(id->version & ud->version)) continue; return id; Modified: branches/linux-2.4/nodemgr.h ============================================================================== --- branches/linux-2.4/nodemgr.h (original) +++ branches/linux-2.4/nodemgr.h 2003-03-20 14:43:49.000000000 -0500 @@ -53,6 +53,7 @@ #define CONFIG_ROM_MODEL_ID 0x17 #define CONFIG_ROM_NODE_CAPABILITES 0x0C #define CONFIG_ROM_UNIT_DIRECTORY 0xd1 +#define CONFIG_ROM_LOGICAL_UNIT_DIRECTORY 0xd4 #define CONFIG_ROM_SPECIFIER_ID 0x12 #define CONFIG_ROM_UNIT_SW_VERSION 0x13 #define CONFIG_ROM_DESCRIPTOR_LEAF 0x81 @@ -114,6 +115,10 @@ /* For linking directories belonging to a node */ struct list_head node_list; + + /* for tracking unit versus logical unit */ + struct unit_directory *parent; + int n_children; int count; /* Number of quadlets */ quadlet_t quadlets[0]; Modified: branches/linux-2.4/sbp2.c ============================================================================== --- branches/linux-2.4/sbp2.c (original) +++ branches/linux-2.4/sbp2.c 2003-03-20 14:43:49.000000000 -0500 @@ -1840,28 +1840,11 @@ return(0); } -/* - * This function is called to parse sbp2 device's config rom unit - * directory. Used to determine things like sbp2 management agent offset, - * and command set used (SCSI or RBC). - */ -static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id) +static void sbp2_parse_logical_unit_directory + (struct scsi_id_instance_data *scsi_id, struct unit_directory *ud) { - struct unit_directory *ud; int i; - - SBP2_DEBUG("sbp2_parse_unit_directory"); - - /* Initialize some fields, in case an entry does not exist */ - scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED; - scsi_id->sbp2_management_agent_addr = 0x0; - scsi_id->sbp2_command_set_spec_id = 0x0; - scsi_id->sbp2_command_set = 0x0; - scsi_id->sbp2_unit_characteristics = 0x0; - scsi_id->sbp2_firmware_revision = 0x0; - - ud = scsi_id->ud; - + /* Handle different fields in the unit directory, based on keys */ for (i = 0; i < ud->count; i++) { switch (CONFIG_ROM_KEY(ud->quadlets[i])) { @@ -1923,11 +1906,44 @@ else SBP2_DEBUG("sbp2_firmware_revision = %x", (unsigned int) scsi_id->sbp2_firmware_revision); break; - +#if 0 + case SBP2_LOGICAL_UNIT_DIRECTORY_OFFSET_KEY: + SBP2_DEBUG("sbp2_parse_unit_directory: found logical unit directory"); + break; +#endif default: break; } } +} + +/* + * This function is called to parse sbp2 device's config rom unit + * directory. Used to determine things like sbp2 management agent offset, + * and command set used (SCSI or RBC). + */ +static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id) +{ + struct unit_directory *ud; + int i; + + SBP2_DEBUG("sbp2_parse_unit_directory"); + + /* Initialize some fields, in case an entry does not exist */ + scsi_id->sbp2_device_type_and_lun = SBP2_DEVICE_TYPE_LUN_UNINITIALIZED; + scsi_id->sbp2_management_agent_addr = 0x0; + scsi_id->sbp2_command_set_spec_id = 0x0; + scsi_id->sbp2_command_set = 0x0; + scsi_id->sbp2_unit_characteristics = 0x0; + scsi_id->sbp2_firmware_revision = 0x0; + + ud = scsi_id->ud; + if (ud->parent != NULL) + sbp2_parse_logical_unit_directory(scsi_id, ud->parent); + if (ud->n_children == 0) + sbp2_parse_logical_unit_directory(scsi_id, ud); + else + return; /* This is the start of our broken device checking. We try to hack * around oddities and known defects. */ |