File:  [DragonFly] / src / sys / dev / disk / ata / ata-all.h
Revision 1.5: download - view: text, annotated - select for diffs
Wed Feb 18 00:50:00 2004 UTC (10 years, 2 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
ATAng stage 2: sync part of the ata_dma*() API.  No operational changes.

    1: /*-
    2:  * Copyright (c) 1998,1999,2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
    3:  * All rights reserved.
    4:  *
    5:  * Redistribution and use in source and binary forms, with or without
    6:  * modification, are permitted provided that the following conditions
    7:  * are met:
    8:  * 1. Redistributions of source code must retain the above copyright
    9:  *    notice, this list of conditions and the following disclaimer,
   10:  *    without modification, immediately at the beginning of the file.
   11:  * 2. Redistributions in binary form must reproduce the above copyright
   12:  *    notice, this list of conditions and the following disclaimer in the
   13:  *    documentation and/or other materials provided with the distribution.
   14:  * 3. The name of the author may not be used to endorse or promote products
   15:  *    derived from this software without specific prior written permission.
   16:  *
   17:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27:  *
   28:  * $FreeBSD: src/sys/dev/ata/ata-all.h,v 1.26.2.12 2003/01/30 07:19:59 sos Exp $
   29:  * $DragonFly: src/sys/dev/disk/ata/ata-all.h,v 1.5 2004/02/18 00:50:00 dillon Exp $
   30:  */
   31: 
   32: #ifndef _SYS_MPIPE_H_
   33: #include <sys/mpipe.h>
   34: #endif
   35: 
   36: /* ATA register defines */
   37: #define ATA_DATA			0x00	/* data register */
   38: #define ATA_ERROR			0x01	/* (R) error register */
   39: #define		ATA_E_NM		0x02	/* no media */
   40: #define		ATA_E_ABORT		0x04	/* command aborted */
   41: #define		ATA_E_MCR		0x08	/* media change request */
   42: #define		ATA_E_IDNF		0x10	/* ID not found */
   43: #define		ATA_E_MC		0x20	/* media changed */
   44: #define		ATA_E_UNC		0x40	/* uncorrectable data */
   45: #define		ATA_E_ICRC		0x80	/* UDMA crc error */
   46: 
   47: #define ATA_FEATURE			0x01	/* (W) feature register */
   48: #define		ATA_F_DMA		0x01	/* enable DMA */
   49: #define		ATA_F_OVL		0x02	/* enable overlap */
   50: 
   51: #define ATA_COUNT			0x02	/* (W) sector count */
   52: #define ATA_IREASON			0x02	/* (R) interrupt reason */
   53: #define		ATA_I_CMD		0x01	/* cmd (1) | data (0) */
   54: #define		ATA_I_IN		0x02	/* read (1) | write (0) */
   55: #define		ATA_I_RELEASE		0x04	/* released bus (1) */
   56: #define		ATA_I_TAGMASK		0xf8	/* tag mask */
   57: 
   58: #define ATA_SECTOR			0x03	/* sector # */
   59: #define ATA_CYL_LSB			0x04	/* cylinder# LSB */
   60: #define ATA_CYL_MSB			0x05	/* cylinder# MSB */
   61: #define ATA_DRIVE			0x06	/* Sector/Drive/Head register */
   62: #define		ATA_D_LBA		0x40	/* use LBA addressing */
   63: #define		ATA_D_IBM		0xa0	/* 512 byte sectors, ECC */
   64: 
   65: #define ATA_CMD				0x07	/* command register */
   66: #define		ATA_C_NOP		0x00	/* NOP command */
   67: #define		    ATA_C_F_FLUSHQUEUE	0x00	/* flush queued cmd's */
   68: #define		    ATA_C_F_AUTOPOLL	0x01	/* start autopoll function */
   69: #define		ATA_C_ATAPI_RESET	0x08	/* reset ATAPI device */
   70: #define		ATA_C_READ		0x20	/* read command */
   71: #define		ATA_C_READ48		0x24	/* read command */
   72: #define		ATA_C_READ_DMA48	0x25	/* read w/DMA command */
   73: #define		ATA_C_READ_DMA_QUEUED48 0x26	/* read w/DMA QUEUED command */
   74: #define		ATA_C_READ_MUL48	0x29	/* read multi command */
   75: #define		ATA_C_WRITE		0x30	/* write command */
   76: #define		ATA_C_WRITE48		0x34	/* write command */
   77: #define		ATA_C_WRITE_DMA48	0x35	/* write w/DMA command */
   78: #define		ATA_C_WRITE_DMA_QUEUED48 0x36	/* write w/DMA QUEUED command */
   79: #define		ATA_C_WRITE_MUL48	0x39	/* write multi command */
   80: #define		ATA_C_PACKET_CMD	0xa0	/* packet command */
   81: #define		ATA_C_ATAPI_IDENTIFY	0xa1	/* get ATAPI params*/
   82: #define		ATA_C_SERVICE		0xa2	/* service command */
   83: #define		ATA_C_READ_MUL		0xc4	/* read multi command */
   84: #define		ATA_C_WRITE_MUL		0xc5	/* write multi command */
   85: #define		ATA_C_SET_MULTI		0xc6	/* set multi size command */
   86: #define		ATA_C_READ_DMA_QUEUED	0xc7	/* read w/DMA QUEUED command */
   87: #define		ATA_C_READ_DMA		0xc8	/* read w/DMA command */
   88: #define		ATA_C_WRITE_DMA		0xca	/* write w/DMA command */
   89: #define		ATA_C_WRITE_DMA_QUEUED	0xcc	/* write w/DMA QUEUED command */
   90: #define		ATA_C_SLEEP		0xe6	/* sleep command */
   91: #define		ATA_C_FLUSHCACHE	0xe7	/* flush cache to disk */
   92: #define		ATA_C_FLUSHCACHE48	0xea	/* flush cache to disk */
   93: #define		ATA_C_ATA_IDENTIFY	0xec	/* get ATA params */
   94: #define		ATA_C_SETFEATURES	0xef	/* features command */
   95: #define		    ATA_C_F_SETXFER	0x03	/* set transfer mode */
   96: #define		    ATA_C_F_ENAB_WCACHE 0x02	/* enable write cache */
   97: #define		    ATA_C_F_DIS_WCACHE	0x82	/* disable write cache */
   98: #define		    ATA_C_F_ENAB_RCACHE 0xaa	/* enable readahead cache */
   99: #define		    ATA_C_F_DIS_RCACHE	0x55	/* disable readahead cache */
  100: #define		    ATA_C_F_ENAB_RELIRQ 0x5d	/* enable release interrupt */
  101: #define		    ATA_C_F_DIS_RELIRQ	0xdd	/* disable release interrupt */
  102: #define		    ATA_C_F_ENAB_SRVIRQ 0x5e	/* enable service interrupt */
  103: #define		    ATA_C_F_DIS_SRVIRQ	0xde	/* disable service interrupt */
  104: 
  105: #define ATA_STATUS			0x07	/* status register */
  106: #define		ATA_S_ERROR		0x01	/* error */
  107: #define		ATA_S_INDEX		0x02	/* index */
  108: #define		ATA_S_CORR		0x04	/* data corrected */
  109: #define		ATA_S_DRQ		0x08	/* data request */
  110: #define		ATA_S_DSC		0x10	/* drive seek completed */
  111: #define		ATA_S_SERVICE		0x10	/* drive needs service */
  112: #define		ATA_S_DWF		0x20	/* drive write fault */
  113: #define		ATA_S_DMA		0x20	/* DMA ready */
  114: #define		ATA_S_READY		0x40	/* drive ready */
  115: #define		ATA_S_BUSY		0x80	/* busy */
  116: 
  117: #define ATA_ALTSTAT			0x00	/* alternate status register */
  118: #define ATA_ALTOFFSET			0x206	/* alternate registers offset */
  119: #define ATA_PCCARD_ALTOFFSET		0x0e	/* do for PCCARD devices */
  120: #define		ATA_A_IDS		0x02	/* disable interrupts */
  121: #define		ATA_A_RESET		0x04	/* RESET controller */
  122: #define		ATA_A_4BIT		0x08	/* 4 head bits */
  123: 
  124: /* misc defines */
  125: #define ATA_PRIMARY			0x1f0
  126: #define ATA_SECONDARY			0x170
  127: #define ATA_IOSIZE			0x08
  128: #define ATA_ALTIOSIZE			0x01
  129: #define ATA_BMIOSIZE			0x08
  130: #define ATA_OP_FINISHED			0x00
  131: #define ATA_OP_CONTINUES		0x01
  132: #define ATA_IOADDR_RID			0
  133: #define ATA_ALTADDR_RID			1
  134: #define ATA_BMADDR_RID			2
  135: #define ATA_IRQ_RID			0
  136: #define ATA_DEV(device)			((device == ATA_MASTER) ? 0 : 1)
  137: 
  138: /* busmaster DMA related defines */
  139: #define ATA_DMA_ENTRIES			256
  140: #define ATA_DMA_EOT			0x80000000
  141: 
  142: #define ATA_BMCMD_PORT			0x00
  143: #define		ATA_BMCMD_START_STOP	0x01
  144: #define		ATA_BMCMD_WRITE_READ	0x08
  145: 
  146: #define ATA_BMDEVSPEC_0			0x01
  147: 
  148: #define ATA_BMSTAT_PORT			0x02
  149: #define		ATA_BMSTAT_ACTIVE	0x01
  150: #define		ATA_BMSTAT_ERROR	0x02
  151: #define		ATA_BMSTAT_INTERRUPT	0x04
  152: #define		ATA_BMSTAT_MASK		0x07
  153: #define		ATA_BMSTAT_DMA_MASTER	0x20
  154: #define		ATA_BMSTAT_DMA_SLAVE	0x40
  155: #define		ATA_BMSTAT_DMA_SIMPLEX	0x80
  156: 
  157: #define ATA_BMDEVSPEC_1			0x03
  158: #define ATA_BMDTP_PORT			0x04
  159: 
  160: /* structure for holding DMA address data */
  161: struct ata_dmaentry {
  162:     u_int32_t base;
  163:     u_int32_t count;
  164: };  
  165: 
  166: /* structure describing an ATA/ATAPI device */
  167: struct ata_device {
  168:     struct ata_channel		*channel;
  169:     int				unit;		/* unit number */
  170: #define ATA_MASTER			0x00
  171: #define ATA_SLAVE			0x10
  172: 
  173:     char			*name;		/* device name */
  174:     struct ata_params		*param;		/* ata param structure */
  175:     void			*driver;	/* ptr to driver for device */
  176:     int				flags;
  177: #define		ATA_D_USE_CHS		0x0001
  178: #define		ATA_D_DETACHING		0x0002
  179: #define		ATA_D_MEDIA_CHANGED	0x0004
  180: #define		ATA_D_ENC_PRESENT	0x0008
  181: 
  182:     int				mode;		/* transfermode */
  183:     int				cmd;		/* last cmd executed */
  184:     void			*result;	/* misc data */
  185: };
  186: 
  187: /* structure describing an ATA channel */
  188: struct ata_channel {
  189:     struct device		*dev;		/* device handle */
  190:     int				unit;		/* channel number */
  191:     struct resource		*r_io;		/* io addr resource handle */
  192:     struct resource		*r_altio;	/* altio addr resource handle */
  193:     struct resource		*r_bmio;	/* bmio addr resource handle */
  194:     struct resource		*r_irq;		/* interrupt of this channel */
  195:     void			*ih;		/* interrupt handle */
  196:     int (*intr_func)(struct ata_channel *);	/* interrupt function */
  197:     u_int32_t			chiptype;	/* pciid of controller chip */
  198:     u_int32_t			alignment;	/* dma engine min alignment */
  199:     int				flags;		/* controller flags */
  200: #define		ATA_NO_SLAVE		0x01
  201: #define		ATA_USE_16BIT		0x02
  202: #define		ATA_ATAPI_DMA_RO	0x04
  203: #define		ATA_QUEUED		0x08
  204: #define		ATA_DMA_ACTIVE		0x10
  205: 
  206:     struct ata_device		device[2];	/* devices on this channel */
  207: #define		MASTER			0x00
  208: #define		SLAVE			0x01
  209: 
  210:     int				devices;	/* what is present */
  211: #define		ATA_ATA_MASTER		0x01
  212: #define		ATA_ATA_SLAVE		0x02
  213: #define		ATA_ATAPI_MASTER	0x04
  214: #define		ATA_ATAPI_SLAVE		0x08
  215: 
  216:     u_int8_t			status;		/* last controller status */
  217:     u_int8_t			error;		/* last controller error */
  218:     int				active;		/* active processing request */
  219: #define		ATA_IDLE		0x0000
  220: #define		ATA_IMMEDIATE		0x0001
  221: #define		ATA_WAIT_INTR		0x0002
  222: #define		ATA_WAIT_READY		0x0004
  223: #define		ATA_WAIT_MASK		0x0007
  224: #define		ATA_ACTIVE		0x0010
  225: #define		ATA_ACTIVE_ATA		0x0020
  226: #define		ATA_ACTIVE_ATAPI	0x0040
  227: #define		ATA_CONTROL		0x0080
  228: 
  229:     TAILQ_HEAD(, ad_request)	ata_queue;	/* head of ATA queue */
  230:     TAILQ_HEAD(, atapi_request) atapi_queue;	/* head of ATAPI queue */
  231:     void			*running;	/* currently running request */
  232:     struct malloc_pipe		req_mpipe;	/* request allocations */
  233:     struct malloc_pipe		dma_mpipe;	/* dma allocations */
  234: };
  235: 
  236: /* disk bay/enclosure related */
  237: #define		ATA_LED_OFF		0x00
  238: #define		ATA_LED_RED		0x01
  239: #define		ATA_LED_GREEN		0x02
  240: #define		ATA_LED_ORANGE		0x03
  241: #define		ATA_LED_MASK		0x03
  242: 
  243: /* externs */
  244: extern devclass_t ata_devclass;
  245: extern int	ata_mpipe_size;
  246:  
  247: /* public prototypes */
  248: int ata_probe(device_t);
  249: int ata_attach(device_t);
  250: int ata_detach(device_t);
  251: int ata_resume(device_t);
  252: 
  253: void ata_start(struct ata_channel *);
  254: void ata_reset(struct ata_channel *);
  255: int ata_reinit(struct ata_channel *);
  256: int ata_wait(struct ata_device *, u_int8_t);
  257: int ata_command(struct ata_device *, u_int8_t, u_int64_t, u_int16_t, u_int8_t, int);
  258: void ata_enclosure_leds(struct ata_device *, u_int8_t);
  259: void ata_enclosure_print(struct ata_device *);
  260: int ata_printf(struct ata_channel *, int, const char *, ...) __printflike(3, 4);
  261: int ata_prtdev(struct ata_device *, const char *, ...) __printflike(2, 3);
  262: void ata_set_name(struct ata_device *, char *, int);
  263: void ata_free_name(struct ata_device *);
  264: int ata_get_lun(u_int32_t *);
  265: int ata_test_lun(u_int32_t *, int);
  266: void ata_free_lun(u_int32_t *, int);
  267: char *ata_mode2str(int);
  268: int ata_pmode(struct ata_params *);
  269: int ata_wmode(struct ata_params *);
  270: int ata_umode(struct ata_params *);
  271: int ata_find_dev(device_t, u_int32_t, u_int32_t);
  272: 
  273: void *ata_dmaalloc(struct ata_channel *, int, int);
  274: void ata_dmafree(struct ata_channel *, void *buf);
  275: void ata_dmainit(struct ata_device *, int, int, int);
  276: int ata_dmasetup(struct ata_channel *, int, struct ata_dmaentry *, caddr_t, int);
  277: void ata_dmastart(struct ata_channel *, int, struct ata_dmaentry *, int);
  278: int ata_dmastatus(struct ata_channel *);
  279: int ata_dmadone(struct ata_device *);
  280: 
  281: /* macros for locking a channel */
  282: #define ATA_LOCK_CH(ch, value)\
  283: 	(((ch)->active == ATA_IDLE) ? ((ch)->active = value) : 0)
  284: 
  285: #define ATA_SLEEPLOCK_CH(ch, value) {\
  286: 	while ((ch)->active != ATA_IDLE)\
  287: 	    tsleep((caddr_t)&(ch), 0, "atalck", 1);\
  288: 	(ch)->active = value; }
  289: 
  290: #define ATA_FORCELOCK_CH(ch, value) \
  291: 	(ch)->active = value
  292: 
  293: #define ATA_UNLOCK_CH(ch) \
  294: 	(ch)->active = ATA_IDLE
  295: 
  296: /* macros to hide busspace uglyness */
  297: #define ATA_INB(res, offset) \
  298: 	bus_space_read_1(rman_get_bustag((res)), \
  299: 			 rman_get_bushandle((res)), (offset))
  300: #define ATA_INW(res, offset) \
  301: 	bus_space_read_2(rman_get_bustag((res)), \
  302: 			 rman_get_bushandle((res)), (offset))
  303: #define ATA_INL(res, offset) \
  304: 	bus_space_read_4(rman_get_bustag((res)), \
  305: 			 rman_get_bushandle((res)), (offset))
  306: #define ATA_INSW(res, offset, addr, count) \
  307: 	bus_space_read_multi_2(rman_get_bustag((res)), \
  308: 			       rman_get_bushandle((res)), \
  309: 			       (offset), (addr), (count))
  310: #define ATA_INSL(res, offset, addr, count) \
  311: 	bus_space_read_multi_4(rman_get_bustag((res)), \
  312: 			       rman_get_bushandle((res)), \
  313: 			       (offset), (addr), (count))
  314: #define ATA_OUTB(res, offset, value) \
  315: 	bus_space_write_1(rman_get_bustag((res)), \
  316: 			  rman_get_bushandle((res)), (offset), (value))
  317: #define ATA_OUTW(res, offset, value) \
  318: 	bus_space_write_2(rman_get_bustag((res)), \
  319: 			  rman_get_bushandle((res)), (offset), (value))
  320: #define ATA_OUTL(res, offset, value) \
  321: 	bus_space_write_4(rman_get_bustag((res)), \
  322: 			  rman_get_bushandle((res)), (offset), (value))
  323: #define ATA_OUTSW(res, offset, addr, count) \
  324: 	bus_space_write_multi_2(rman_get_bustag((res)), \
  325: 				rman_get_bushandle((res)), \
  326: 				(offset), (addr), (count))
  327: #define ATA_OUTSL(res, offset, addr, count) \
  328: 	bus_space_write_multi_4(rman_get_bustag((res)), \
  329: 				rman_get_bushandle((res)), \
  330: 				(offset), (addr), (count))