⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isp_linux.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
	    } else {		mhz = 0;	    }	    switch (flags & (DPARM_WIDE|DPARM_TQING)) {	    case DPARM_WIDE:		wt = ", 16 bit wide";		break;	    case DPARM_TQING:		wt = ", Tagged Queueing Enabled";		break;	    case DPARM_WIDE|DPARM_TQING:		wt = ", 16 bit wide, Tagged Queueing Enabled";		break;	    default:		wt = " ";		break;	    }	    if (mhz) {		isp_prt(isp, ISP_LOGINFO,		    "Channel %d Target %d at %dMHz Max Offset %d%s",		    bus, tgt, mhz, sdp->isp_devparam[tgt].actv_offset, wt);	    } else {		isp_prt(isp, ISP_LOGINFO, "Channel %d Target %d Async Mode%s",		    bus, tgt, wt);	    }	}	break;    case ISPASYNC_LIP:	isp_prt(isp, ISP_LOGINFO, "LIP Received");	break;    case ISPASYNC_LOOP_RESET:	isp_prt(isp, ISP_LOGINFO, "Loop Reset Received");	break;    case ISPASYNC_BUS_RESET:	isp_prt(isp, ISP_LOGINFO, "SCSI bus %d reset detected", *((int *) arg));	break;    case ISPASYNC_LOOP_DOWN:	isp_prt(isp, ISP_LOGINFO, "Loop DOWN");	break;    case ISPASYNC_LOOP_UP:	isp_prt(isp, ISP_LOGINFO, "Loop UP");	break;    case ISPASYNC_PROMENADE:    {	fcparam *fcp = isp->isp_param;	struct lportdb *lp;	int tgt;	tgt = *((int *) arg);	lp = &fcp->portdb[tgt];	if (lp->valid) {	    isp_prt(isp, ISP_LOGINFO,		"ID %d (Loop 0x%x) Port WWN 0x%08x%08x arrived, role %s",		tgt, lp->loopid, (unsigned int) (lp->port_wwn >> 32),		(unsigned int) (lp->port_wwn & 0xffffffff),		class3_roles[fcp->portdb[tgt].roles]);	} else {	    isp_prt(isp, ISP_LOGINFO,		"ID %d (Loop 0x%x) Port WWN 0x%08x%08x departed", tgt,		lp->loopid, (unsigned int) (lp->port_wwn >> 32),		(unsigned int) (lp->port_wwn & 0xffffffff));	}	break;    }    case ISPASYNC_CHANGE_NOTIFY:	if (arg == ISPASYNC_CHANGE_PDB) {		isp_prt(isp, ISP_LOGINFO,		    "Port Database Changed");	} else if (arg == ISPASYNC_CHANGE_SNS) {		isp_prt(isp, ISP_LOGINFO,		    "Name Server Database Changed");	}	SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, 0);	break;    case ISPASYNC_FABRIC_DEV:    {	int target, base, lim;	fcparam *fcp = isp->isp_param;	struct lportdb *lp = NULL;	struct lportdb *clp = (struct lportdb *) arg;	char *pt;	switch (clp->port_type) {	case 1:		pt = "   N_Port";		break;	case 2:		pt = "  NL_Port";		break;	case 3:		pt = "F/NL_Port";		break;	case 0x7f:		pt = "  Nx_Port";		break;	case 0x81:		pt = "  F_port";		break;	case 0x82:		pt = "  FL_Port";		break;	case 0x84:		pt = "   E_port";		break;	default:		pt = " ";		break;	}	isp_prt(isp, ISP_LOGINFO,	    "%s Fabric Device @ PortID 0x%x", pt, clp->portid);	/*	 * If we don't have an initiator role we bail.	 *	 * We just use ISPASYNC_FABRIC_DEV for announcement purposes.	 */	if ((isp->isp_role & ISP_ROLE_INITIATOR) == 0) {		break;	}	/*	 * Is this entry for us? If so, we bail.	 */	if (fcp->isp_portid == clp->portid) {		break;	}	/*	 * Else, the default policy is to find room for it in	 * our local port database. Later, when we execute	 * the call to isp_pdb_sync either this newly arrived	 * or already logged in device will be (re)announced.	 */	if (fcp->isp_topo == TOPO_FL_PORT)		base = FC_SNS_ID+1;	else		base = 0;	if (fcp->isp_topo == TOPO_N_PORT)		lim = 1;	else		lim = MAX_FC_TARG;	/*	 * Is it already in our list?	 */	for (target = base; target < lim; target++) {		if (target >= FL_PORT_ID && target <= FC_SNS_ID) {			continue;		}		lp = &fcp->portdb[target];		if (lp->port_wwn == clp->port_wwn &&		    lp->node_wwn == clp->node_wwn) {			lp->fabric_dev = 1;			break;		}	}	if (target < lim) {		break;	}	for (target = base; target < lim; target++) {		if (target >= FL_PORT_ID && target <= FC_SNS_ID) {			continue;		}		lp = &fcp->portdb[target];		if (lp->port_wwn == 0) {			break;		}	}	if (target == lim) {		isp_prt(isp, ISP_LOGWARN,		    "out of space for fabric devices");		break;	}	lp->port_type = clp->port_type;	lp->fc4_type = clp->fc4_type;	lp->node_wwn = clp->node_wwn;	lp->port_wwn = clp->port_wwn;	lp->portid = clp->portid;	lp->fabric_dev = 1;	break;    }#ifdef	LINUX_ISP_TARGET_MODE    case ISPASYNC_TARGET_MESSAGE:    {	tmd_msg_t *mp = arg;	isp_prt(isp, ISP_LOGTDEBUG2,	    "bus %d iid %d tgt %d lun %d ttype %x tval %x msg[0]=%x",	    mp->nt_bus, (int) mp->nt_iid, (int) mp->nt_tgt, (int) mp->nt_lun,	    mp->nt_tagtype, mp->nt_tagval, mp->nt_msg[0]);	break;    }    case ISPASYNC_TARGET_EVENT:    {	tmd_event_t *ep = arg;	isp_prt(isp, ISP_LOGTDEBUG2,	    "bus %d event code 0x%x", ep->ev_bus, ep->ev_event);	break;    }    case ISPASYNC_TARGET_ACTION:	switch (((isphdr_t *)arg)->rqs_entry_type) {	default:	    isp_prt(isp, ISP_LOGWARN, "event 0x%x for unhandled target action",		((isphdr_t *)arg)->rqs_entry_type);	    break;	case RQSTYPE_ATIO:	    (void) isp_handle_platform_atio(isp, (at_entry_t *) arg);	    break;	case RQSTYPE_ATIO2:	    (void) isp_handle_platform_atio2(isp, (at2_entry_t *)arg);	    break;	case RQSTYPE_CTIO2:	case RQSTYPE_CTIO:	    (void) isp_handle_platform_ctio(isp, arg);	    break;	case RQSTYPE_ENABLE_LUN:	case RQSTYPE_MODIFY_LUN:	    isp->isp_osinfo.rstatus = ((lun_entry_t *)arg)->le_status;	    if (isp->isp_osinfo.rsemap) {		up(isp->isp_osinfo.rsemap);	    }	    break;	}	break;#endif    case ISPASYNC_FW_CRASH:    {	u_int16_t mbox1, mbox6;	mbox1 = ISP_READ(isp, OUTMAILBOX1);	if (IS_DUALBUS(isp)) {	    mbox6 = ISP_READ(isp, OUTMAILBOX6);	} else {	    mbox6 = 0;	}	isp_prt(isp, ISP_LOGERR,	    "Internal F/W Error on bus %d @ RISC Address 0x%x", mbox6, mbox1);	if (IS_FC(isp)) {	    /* XXX isp->isp_blocked = 1; */	    SEND_THREAD_EVENT(isp, ISP_THREAD_FW_CRASH_DUMP, 0);	}	break;    }    case ISPASYNC_UNHANDLED_RESPONSE:	break;    default:	return (-1);    }    return (0);}intisplinux_biosparam(Disk *disk, kdev_t n, int ip[]){    int size = disk->capacity;    ip[0] = 64;    ip[1] = 32;    ip[2] = size >> 11;    if (ip[2] > 1024) {	ip[0] = 255;	ip[1] = 63;	ip[2] = size / (ip[0] * ip[1]);    }    return (0);}/* * Set the queue depth for this device. */voidisplinux_sqd(struct Scsi_Host *host, Scsi_Device *devs){    while (devs) {	if (devs->host == host && devs->tagged_supported == 0) {	    /*	     * If this device doesn't support tagged operations, don't waste	     * queue space for it, even if it has multiple luns.	     */	    devs->queue_depth = 2;	} else if (devs->host == host) {	    int depth = 2;	    struct ispsoftc *isp = (struct ispsoftc *) host->hostdata;	    if (IS_SCSI(isp)) {		sdparam *sdp = isp->isp_param;		sdp += devs->channel;		depth = sdp->isp_devparam[devs->id].exc_throttle;	    } else {		depth = FCPARAM(isp)->isp_execthrottle;	    }	    if (isp_throttle) {		/*		 * This limit is due to the size of devs->queue_depth		 */		depth = (unsigned char) min(isp_throttle, 255);;	    }	    if (depth < 4) {		depth = 4;	    }	    devs->queue_depth = depth;	}	devs = devs->next;    }}/* * Periodic watchdog timer.. the main purpose here is to restart * commands that were pegged on resources, etc... */voidisplinux_timer(unsigned long arg){    Scsi_Cmnd *Cmnd;    struct ispsoftc *isp = (struct ispsoftc *) arg;    ISP_ILOCK_SOFTC(isp);    if (IS_FC(isp)) {	int rql;	if (isp->isp_role & ISP_ROLE_INITIATOR)	    rql = LOOP_READY;	else	    rql = LOOP_LSCAN_DONE;	if (isp->isp_fcrswdog || FCPARAM(isp)->isp_fwstate != FW_READY ||	    FCPARAM(isp)->isp_loopstate < rql) {	    isp->isp_fcrswdog = 0;	    if (isp->isp_deadloop == 0 && isp->isp_role != ISP_ROLE_NONE) {		SEND_THREAD_EVENT(isp, ISP_THREAD_FC_RESCAN, 0);	    }	}    }    isplinux_runwaitq(isp);    if ((Cmnd = isp->isp_osinfo.dqnext) != NULL) {	isp->isp_osinfo.dqnext = isp->isp_osinfo.dqtail = NULL;    }    if (isp->dogactive) {	isp->isp_osinfo.timer.expires = jiffies + ISP_WATCH_TIME;	add_timer(&isp->isp_osinfo.timer);    }    ISP_IUNLK_SOFTC(isp);    if (Cmnd) {	ISP_LOCK_SCSI_DONE(isp);        while (Cmnd) {	    Scsi_Cmnd *f = (Scsi_Cmnd *) Cmnd->host_scribble;	    Cmnd->host_scribble = NULL;	    /*	     * Get around silliness in midlayer.	     */	    if (host_byte(Cmnd->result) == DID_RESET) {		Cmnd->flags |= IS_RESETTING;	    }	    (*Cmnd->scsi_done)(Cmnd);	    Cmnd = f;	}	ISP_UNLK_SCSI_DONE(isp);    }}voidisplinux_mbtimer(unsigned long arg){    struct ispsoftc *isp = (struct ispsoftc *) arg;    ISP_ILOCK_SOFTC(isp);    if (isp->mbox_waiting) {	isp->mbox_waiting = 0;	up(&isp->mbox_c_sem);    }    ISP_IUNLK_SOFTC(isp);}voidisplinux_intr(int irq, void *arg, struct pt_regs *pt){    struct ispsoftc *isp = arg;    u_int16_t isr, sema, mbox;    Scsi_Cmnd *Cmnd;    ISP_ILOCK_SOFTC(isp);    isp->isp_intcnt++;    if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) {	isp->isp_intbogus++;	ISP_IUNLK_SOFTC(isp);	return;    }    isp_intr(isp, isr, sema, mbox);    isplinux_runwaitq(isp);    if ((Cmnd = isp->isp_osinfo.dqnext) != NULL) {	isp->isp_osinfo.dqnext = isp->isp_osinfo.dqtail = NULL;    }#ifdef	LINUX_ISP_TARGET_MODE    if (isp->isp_osinfo.pending_t) {	struct tmd_cmd *tmd = isp->isp_osinfo.pending_t;	isp->isp_osinfo.pending_t = NULL;	ISP_IUNLK_SOFTC(isp);	do {	    struct tmd_cmd *next = tmd->cd_private;	    tmd->cd_private = isp->isp_osinfo.hcb_token;	    (*isp->isp_osinfo.hcb)(tmd->cd_reserved[0], tmd);	    tmd = next;	} while (tmd != NULL);    } else {	ISP_IUNLK_SOFTC(isp);    }#else    ISP_IUNLK_SOFTC(isp);#endif    if (Cmnd) {	ISP_LOCK_SCSI_DONE(isp);        while (Cmnd) {	    Scsi_Cmnd *f = (Scsi_Cmnd *) Cmnd->host_scribble;	    Cmnd->host_scribble = NULL;	    /*	     * Get around silliness in midlayer.	     */	    if (host_byte(Cmnd->result) == DID_RESET) {		Cmnd->flags |= IS_RESETTING;	    }	    (*Cmnd->scsi_done)(Cmnd);	    Cmnd = f;	}	ISP_UNLK_SCSI_DONE(isp);    }}static INLINE intisp_parse_rolearg(struct ispsoftc *isp, char *roles){    char *role = roles;    while (role && *role) {	unsigned int id;	char *eqtok, *commatok, *p, *q;		eqtok = role;	eqtok = strchr(role, '=');	if (eqtok == NULL)	   break;	*eqtok = 0;	commatok = strchr(eqtok+1, ',');	if (commatok)	    *commatok = 0;	if (strncmp(role, "0x", 2) == 0)	    q = role + 2;	else	    q = role;	id = simple_strtoul(q, &p, 16);	*eqtok = '=';	if (p != q && id == isp->isp_osinfo.device_id) {	    p = eqtok + 1;	    if (strcmp(p, "none") == 0) {		if (commatok) {		    *commatok = ',';		}		return (ISP_ROLE_NONE);	    }	    if (strcmp(p, "target") == 0) {		if (commatok) {		    *commatok = ',';		}		return (ISP_ROLE_TARGET);	    }	    if (strcmp(p, "initiator") == 0) {		if (commatok) {		    *commatok = ',';		}		return (ISP_ROLE_INITIATOR);	    }	    if (strcmp(p, "both") == 0) {		if (commatok) {		    *commatok = ',';		}		return (ISP_ROLE_BOTH);	    }	    break;	}        if (commatok) {	    role = commatok+1;	    *commatok = ',';	} else {	    break;	}    }    return (ISP_DEFAULT_ROLES);}static INLINE u_int64_tisp_parse_wwnarg(struct ispsoftc *isp, char *wwns){    char *wwnt = wwns;  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -