Defined more SCSI sense data keys
[AROS.git] / rom / devs / ahci / ahci_aros.h
blob840f7ec5f728c7756170b2e3848913b05400f49e
1 /*
2 * Copyright (C) 2012, The AROS Development Team. All rights reserved.
3 * Author: Jason S. McMullan <jason.mcmullan@gmail.com>
5 * Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
6 */
8 #ifndef AHCI_AROS_H
9 #define AHCI_AROS_H
11 #include <stdio.h>
12 #include <stdint.h>
13 #include <errno.h>
14 #include <assert.h>
16 #include <sys/types.h>
17 #include <sys/select.h>
19 #include <aros/debug.h>
21 #undef D2
22 #if DEBUG > 1
23 #define D2(x) x
24 #else
25 #define D2(x)
26 #endif
28 #include <proto/exec.h>
29 #include <proto/oop.h>
31 #include <hidd/pci.h>
33 #include "ahci_intern.h"
34 #include "pci_ids.h"
36 #undef kprintf
37 #define kprintf(fmt, args...) device_printf(NULL, fmt ,##args)
39 #ifdef __GNUC__
40 #define __packed __attribute__((__packed__))
41 #else
42 #error Define __packed appropriately for your compiler!
43 #endif
45 typedef uint8_t u_int8_t;
46 typedef uint16_t u_int16_t;
47 typedef uint32_t u_int32_t;
48 typedef uint64_t u_int64_t;
49 typedef unsigned int u_int;
51 #define le16toh(x) AROS_LE2WORD(x)
52 #define le32toh(x) AROS_LE2LONG(x)
53 #define htole32(x) AROS_LONG2LE(x)
54 #define htole16(x) AROS_WORD2LE(x)
56 #define PAGE_SIZE 4096
58 typedef struct {
59 struct MinNode dev_Node;
60 OOP_Object *dev_Object;
61 struct AHCIBase *dev_AHCIBase;
62 struct ahci_softc *dev_softc;
63 ULONG dev_HostID;
64 } *device_t;
66 /* Kernel stuff */
68 #define KKASSERT(expr) ASSERT(expr)
70 int kvsnrprintf(char *str, size_t size, int radix, const char *format, va_list ap);
71 int kvsnprintf(char *str, size_t size, const char *format, va_list ap);
72 int ksnprintf(char *buff, size_t len, const char *fmt, ...);
73 int kvcprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap);
75 static inline void bug_c(int c, void *info)
77 RawPutChar(c);
80 static inline int device_printf(device_t dev, const char *fmt, ...)
82 va_list args;
83 int err;
84 va_start(args, fmt);
85 err = kvcprintf(fmt, bug_c, NULL, 10, args);
86 va_end(args);
87 return err;
91 #define panic(fmt, args...) do { Forbid(); device_printf(NULL, fmt ,##args); Disable(); for (;;); } while (0);
93 static inline void *kmalloc(size_t size, unsigned where, unsigned flags)
95 return AllocVec(size, flags);
98 static inline void kfree(void *ptr, unsigned where)
100 FreeVec(ptr);
103 static inline void crit_enter(void)
105 Disable();
108 static inline void crit_exit(void)
110 Enable();
113 typedef struct Task *thread_t;
115 static inline int kthread_create(void (*func)(void *), void *arg, thread_t *tdp, const char *fmt, ...)
117 va_list args;
118 char name[64];
120 va_start(args, fmt);
121 kvsnprintf(name, sizeof(name), fmt, args);
122 va_end(args);
124 name[sizeof(name)-1] = 0;
126 *tdp = NewCreateTask(TASKTAG_NAME, name,
127 TASKTAG_PC, func,
128 TASKTAG_PRI, 20,
129 TASKTAG_ARG1, arg,
130 TAG_END);
132 return (*tdp == NULL) ? ENOMEM : 0;
135 /* PCI devices */
136 typedef u_int16_t pci_vendor_id_t;
137 typedef u_int16_t pci_product_id_t;
138 typedef u_int32_t pcireg_t;
140 static inline u_int32_t pci_read_config(device_t dev, int reg, int width)
142 u_int32_t val = ~0;
143 struct AHCIBase *AHCIBase = dev->dev_AHCIBase;
144 OOP_MethodID HiddPCIDeviceMethodBase = AHCIBase->ahci_HiddPCIDeviceMethodBase;
145 struct pHidd_PCIDevice_ReadConfigByte cb;
146 struct pHidd_PCIDevice_ReadConfigWord cw;
147 struct pHidd_PCIDevice_ReadConfigLong cl;
148 OOP_Object *Device = dev->dev_Object;
150 switch (width) {
151 case 1:
152 cb.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_ReadConfigByte;
153 cb.reg = reg;
154 val = (u_int32_t)OOP_DoMethod(Device, (OOP_Msg)&cb);
155 break;
157 case 2:
158 cw.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_ReadConfigWord;
159 cw.reg = reg;
160 val = (u_int32_t)OOP_DoMethod(Device, (OOP_Msg)&cw);
161 break;
163 case 4:
164 cl.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_ReadConfigLong;
165 cl.reg = reg;
166 val = (u_int32_t)OOP_DoMethod(Device, (OOP_Msg)&cl);
167 break;
170 return val;
173 static inline void pci_write_config(device_t dev, int reg, u_int32_t val, int width)
175 struct AHCIBase *AHCIBase = dev->dev_AHCIBase;
176 OOP_MethodID HiddPCIDeviceMethodBase = AHCIBase->ahci_HiddPCIDeviceMethodBase;
177 struct pHidd_PCIDevice_WriteConfigByte cb;
178 struct pHidd_PCIDevice_WriteConfigWord cw;
179 struct pHidd_PCIDevice_WriteConfigLong cl;
180 OOP_Object *Device = dev->dev_Object;
182 switch (width) {
183 case 1:
184 cb.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_WriteConfigByte;
185 cb.reg = reg;
186 cw.val = val & 0xff;
187 OOP_DoMethod(Device, (OOP_Msg)&cb);
188 break;
190 case 2:
191 cw.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_WriteConfigWord;
192 cw.reg = reg;
193 cw.val = val & 0xffff;
194 OOP_DoMethod(Device, (OOP_Msg)&cw);
195 break;
197 case 4:
198 cl.mID = HiddPCIDeviceMethodBase + moHidd_PCIDevice_WriteConfigLong;
199 cl.reg = reg;
200 cl.val = val;
201 OOP_DoMethod(Device, (OOP_Msg)&cl);
202 break;
207 static inline u_int16_t pci_get_vendor(device_t dev)
209 return (u_int16_t)pci_read_config(dev, PCIR_VENDOR, 2);
212 static inline u_int16_t pci_get_device(device_t dev)
214 return (u_int16_t)pci_read_config(dev, PCIR_DEVICE, 2);
217 static inline u_int8_t pci_get_class(device_t dev)
219 return (u_int8_t)pci_read_config(dev, PCIR_CLASS, 1);
222 static inline u_int8_t pci_get_subclass(device_t dev)
224 return (u_int8_t)pci_read_config(dev, PCIR_SUBCLASS, 1);
227 /* DMA Types */
228 typedef IPTR bus_size_t;
229 typedef IPTR bus_addr_t;
230 typedef struct {
231 bus_addr_t ds_addr;
232 bus_size_t ds_len;
233 } bus_dma_segment_t;
235 struct bus_dma_tag;
236 typedef struct bus_dma_tag *bus_dma_tag_t;
238 #define BUS_DMA_MAX_SLABS 16
239 #define BUS_DMA_MAX_SEGMENTS 1024
241 typedef IPTR bus_space_tag_t;
242 typedef APTR bus_dmamap_t;
243 typedef IPTR bus_space_handle_t;
244 typedef int bus_dma_filter_t(void *arg, bus_addr_t paddr);
246 #define BUS_SPACE_MAXADDR ~0
247 #define BUS_SPACE_MAXADDR_32BIT ((ULONG)~0)
249 int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, bus_size_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr, bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize, int nsegments, bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat);
251 int bus_dma_tag_destroy(bus_dma_tag_t tag);
253 #define BUS_DMA_ALLOCNOW 0
254 #define BUS_DMA_ZERO MEMF_CLEAR
256 int bus_dmamem_alloc(bus_dma_tag_t tag, void **vaddr, unsigned flags, bus_dmamap_t *map);
258 bus_size_t bus_dma_tag_getmaxsize(bus_dma_tag_t tag);
260 void bus_dmamem_free(bus_dma_tag_t tag, void *vaddr, bus_dmamap_t map);
262 int bus_dmamap_create(bus_dma_tag_t tag, unsigned flags, bus_dmamap_t *map);
264 void bus_dmamap_destroy(bus_dma_tag_t tag, bus_dmamap_t map);
266 typedef void bus_dmamap_callback_t(void *info, bus_dma_segment_t *segs, int nsegs, int error);
268 #define BUS_DMA_NOWAIT 0
269 #define BUS_DMA_WAITOK 0
271 int bus_dmamap_load(bus_dma_tag_t tag, bus_dmamap_t map, void *data, size_t len, bus_dmamap_callback_t *callback, void *info, unsigned flags);
273 #define BUS_DMASYNC_PREREAD 0
274 #define BUS_DMASYNC_PREWRITE DMA_ReadFromRAM
275 #define BUS_DMASYNC_POSTREAD (1 << 31)
276 #define BUS_DMASYNC_POSTWRITE (1 << 31) | DMA_ReadFromRAM
278 void bus_dmamap_sync(bus_dma_tag_t tag, bus_dmamap_t map, unsigned flags);
280 void bus_dmamap_unload(bus_dma_tag_t tag, bus_dmamap_t map);
282 /* Generic bus operations */
283 enum bus_resource_t {
284 SYS_RES_IRQ = 0,
285 SYS_RES_MEMORY = 1,
288 #define AHCI_IRQ_RID 0
290 struct resource {
291 bus_space_tag_t res_tag;
292 bus_space_handle_t res_handle;
293 ULONG res_size;
296 #define RF_SHAREABLE (1 << 0)
297 #define RF_ACTIVE (1 << 1)
299 struct resource *bus_alloc_resource_any(device_t dev, enum bus_resource_t type, int *rid, u_int flags);
301 int bus_release_resource(device_t dev, enum bus_resource_t type, int rid, struct resource *res);
303 static inline bus_space_tag_t rman_get_bustag(struct resource *r)
305 return r->res_tag;
308 static inline bus_space_handle_t rman_get_bushandle(struct resource *r)
310 return r->res_handle;
313 /* Bus IRQ */
314 typedef void driver_intr_t(void *arg);
316 #define INTR_MPSAFE 0
318 int bus_setup_intr(device_t dev, struct resource *r, int flags, driver_intr_t handler, void *arg, void **cookiep, void *serializer);
320 int bus_teardown_intr(device_t dev, struct resource *r, void *cookie);
322 /* Bus IO */
324 static inline int bus_space_subregion(bus_space_tag_t iot, bus_space_handle_t ioh, unsigned offset, size_t size, bus_space_handle_t *result)
326 *result = ioh + offset;
327 return 0;
330 #define BUS_SPACE_BARRIER_READ 0
331 #define BUS_SPACE_BARRIER_WRITE 0
333 static inline void bus_space_barrier(bus_space_tag_t iot, bus_space_handle_t ioh, unsigned offset, size_t size, unsigned flags)
335 /* FIXME: Sync bus area */
338 static inline u_int32_t bus_space_read_4(bus_space_tag_t iot, bus_space_handle_t ioh, unsigned offset)
340 return *(u_int32_t *)(ioh + offset);
343 static inline void bus_space_write_4(bus_space_tag_t iot, bus_space_handle_t ioh, unsigned offset, u_int32_t val)
345 *(u_int32_t *)(ioh + offset) = val;
349 /* Generic device info */
350 static inline void *device_get_softc(device_t dev)
352 return dev->dev_softc;
355 /* Lock management */
357 struct lock {
358 struct SignalSemaphore sem;
359 const char *name;
362 static inline void lockinit(struct lock *lock, const char *name, unsigned flags, unsigned count)
364 lock->name = name;
365 InitSemaphore(&lock->sem);
368 static inline void lockuninit(struct lock *lock)
370 /* Nothing needed */
373 #define LK_RELEASE (1 << 0)
374 #define LK_EXCLUSIVE (1 << 1)
375 #define LK_CANRECURSE (1 << 2)
376 #define LK_NOWAIT (1 << 3)
378 static inline int lockmgr(struct lock *lock, int flags)
380 int err = 0;
382 flags &= (LK_EXCLUSIVE | LK_NOWAIT | LK_RELEASE);
383 switch (flags) {
384 case 0:
385 ObtainSemaphoreShared(&lock->sem);
386 break;
387 case LK_EXCLUSIVE | LK_NOWAIT:
388 err = (AttemptSemaphore(&lock->sem) == FALSE) ? 1 : 0;
389 break;
390 case LK_EXCLUSIVE:
391 ObtainSemaphore(&lock->sem);
392 break;
393 case LK_RELEASE:
394 ReleaseSemaphore(&lock->sem);
395 break;
398 return err;
401 /* Events */
402 #define atomic_clear_int(ptr, val) AROS_ATOMIC_AND(*(ptr), ~(val))
403 #define atomic_set_int(ptr, val) AROS_ATOMIC_OR(*(ptr), (val))
405 /* Callouts */
407 static const int hz = (1000000 / 2); /* UNIT_MICROHZ frequency */
409 typedef void timeout_t (void *);
411 struct callout {
412 struct Task *co_Task;
415 void callout_init_mp(struct callout *c);
417 void callout_init(struct callout *c);
419 void callout_stop(struct callout *c);
421 void callout_stop_sync(struct callout *c);
423 int callout_reset(struct callout *c, unsigned int ticks, void (*func)(void *), void *arg);
425 struct sysctl_ctx_list {};
427 /* BSD style TailQs */
428 #define TAILQ_HEAD(sname,type) struct sname { struct type *tqh_first; struct type **tqh_last; }
429 #define TAILQ_ENTRY(type) struct { struct type *tqe_next; struct type **tqe_prev; }
430 #define TAILQ_FIRST(head) ((head)->tqh_first)
431 #define TAILQ_EMPTY(head) (TAILQ_FIRST(head) == NULL)
432 #define TAILQ_INIT(head) do { \
433 (head)->tqh_first = NULL; \
434 (head)->tqh_last = &(head)->tqh_first; \
435 } while (0)
436 #define TAILQ_NEXT(elm,field) ((elm)->field.tqe_next)
437 #define TAILQ_REMOVE(head,elm,field) do { \
438 if ((elm)->field.tqe_next) \
439 (elm)->field.tqe_next->field.tqe_prev = (elm)->field.tqe_prev; \
440 else \
441 (head)->tqh_last = (elm)->field.tqe_prev; \
442 *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
443 } while (0)
444 #define TAILQ_INSERT_TAIL(head,elm,field) do { \
445 (elm)->field.tqe_next = NULL; \
446 (elm)->field.tqe_prev = (head)->tqh_last; \
447 *(head)->tqh_last = (elm); \
448 (head)->tqh_last = &(elm)->field.tqe_next; \
449 } while (0)
450 #define TAILQ_FOREACH(elm,head,field) \
451 for ((elm) = ((head)->tqh_first); \
452 (elm) != NULL; (elm)=(elm)->field.tqe_next)
454 #define device_get_name(dev) "ahci.device "
455 #define device_get_unit(dev) ((dev)->dev_HostID)
457 #define M_DEVBUF 0
458 #define M_TEMP 0
459 #define M_WAITOK 0
460 #define M_INTWAIT 0
461 #define M_ZERO MEMF_CLEAR
463 static const int bootverbose = 0;
465 /* Bit operations */
466 static inline int ffs(unsigned int bits)
468 int i;
470 for (i = 0; i < 32; i++, bits >>= 1)
471 if (bits & 1)
472 return (i+1);
474 return 0;
477 struct ata_xfer;
478 void ahci_ata_io_complete(struct ata_xfer *xa);
480 #endif /* AHCI_AROS_H */