Пример #1
0
Файл: ips.c Проект: MarginC/kame
/* clean up so we can unload the driver. */
int ips_adapter_free(ips_softc_t *sc)
{
	int error = 0;
	intrmask_t mask;
	if(sc->state & IPS_DEV_OPEN)
		return EBUSY;
	if((error = ips_diskdev_free(sc)))
		return error;
	if(ips_cmdqueue_free(sc)){
		device_printf(sc->dev,
		     "trying to exit when command queue is not empty!\n");
		return EBUSY;
	}
	DEVICE_PRINTF(1, sc->dev, "free\n");
	mask = splbio();
	untimeout(ips_timeout, sc, sc->timer);
	splx(mask);
	if (mtx_initialized(&sc->cmd_mtx))
		mtx_destroy(&sc->cmd_mtx);

	if(sc->sg_dmatag)
		bus_dma_tag_destroy(sc->sg_dmatag);
	if(sc->command_dmatag)
		bus_dma_tag_destroy(sc->command_dmatag);
	if(sc->device_file)
	        destroy_dev(sc->device_file);
        return 0;
}
Пример #2
0
Файл: ips.c Проект: MarginC/kame
/* places all ips command structs on the free command queue.  No locking as if someone else tries
 * to access this during init, we have bigger problems */
static __inline__ int ips_cmdqueue_init(ips_softc_t *sc)
{
	int i;
	ips_command_t *command;
	SLIST_INIT(&sc->free_cmd_list);
	STAILQ_INIT(&sc->cmd_wait_list);
	for(i = 0; i < sc->max_cmds; i++){
		sc->commandarray[i].id = i;
		sc->commandarray[i].sc = sc;
		SLIST_INSERT_HEAD(&sc->free_cmd_list, &sc->commandarray[i], 
				  next);	
	}
	for(i = 0; i < sc->max_cmds; i++){
		command = &sc->commandarray[i];
		if(bus_dmamem_alloc(sc->command_dmatag,&command->command_buffer,
		    BUS_DMA_NOWAIT, &command->command_dmamap))
			goto error;
		bus_dmamap_load(sc->command_dmatag, command->command_dmamap, 
				command->command_buffer,IPS_COMMAND_LEN, 
				ips_cmd_dmaload, command, BUS_DMA_NOWAIT);
		if(!command->command_phys_addr){
			bus_dmamem_free(sc->command_dmatag, 
			    command->command_buffer, command->command_dmamap);
			goto error;
		}
	}
	sc->state &= ~IPS_OFFLINE;
	return 0;
error:
		ips_cmdqueue_free(sc);
		return ENOMEM;
}
Пример #3
0
/* places all ips command structs on the free command queue.  No locking as if someone else tries
 * to access this during init, we have bigger problems */
static int ips_cmdqueue_init(ips_softc_t *sc)
{
	int i;
	ips_command_t *command;

	sc->commandarray = (ips_command_t *)malloc(sizeof(ips_command_t) *
	    sc->max_cmds, M_DEVBUF, M_NOWAIT|M_ZERO);
	if (sc->commandarray == NULL)
		return (ENOMEM);

	SLIST_INIT(&sc->free_cmd_list);
	for(i = 0; i < sc->max_cmds; i++){
		command = &sc->commandarray[i];
		command->id = i;
		command->sc = sc;

		if(bus_dmamem_alloc(sc->command_dmatag,&command->command_buffer,
		    BUS_DMA_NOWAIT, &command->command_dmamap))
			goto error;
		bus_dmamap_load(sc->command_dmatag, command->command_dmamap, 
				command->command_buffer,IPS_COMMAND_LEN, 
				ips_cmd_dmaload, command, BUS_DMA_NOWAIT);
		if(!command->command_phys_addr){
			bus_dmamem_free(sc->command_dmatag, 
			    command->command_buffer, command->command_dmamap);
			goto error;
		}

		if (i != 0) {
			command->data_dmatag = sc->sg_dmatag;
			if (bus_dmamap_create(command->data_dmatag, 0,
			    &command->data_dmamap))
				goto error;
			SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);	
		} else
			sc->staticcmd = command;
	}
	sc->state &= ~IPS_OFFLINE;
	return 0;
