1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-31 16:57:10 +00:00

- Improve configuration ROM parser for multiple unit directory.

- Remove getcsrdata().
- Don't print device type, this can be obtained by fwcontrol.

Tested with: Maxtor 5000XT
Tested by: Daniel O'Connor <doconnor@gsoft.com.au>
This commit is contained in:
Hidetoshi Shimokawa 2003-04-26 16:45:40 +00:00
parent f0aa77427a
commit 5e286c3211
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=114069
5 changed files with 138 additions and 148 deletions

View File

@ -1497,25 +1497,6 @@ fw_bus_explore_callback(struct fw_xfer *xfer)
return;
}
/*
* To obtain CSR register values.
*/
u_int32_t
getcsrdata(struct fw_device *fwdev, u_int8_t key)
{
int i;
struct csrhdr *chdr;
struct csrreg *creg;
chdr = (struct csrhdr *)&fwdev->csrrom[0];
for( i = chdr->info_len + 4; i <= fwdev->rommax - CSRROMOFF; i+=4){
creg = (struct csrreg *)&fwdev->csrrom[i/4];
if(creg->key == key){
return (u_int32_t)creg->val;
}
}
return 0;
}
/*
* To attach sub-devices layer onto IEEE1394 bus.
*/
@ -1528,71 +1509,11 @@ fw_attach_dev(struct firewire_comm *fc)
device_t *devlistp;
int devcnt;
struct firewire_dev_comm *fdc;
u_int32_t spec, ver;
STAILQ_FOREACH(fwdev, &fc->devices, link) {
if(fwdev->status == FWDEVINIT){
spec = getcsrdata(fwdev, CSRKEY_SPEC);
if(spec == 0)
continue;
ver = getcsrdata(fwdev, CSRKEY_VER);
if(ver == 0)
continue;
fwdev->maxrec = (fwdev->csrrom[2] >> 12) & 0xf;
device_printf(fc->bdev, "Device ");
switch(spec){
case CSRVAL_ANSIT10:
switch(ver){
case CSRVAL_T10SBP2:
printf("SBP-II");
break;
default:
break;
}
break;
case CSRVAL_1394TA:
switch(ver){
case CSR_PROTAVC:
printf("AV/C");
break;
case CSR_PROTCAL:
printf("CAL");
break;
case CSR_PROTEHS:
printf("EHS");
break;
case CSR_PROTHAVI:
printf("HAVi");
break;
case CSR_PROTCAM104:
printf("1394 Cam 1.04");
break;
case CSR_PROTCAM120:
printf("1394 Cam 1.20");
break;
case CSR_PROTCAM130:
printf("1394 Cam 1.30");
break;
case CSR_PROTDPP:
printf("1394 Direct print");
break;
case CSR_PROTIICP:
printf("Industrial & Instrument");
break;
default:
printf("unknown 1394TA");
break;
}
break;
default:
printf("unknown spec");
break;
}
STAILQ_FOREACH(fwdev, &fc->devices, link)
if (fwdev->status == FWDEVINIT)
fwdev->status = FWDEVATTACHED;
printf("\n");
}
}
err = device_get_children(fc->bdev, &devlistp, &devcnt);
if( err != 0 )
return;

View File

@ -273,7 +273,6 @@ struct fw_xfer *fw_xfer_alloc_buf __P((struct malloc_type *, int, int));
void fw_init __P((struct firewire_comm *));
int fw_tbuf_update __P((struct firewire_comm *, int, int));
int fw_rbuf_update __P((struct firewire_comm *, int, int));
u_int32_t getcsrdata __P((struct fw_device *, u_int8_t));
void fw_asybusy __P((struct fw_xfer *));
int fw_bindadd __P((struct firewire_comm *, struct fw_bind *));
int fw_bindremove __P((struct firewire_comm *, struct fw_bind *));

View File

