예제 #1
0
static void DoC_Probe(unsigned long physadr)
{
	unsigned long docptr;
	struct DiskOnChip *this;
	struct mtd_info *mtd;
	int ChipID;
	char namebuf[15];
	char *name = namebuf;
	char *im_funcname = NULL;
	char *im_modname = NULL;
	void (*initroutine)(struct mtd_info *) = NULL;

	docptr = (unsigned long)ioremap(physadr, 0x2000);
	
	if (!docptr)
		return;
	
	if ((ChipID = doccheck(docptr, physadr))) {
		
		mtd = kmalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL);

		if (!mtd) {
			printk("Cannot allocate memory for data structures. Dropping.\n");
			iounmap((void *)docptr);
			return;
		}
		
		this = (struct DiskOnChip *)(&mtd[1]);
		
		memset((char *)mtd,0, sizeof(struct mtd_info));
		memset((char *)this, 0, sizeof(struct DiskOnChip));

		mtd->priv = this;
		this->virtadr = docptr;
		this->physadr = physadr;
		this->ChipID = ChipID;
		sprintf(namebuf, "with ChipID %2.2X", ChipID);

		switch(ChipID) {
		case DOC_ChipID_Doc2k:
			name="2000";
			im_funcname = "DoC2k_init";
			im_modname = "doc2000";
			break;
			
		case DOC_ChipID_DocMil:
			name="Millennium";
#ifdef DOC_SINGLE_DRIVER
			im_funcname = "DoC2k_init";
			im_modname = "doc2000";
#else
			im_funcname = "DoCMil_init";
			im_modname = "doc2001";
#endif /* DOC_SINGLE_DRIVER */
			break;
		}

		if (im_funcname)
			initroutine = inter_module_get_request(im_funcname, im_modname);

		if (initroutine) {
			(*initroutine)(mtd);
			inter_module_put(im_funcname);
			return;
		}
		printk("Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
	}
	iounmap((void *)docptr);
}
예제 #2
0
static void __init DoC_Probe(unsigned long physadr)
{
	unsigned long docptr;
	struct DiskOnChip *this;
	struct mtd_info *mtd;
	int ChipID;
	char namebuf[15];
	char *name = namebuf;
	char *im_funcname = NULL;
	char *im_modname = NULL;
	void (*initroutine)(struct mtd_info *) = NULL;

	docptr = (unsigned long)ioremap(physadr, DOC_IOREMAP_LEN);
	
	if (!docptr)
		return;
	
	if ((ChipID = doccheck(docptr, physadr))) {
		if (ChipID == DOC_ChipID_Doc2kTSOP) {
			/* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */
			printk(KERN_NOTICE "Refusing to drive DiskOnChip 2000 TSOP until Bad Block Table is correctly supported by INFTL\n");
			iounmap((void *)docptr);
			return;
		}
		docfound = 1;
		mtd = kmalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL);

		if (!mtd) {
			printk(KERN_WARNING "Cannot allocate memory for data structures. Dropping.\n");
			iounmap((void *)docptr);
			return;
		}
		
		this = (struct DiskOnChip *)(&mtd[1]);
		
		memset((char *)mtd,0, sizeof(struct mtd_info));
		memset((char *)this, 0, sizeof(struct DiskOnChip));

		mtd->priv = this;
		this->virtadr = (void __iomem *)docptr;
		this->physadr = physadr;
		this->ChipID = ChipID;
		sprintf(namebuf, "with ChipID %2.2X", ChipID);

		switch(ChipID) {
		case DOC_ChipID_Doc2kTSOP:
			name="2000 TSOP";
			im_funcname = "DoC2k_init";
			im_modname = "doc2000";
			break;
			
		case DOC_ChipID_Doc2k:
			name="2000";
			im_funcname = "DoC2k_init";
			im_modname = "doc2000";
			break;
			
		case DOC_ChipID_DocMil:
			name="Millennium";
#ifdef DOC_SINGLE_DRIVER
			im_funcname = "DoC2k_init";
			im_modname = "doc2000";
#else
			im_funcname = "DoCMil_init";
			im_modname = "doc2001";
#endif /* DOC_SINGLE_DRIVER */
			break;

		case DOC_ChipID_DocMilPlus16:
		case DOC_ChipID_DocMilPlus32:
			name="MillenniumPlus";
			im_funcname = "DoCMilPlus_init";
			im_modname = "doc2001plus";
			break;
		}

		if (im_funcname)
			initroutine = inter_module_get_request(im_funcname, im_modname);

		if (initroutine) {
			(*initroutine)(mtd);
			inter_module_put(im_funcname);
			return;
		}
		printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
		kfree(mtd);
	}
	iounmap((void *)docptr);
}
예제 #3
0
RM_STATUS KernInitAGP(
    nv_stack_t *sp,
    nv_state_t *nv,
    NvU64      *ap_phys_base,
    NvU64      *ap_limit
)
{
#ifndef AGPGART
    return RM_ERROR;
#else
    RM_STATUS status = RM_ERROR;
    nv_linux_state_t *nvl;
    void *bitmap;
    agp_kern_info agp_info;
    NvU32 bitmap_size;

    NvU32 agp_rate    = (8 | 4 | 2 | 1);
    NvU32 enable_sba  = 0;
    NvU32 enable_fw   = 0;
    NvU32 agp_mode    = 0;

#if defined(KERNEL_2_4)
    if (!(drm_agp_p = inter_module_get_request("drm_agp", "agpgart")))
        return RM_ERR_NOT_SUPPORTED;
#endif

    /* NOTE: from here down, return an error code of '-1'
     * that indicates that agpgart is loaded, but we failed to use it
     * in some way. This is so we don't try to use nvagp and lock up
     * the memory controller.
     */
    nvl = NV_GET_NVL_FROM_NV_STATE(nv);

    if (NV_AGPGART_BACKEND_ACQUIRE(drm_agp_p, nvl->agp_bridge, nvl->dev))
    {
        nv_printf(NV_DBG_INFO, "NVRM: AGPGART: no backend available\n");
        status = RM_ERR_NOT_SUPPORTED;
        goto bailout;
    }

    if (NV_AGPGART_COPY_INFO(drm_agp_p, nvl->agp_bridge, &agp_info))
    {
        nv_printf(NV_DBG_ERRORS,
            "NVRM: AGPGART: kernel reports chipset as unsupported\n");
        goto release;
    }

    if (nv_pat_mode == NV_PAT_MODE_DISABLED)
    {
#ifdef CONFIG_MTRR
        /*
         * Failure to set a write-combining range on the AGP aperture may
         * be due to the presence of other memory ranges with conflicting
         * caching  attributes. Play safe and fail AGP initialization.
         */
        if (mtrr_add(agp_info.aper_base, agp_info.aper_size << 20,
                MTRR_TYPE_WRCOMB, 0) < 0)
#endif
        {
            nv_printf(NV_DBG_ERRORS, 
                "NVRM: AGPGART: unable to set MTRR write-combining\n");
            goto release;
        }
    }

    // allocate and set the bitmap for tracking agp allocations
    bitmap_size = (agp_info.aper_size << 20)/PAGE_SIZE/8;
    if (os_alloc_mem(&bitmap, bitmap_size))
    {
        nv_printf(NV_DBG_ERRORS, "NVRM: AGPGART: unable to allocate bitmap\n");
        goto failed;
    }

    os_mem_set(bitmap, 0xff, bitmap_size);
    status = rm_set_agp_bitmap(sp, nv, bitmap);
    if (status != RM_OK)
    {
        nv_printf(NV_DBG_ERRORS, "NVRM: AGPGART: unable to set bitmap\n");
        os_free_mem(bitmap);
        goto failed;
    }

    agp_mode = agp_info.mode;
    rm_read_registry_dword(sp, NULL, "NVreg", "ReqAGPRate", &agp_rate);

    agp_mode = NV_AGPGART_MODE_BITS_RATE(agp_mode, agp_rate);
    agp_mode |= 1; /* avoid 0x mode request */

    if (agp_mode & 2) agp_mode &= ~1;
    if (agp_mode & 4) agp_mode &= ~2;

    rm_read_registry_dword(sp, NULL, "NVreg", "EnableAGPSBA", &enable_sba);
    agp_mode |= NV_AGPGART_MODE_BITS_SBA(enable_sba);

    rm_read_registry_dword(sp, NULL, "NVreg", "EnableAGPFW", &enable_fw);
    agp_mode |= NV_AGPGART_MODE_BITS_FW(enable_fw);

    agp_info.mode &= (0xff000000 | agp_mode);
    NV_AGPGART_BACKEND_ENABLE(drm_agp_p, nvl->agp_bridge, agp_info.mode);

    *ap_phys_base = (unsigned)agp_info.aper_base;
    *ap_limit = (unsigned)((agp_info.aper_size << 20) - 1);

    return RM_OK;

failed:
#ifdef CONFIG_MTRR
    if (nv_pat_mode == NV_PAT_MODE_DISABLED)
        mtrr_del(-1, agp_info.aper_base, agp_info.aper_size << 20);
#endif
release:
    NV_AGPGART_BACKEND_RELEASE(drm_agp_p, nvl->agp_bridge);
bailout:
#if defined(KERNEL_2_4)
    inter_module_put("drm_agp");
#endif

    return status;

#endif /* AGPGART */
}