error:
	ips_cmdqueue_free(sc);
	return ENOMEM;
}
Пример #4
0
/* clean up so we can unload the driver. */
int ips_adapter_free(ips_softc_t *sc)
{
	int error = 0;
	if(sc->state & IPS_DEV_OPEN)
		return EBUSY;
	if((error = ips_diskdev_free(sc)))
		return error;
	if(ips_cmdqueue_free(sc)){
		device_printf(sc->dev,
		     "trying to exit when command queue is not empty!\n");
		return EBUSY;
	}
	DEVICE_PRINTF(1, sc->dev, "free\n");
	callout_drain(&sc->timer);

	if(sc->sg_dmatag)
		bus_dma_tag_destroy(sc->sg_dmatag);
	if(sc->command_dmatag)
		bus_dma_tag_destroy(sc->command_dmatag);
	if(sc->device_file)
	        destroy_dev(sc->device_file);
        return 0;
}
Пример #5
0
/* check card and initialize it */
int ips_adapter_init(ips_softc_t *sc)
{
        int i;
        DEVICE_PRINTF(1,sc->dev, "initializing\n");

        if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
				/* alignemnt */	1,
				/* boundary  */	0,
				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
				/* highaddr  */	BUS_SPACE_MAXADDR,
				/* filter    */	NULL,
				/* filterarg */	NULL,
				/* maxsize   */	IPS_COMMAND_LEN + 
						    IPS_MAX_SG_LEN,
				/* numsegs   */	1,
				/* maxsegsize*/	IPS_COMMAND_LEN + 
						    IPS_MAX_SG_LEN,
				/* flags     */	0,
				/* lockfunc  */ NULL,
				/* lockarg   */ NULL,
				&sc->command_dmatag) != 0) {
                device_printf(sc->dev, "can't alloc command dma tag\n");
		goto error;
        }
	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
				/* alignemnt */	1,
				/* boundary  */	0,
				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
				/* highaddr  */	BUS_SPACE_MAXADDR,
				/* filter    */	NULL,
				/* filterarg */	NULL,
				/* maxsize   */	IPS_MAX_IOBUF_SIZE,
				/* numsegs   */	IPS_MAX_SG_ELEMENTS,
				/* maxsegsize*/	IPS_MAX_IOBUF_SIZE,
				/* flags     */	0,
				/* lockfunc  */ busdma_lock_mutex,
				/* lockarg   */ &sc->queue_mtx,
				&sc->sg_dmatag) != 0) {
		device_printf(sc->dev, "can't alloc SG dma tag\n");
		goto error;
	}
	/* create one command buffer until we know how many commands this card
           can handle */
	sc->max_cmds = 1;
	ips_cmdqueue_init(sc);

	if(sc->ips_adapter_reinit(sc, 0))
		goto error;

	/* initialize ffdc values */
	microtime(&sc->ffdc_resettime);
	sc->ffdc_resetcount = 1;
	if ((i = ips_ffdc_reset(sc)) != 0) {
		device_printf(sc->dev, "failed to send ffdc reset to device (%d)\n", i);
		goto error;
	}
	if ((i = ips_get_adapter_info(sc)) != 0) {
		device_printf(sc->dev, "failed to get adapter configuration data from device (%d)\n", i);
		goto error;
	}
	ips_update_nvram(sc); /* no error check as failure doesn't matter */
	if(sc->adapter_type > 0 && sc->adapter_type <= IPS_ADAPTER_MAX_T){
		device_printf(sc->dev, "adapter type: %s\n", ips_adapter_name[sc->adapter_type]);
	}
 	if ((i = ips_get_drive_info(sc)) != 0) {
		device_printf(sc->dev, "failed to get drive configuration data from device (%d)\n", i);
		goto error;
	}

        ips_cmdqueue_free(sc);
	if(sc->adapter_info.max_concurrent_cmds)
        	sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
	else
		sc->max_cmds = 32;
        if(ips_cmdqueue_init(sc)){
		device_printf(sc->dev, "failed to initialize command buffers\n");
		goto error;
	}
        sc->device_file = make_dev(&ips_cdevsw, device_get_unit(sc->dev), UID_ROOT, GID_OPERATOR,
                                        S_IRUSR | S_IWUSR, "ips%d", device_get_unit(sc->dev));
	sc->device_file->si_drv1 = sc;
	ips_diskdev_init(sc);
	callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
        return 0;

error:
	ips_adapter_free(sc);
	return ENXIO;
}
Пример #6
0
Файл: ips.c Проект: MarginC/kame
/* check card and initialize it */
int ips_adapter_init(ips_softc_t *sc)
{
        DEVICE_PRINTF(1,sc->dev, "initializing\n");
        if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
				/* alignemnt */	1,
				/* boundary  */	0,
				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
				/* highaddr  */	BUS_SPACE_MAXADDR,
				/* filter    */	NULL,
				/* filterarg */	NULL,
				/* maxsize   */	IPS_COMMAND_LEN + 
						    IPS_MAX_SG_LEN,
				/* numsegs   */	1,
				/* maxsegsize*/	IPS_COMMAND_LEN + 
						    IPS_MAX_SG_LEN,
				/* flags     */	0,
				&sc->command_dmatag) != 0) {
                device_printf(sc->dev, "can't alloc command dma tag\n");
		goto error;
        }
	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
				/* alignemnt */	1,
				/* boundary  */	0,
				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
				/* highaddr  */	BUS_SPACE_MAXADDR,
				/* filter    */	NULL,
				/* filterarg */	NULL,
				/* maxsize   */	IPS_MAX_IOBUF_SIZE,
				/* numsegs   */	IPS_MAX_SG_ELEMENTS,
				/* maxsegsize*/	IPS_MAX_IOBUF_SIZE,
				/* flags     */	0,
				&sc->sg_dmatag) != 0) {
		device_printf(sc->dev, "can't alloc SG dma tag\n");
		goto error;
	}
	/* create one command buffer until we know how many commands this card
           can handle */
	sc->max_cmds = 1;
	ips_cmdqueue_init(sc);

	if(sc->ips_adapter_reinit(sc, 0))
		goto error;

	mtx_init(&sc->cmd_mtx, "ips command mutex", NULL, MTX_DEF);
	if(ips_get_adapter_info(sc) || ips_get_drive_info(sc)){
		device_printf(sc->dev, "failed to get configuration data from device\n");
		goto error;
	}
	ips_update_nvram(sc); /* no error check as failure doesn't matter */

        ips_cmdqueue_free(sc);
	if(sc->adapter_info.max_concurrent_cmds)
        	sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
	else
		sc->max_cmds = 32;
        if(ips_cmdqueue_init(sc)){
		device_printf(sc->dev, "failed to initialize command buffers\n");
		goto error;
	}
        sc->device_file = make_dev(&ips_cdevsw, device_get_unit(sc->dev), UID_ROOT, GID_OPERATOR,
                                        S_IRUSR | S_IWUSR, "ips%d", device_get_unit(sc->dev));
	sc->device_file->si_drv1 = sc;
	ips_diskdev_init(sc);
	sc->timer = timeout(ips_timeout, sc, 10*hz);
        return 0;

error:
	ips_adapter_free(sc);
	return ENXIO;
}