@ -63,6 +63,12 @@ crom_init_context(struct crom_context *cc, u_int32_t *p)
cc->depth = -1;
}
p += 1 + hdr->info_len;
/* check size of root directory */
if (((struct csrdirectory *)p)->crc_len == 0) {
cc->depth = -1;
return;
}
cc->depth = 0;
cc->stack[0].dir = (struct csrdirectory *)p;
cc->stack[0].index = 0;
@ -127,6 +133,33 @@ crom_search_key(struct crom_context *cc, u_int8_t key)
return NULL;
}
int
crom_has_specver(u_int32_t *p, u_int32_t spec, u_int32_t ver)
{
struct csrreg *reg;
struct crom_context c, *cc;
int state = 0;
cc = &c;
crom_init_context(cc, p);
while(cc->depth >= 0) {
reg = crom_get(cc);
if (state == 0) {
if (reg->key == CSRKEY_SPEC && reg->val == spec)
state = 1;
else
state = 0;
} else {
if (reg->key == CSRKEY_VER && reg->val == ver)
return 1;
else
state = 0;
}
crom_next(cc);
}
return 0;
}
void
crom_parse_text(struct crom_context *cc, char *buf, int len)
{
@ -136,6 +169,9 @@ crom_parse_text(struct crom_context *cc, char *buf, int len)
int i, qlen;
static char *nullstr = "(null)";
if (cc->depth < 0)
return;
reg = crom_get(cc);
if (reg->key != CROM_TEXTLEAF) {
strncpy(buf, nullstr, len);
@ -176,34 +212,91 @@ crom_crc(u_int32_t *ptr, int len)
}
#ifndef _KERNEL
static void
crom_desc_specver(u_int32_t spec, u_int32_t ver, char *buf, int len)
{
char *s = NULL;
if (spec == CSRVAL_ANSIT10 || spec == 0) {
switch (ver) {
case CSRVAL_T10SBP2:
s = "SBP-2";
break;
default:
if (spec != 0)
s = "unknown ANSIT10";
}
}
if (spec == CSRVAL_1394TA || spec == 0) {
switch (ver) {
case CSR_PROTAVC:
s = "AV/C";
break;
case CSR_PROTCAL:
s = "CAL";
break;
case CSR_PROTEHS:
s = "EHS";
break;
case CSR_PROTHAVI:
s = "HAVi";
break;
case CSR_PROTCAM104:
s = "1394 Cam 1.04";
break;
case CSR_PROTCAM120:
s = "1394 Cam 1.20";
break;
case CSR_PROTCAM130:
s = "1394 Cam 1.30";
break;
case CSR_PROTDPP:
s = "1394 Direct print";
break;
case CSR_PROTIICP:
s = "Industrial & Instrument";
break;
default:
if (spec != 0)
s = "unknown 1394TA";
}
}
if (s != NULL)
snprintf(buf, len, "%s", s);
}
char *
crom_desc(struct crom_context *cc, char *buf, int len)
{
struct csrreg *reg;
struct csrdirectory *dir;
char *desc;
char *desc, st;
u_int16_t crc;
reg = crom_get(cc);
switch (reg->key & CSRTYPE_MASK) {
case CSRTYPE_I:
snprintf(buf, len, "%d", reg->val);
#if 0
len -= snprintf(buf, len, "%d", reg->val);
buf += strlen(buf);
#else
*buf = '\0';
#endif
break;
case CSRTYPE_C:
snprintf(buf, len, "offset=0x%04x(%d)", reg->val, reg->val);
len -= snprintf(buf, len, "offset=0x%04x(%d)",
reg->val, reg->val);
buf += strlen(buf);
break;
case CSRTYPE_L:
/* XXX fall through */
case CSRTYPE_D:
dir = (struct csrdirectory *) (reg + reg->val);
crc = crom_crc((u_int32_t *)&dir->entry[0], dir->crc_len);
len -= snprintf(buf, len, "len=%d crc=0x%04x",
dir->crc_len, dir->crc);
if (crc == dir->crc)
strncat(buf, "(OK) ", len);
else
strncat(buf, "(NG) ", len);
len -= 5;
len -= snprintf(buf, len, "len=%d crc=0x%04x(%s) ",
dir->crc_len, dir->crc,
(crc == dir->crc) ? "OK" : "NG");
buf += strlen(buf);
}
switch (reg->key) {
case 0x03:
@ -220,6 +313,7 @@ crom_desc(struct crom_context *cc, char *buf, int len)
break;
case 0x13:
desc = "unit_sw_version";
crom_desc_specver(0, reg->val, buf, len);
break;
case 0x14:
desc = "logical_unit_number";

View File

@ -170,6 +170,8 @@ void crom_next(struct crom_context *);
void crom_parse_text(struct crom_context *, char *, int);
u_int16_t crom_crc(u_int32_t *r, int);
struct csrreg *crom_search_key(struct crom_context *, u_int8_t);
int crom_has_specver(u_int32_t *, u_int32_t, u_int32_t);
#ifndef _KERNEL
char *crom_desc(struct crom_context *, char *, int);
#endif

View File

@ -526,14 +526,16 @@ END_DEBUG
target->fwdev = fwdev;
target->target_id = i;
/* XXX we may want to reload mgm port after each bus reset */
if((target->mgm_lo = getcsrdata(fwdev, 0x54)) == 0 ){
/* bad target */
/* XXX there might be multiple management agents */
crom_init_context(&cc, target->fwdev->csrrom);
reg = crom_search_key(&cc, CROM_MGM);
if (reg == NULL || reg->val == 0) {
printf("NULL management address\n");
target->fwdev = NULL;
return NULL;
}
target->mgm_hi = 0xffff;
target->mgm_lo = 0xf0000000 | target->mgm_lo << 2;
target->mgm_lo = 0xf0000000 | (reg->val << 2);
target->mgm_ocb_cur = NULL;
SBP_DEBUG(1)
printf("target:%d mgm_port: %x\n", i, target->mgm_lo);
@ -619,59 +621,36 @@ END_DEBUG
sbp_free_ocb(sdev, ocb);
}
crom_next(&cc);
}
return target;
}
static void
sbp_get_text_leaf(struct fw_device *fwdev, int key, char *buf, int len)
{
static char *nullstr = "(null)";
int i, clen, found=0;
struct csrhdr *chdr;
struct csrreg *creg;
u_int32_t *src, *dst;
chdr = (struct csrhdr *)&fwdev->csrrom[0];
/* skip crom header, bus info and root directory */
creg = (struct csrreg *)chdr + chdr->info_len + 2;
/* search unitl the one before the last. */
for (i = chdr->info_len + 2; i < fwdev->rommax / 4; i++) {
if((creg++)->key == key){
found = 1;
break;
}
}
if (!found || creg->key != CROM_TEXTLEAF) {
strncpy(buf, nullstr, len);
return;
}
src = (u_int32_t *) creg + creg->val;
clen = ((*src >> 16) - 2) * 4;
src += 3;
dst = (u_int32_t *) buf;
if (len < clen)
clen = len;
for (i = 0; i < clen/4; i++)
*dst++ = htonl(*src++);
buf[clen] = 0;
return target;
}
static void
sbp_probe_lun(struct sbp_dev *sdev)
{
struct fw_device *fwdev;
int rev;
struct crom_context c, *cc = &c;
struct csrreg *reg;
fwdev = sdev->target->fwdev;
bzero(sdev->vendor, sizeof(sdev->vendor));
bzero(sdev->product, sizeof(sdev->product));
sbp_get_text_leaf(fwdev, 0x03, sdev->vendor, sizeof(sdev->vendor));
sbp_get_text_leaf(fwdev, 0x17, sdev->product, sizeof(sdev->product));
rev = getcsrdata(sdev->target->fwdev, 0x3c);
snprintf(sdev->revision, sizeof(sdev->revision), "%06x", rev);
}
fwdev = sdev->target->fwdev;
crom_init_context(cc, fwdev->csrrom);
/* get vendor string */
crom_search_key(cc, CSRKEY_VENDOR);
crom_next(cc);
crom_parse_text(cc, sdev->vendor, sizeof(sdev->vendor));
/* get firmware revision */
reg = crom_search_key(cc, CSRKEY_FIRM_VER);
if (reg != NULL)
snprintf(sdev->revision, sizeof(sdev->revision),
"%06x", reg->val);
/* get product string */
crom_search_key(cc, CSRKEY_MODEL);
crom_next(cc);
crom_parse_text(cc, sdev->product, sizeof(sdev->product));
}
static void
sbp_login_callout(void *arg)
@ -680,10 +659,8 @@ sbp_login_callout(void *arg)
sbp_mgm_orb(sdev, ORB_FUN_LGI, NULL);
}
#define SBP_FWDEV_ALIVE(fwdev) \
((fwdev->status == FWDEVATTACHED) \
&& (getcsrdata(fwdev, CSRKEY_SPEC) == CSRVAL_ANSIT10) \
&& (getcsrdata(fwdev, CSRKEY_VER) == CSRVAL_T10SBP2))
#define SBP_FWDEV_ALIVE(fwdev) (((fwdev)->status == FWDEVATTACHED) \
&& crom_has_specver((fwdev)->csrrom, CSRVAL_ANSIT10, CSRVAL_T10SBP2))
static void
sbp_probe_target(void *arg)
@ -812,13 +789,10 @@ END_DEBUG
SBP_DEBUG(0)
printf("sbp_post_explore: EUI:%08x%08x ",
fwdev->eui.hi, fwdev->eui.lo);
if (fwdev->status == FWDEVATTACHED) {
printf("spec=%d key=%d.\n",
getcsrdata(fwdev, CSRKEY_SPEC) == CSRVAL_ANSIT10,
getcsrdata(fwdev, CSRKEY_VER) == CSRVAL_T10SBP2);
} else {
if (fwdev->status != FWDEVATTACHED)
printf("not attached, state=%d.\n", fwdev->status);
}
else
printf("attached\n");
END_DEBUG
alive = SBP_FWDEV_ALIVE(fwdev);
for(i = 0 ; i < SBP_NUM_TARGETS ; i ++){