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:
parent
f0aa77427a
commit
5e286c3211
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=114069
@ -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;
|
||||
|
@ -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 *));
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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 ++){
|
||||
|
Loading…
Reference in New Issue
Block a user