4 * Copyright (C) 2004 Jens Axboe <axboe@suse.de>
5 * Copyright (C) 2005 Stefan Reinauer <stepan@openbios.org>
7 * Credit goes to Hale Landis for his excellent ata demo software
8 * OF node handling and some fixes by Stefan Reinauer
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
17 #include "libopenbios/bindings.h"
18 #include "kernel/kernel.h"
19 #include "libc/byteorder.h"
20 #include "libc/vsprintf.h"
22 #include "drivers/drivers.h"
27 #include "libopenbios/ofmem.h"
31 #ifdef CONFIG_DEBUG_ESP
32 #define DPRINTF(fmt, args...) \
33 do { printk(fmt , ##args); } while (0)
35 #define DPRINTF(fmt, args...)
39 volatile struct sparc_dma_registers
*regs
;
40 enum dvma_rev revision
;
43 typedef struct sd_private
{
45 const char *media_str
[2];
54 unsigned char regs
[ESP_REG_SIZE
];
57 typedef struct esp_private
{
58 volatile struct esp_regs
*ll
;
60 unsigned int irq
; /* device IRQ number */
61 struct esp_dma espdma
;
62 unsigned char *buffer
;
66 static esp_private_t
*global_esp
;
68 /* DECLARE data structures for the nodes. */
69 DECLARE_UNNAMED_NODE(ob_sd
, INSTALL_OPEN
, sizeof(sd_private_t
*));
70 DECLARE_UNNAMED_NODE(ob_esp
, INSTALL_OPEN
, sizeof(esp_private_t
*));
72 #ifdef CONFIG_DEBUG_ESP
73 static void dump_drive(sd_private_t
*drive
)
75 printk("SCSI DRIVE @%lx:\n", (unsigned long)drive
);
76 printk("id: %d\n", drive
->id
);
77 printk("media: %s\n", drive
->media_str
[0]);
78 printk("media: %s\n", drive
->media_str
[1]);
79 printk("model: %s\n", drive
->model
);
80 printk("sectors: %d\n", drive
->sectors
);
81 printk("present: %d\n", drive
->present
);
82 printk("bs: %d\n", drive
->bs
);
87 do_command(esp_private_t
*esp
, sd_private_t
*sd
, int cmdlen
, int replylen
)
92 esp
->ll
->regs
[ESP_BUSID
] = sd
->id
& 7;
94 esp
->espdma
.regs
->st_addr
= esp
->buffer_dvma
;
96 esp
->ll
->regs
[ESP_TCLOW
] = cmdlen
& 0xff;
97 esp
->ll
->regs
[ESP_TCMED
] = (cmdlen
>> 8) & 0xff;
98 // Set DMA direction and enable DMA
99 esp
->espdma
.regs
->cond_reg
= DMA_ENABLE
;
100 // Set ATN, issue command
101 esp
->ll
->regs
[ESP_CMD
] = ESP_CMD_SELA
| ESP_CMD_DMA
;
102 // Wait for DMA to complete. Can this fail?
103 while ((esp
->espdma
.regs
->cond_reg
& DMA_HNDL_INTR
) == 0) /* no-op */;
105 status
= esp
->ll
->regs
[ESP_STATUS
];
106 // Clear interrupts to avoid guests seeing spurious interrupts
107 (void)esp
->ll
->regs
[ESP_INTRPT
];
109 DPRINTF("do_command: id %d, cmd[0] 0x%x, status 0x%x\n", sd
->id
, esp
->buffer
[0], status
);
111 // Target didn't want all command data or went to status phase
112 // instead of data phase?
113 if ((status
& ESP_STAT_TCNT
) != ESP_STAT_TCNT
114 || (status
& ESP_STAT_PMASK
) == ESP_STATP
)
119 esp
->espdma
.regs
->st_addr
= esp
->buffer_dvma
;
121 esp
->ll
->regs
[ESP_TCLOW
] = replylen
& 0xff;
122 esp
->ll
->regs
[ESP_TCMED
] = (replylen
>> 8) & 0xff;
124 esp
->espdma
.regs
->cond_reg
= DMA_ST_WRITE
| DMA_ENABLE
;
126 esp
->ll
->regs
[ESP_CMD
] = ESP_CMD_TI
| ESP_CMD_DMA
;
127 // Wait for DMA to complete
128 while ((esp
->espdma
.regs
->cond_reg
& DMA_HNDL_INTR
) == 0) /* no-op */;
130 status
= esp
->ll
->regs
[ESP_STATUS
];
131 // Clear interrupts to avoid guests seeing spurious interrupts
132 (void)esp
->ll
->regs
[ESP_INTRPT
];
134 DPRINTF("do_command_reply: status 0x%x\n", status
);
136 if ((status
& ESP_STAT_TCNT
) != ESP_STAT_TCNT
)
142 // offset is in sectors
144 ob_sd_read_sector(esp_private_t
*esp
, sd_private_t
*sd
, int offset
)
146 DPRINTF("ob_sd_read_sector id %d sector=%d\n",
149 // Setup command = Read(10)
150 memset(esp
->buffer
, 0, 10);
151 esp
->buffer
[0] = 0x80;
152 esp
->buffer
[1] = READ_10
;
154 esp
->buffer
[3] = (offset
>> 24) & 0xff;
155 esp
->buffer
[4] = (offset
>> 16) & 0xff;
156 esp
->buffer
[5] = (offset
>> 8) & 0xff;
157 esp
->buffer
[6] = offset
& 0xff;
162 if (do_command(esp
, sd
, 10, sd
->bs
))
169 read_capacity(esp_private_t
*esp
, sd_private_t
*sd
)
171 // Setup command = Read Capacity
172 memset(esp
->buffer
, 0, 11);
173 esp
->buffer
[0] = 0x80;
174 esp
->buffer
[1] = READ_CAPACITY
;
176 if (do_command(esp
, sd
, 11, 8)) {
182 sd
->bs
= (esp
->buffer
[4] << 24) | (esp
->buffer
[5] << 16) | (esp
->buffer
[6] << 8) | esp
->buffer
[7];
183 sd
->sectors
= ((esp
->buffer
[0] << 24) | (esp
->buffer
[1] << 16) | (esp
->buffer
[2] << 8) | esp
->buffer
[3]) * (sd
->bs
/ 512);
189 inquiry(esp_private_t
*esp
, sd_private_t
*sd
)
191 const char *media
[2] = { "UNKNOWN", "UNKNOWN"};
193 // Setup command = Inquiry
194 memset(esp
->buffer
, 0, 7);
195 esp
->buffer
[0] = 0x80;
196 esp
->buffer
[1] = INQUIRY
;
200 if (do_command(esp
, sd
, 7, 36)) {
206 sd
->media
= esp
->buffer
[0];
218 sd
->media_str
[0] = media
[0];
219 sd
->media_str
[1] = media
[1];
220 memcpy(sd
->model
, &esp
->buffer
[16], 16);
221 sd
->model
[17] = '\0';
228 ob_sd_read_blocks(sd_private_t
**sd
)
230 cell n
= POP(), cnt
= n
;
232 char *dest
= (char*)POP();
233 int pos
, spb
, sect_offset
;
235 DPRINTF("ob_sd_read_blocks id %d %lx block=%d n=%d\n", (*sd
)->id
, (unsigned long)dest
, blk
, n
);
237 spb
= (*sd
)->bs
/ 512;
239 sect_offset
= blk
/ spb
;
240 pos
= (blk
- sect_offset
* spb
) * 512;
242 if (ob_sd_read_sector(global_esp
, *sd
, sect_offset
)) {
243 DPRINTF("ob_sd_read_blocks: error\n");
246 while (n
&& pos
< spb
* 512) {
247 memcpy(dest
, global_esp
->buffer
+ pos
, 512);
258 ob_sd_block_size(__attribute__((unused
))sd_private_t
**sd
)
264 ob_sd_open(__attribute__((unused
))sd_private_t
**sd
)
271 POP(); // unit id is 2 ints but we only need one.
272 *sd
= &global_esp
->sd
[id
];
274 #ifdef CONFIG_DEBUG_ESP
279 args
= pop_fstr_copy();
280 DPRINTF("opening drive %d args %s\n", id
, args
);
285 selfword("open-deblocker");
287 /* interpose disk-label */
288 ph
= find_dev("/packages/disk-label");
297 ob_sd_close(__attribute__((unused
)) sd_private_t
**sd
)
299 selfword("close-deblocker");
302 NODE_METHODS(ob_sd
) = {
303 { "open", ob_sd_open
},
304 { "close", ob_sd_close
},
305 { "read-blocks", ob_sd_read_blocks
},
306 { "block-size", ob_sd_block_size
},
311 espdma_init(unsigned int slot
, uint64_t base
, unsigned long offset
,
312 struct esp_dma
*espdma
)
314 espdma
->regs
= (void *)ofmem_map_io(base
+ (uint64_t)offset
, 0x10);
316 if (espdma
->regs
== NULL
) {
317 DPRINTF("espdma_init: cannot map registers\n");
323 switch ((espdma
->regs
->cond_reg
) & DMA_DEVICE_ID
) {
325 espdma
->revision
= dvmarev0
;
326 DPRINTF("Revision 0 ");
329 espdma
->revision
= dvmaesc1
;
330 DPRINTF("ESC Revision 1 ");
333 espdma
->revision
= dvmarev1
;
334 DPRINTF("Revision 1 ");
337 espdma
->revision
= dvmarev2
;
338 DPRINTF("Revision 2 ");
341 espdma
->revision
= dvmahme
;
342 DPRINTF("HME DVMA gate array ");
345 espdma
->revision
= dvmarevplus
;
346 DPRINTF("Revision 1 PLUS ");
349 DPRINTF("unknown dma version %x",
350 (espdma
->regs
->cond_reg
) & DMA_DEVICE_ID
);
351 /* espdma->allocated = 1; */
356 push_str("/iommu/sbus/espdma");
357 fword("find-device");
375 ob_esp_initialize(__attribute__((unused
)) esp_private_t
**esp
)
377 phandle_t ph
= get_cur_dev();
379 set_int_property(ph
, "#address-cells", 2);
380 set_int_property(ph
, "#size-cells", 0);
382 /* set device type */
384 fword("device-type");
396 ob_esp_decodeunit(__attribute__((unused
)) esp_private_t
**esp
)
398 fword("decode-unit-scsi");
403 ob_esp_encodeunit(__attribute__((unused
)) esp_private_t
**esp
)
405 fword("encode-unit-scsi");
408 NODE_METHODS(ob_esp
) = {
409 { NULL
, ob_esp_initialize
},
410 { "decode-unit", ob_esp_decodeunit
},
411 { "encode-unit", ob_esp_encodeunit
},
415 add_alias(const char *device
, const char *alias
)
417 DPRINTF("add_alias dev \"%s\" = alias \"%s\"\n", device
, alias
);
418 push_str("/aliases");
419 fword("find-device");
421 fword("encode-string");
427 ob_esp_init(unsigned int slot
, uint64_t base
, unsigned long espoffset
,
428 unsigned long dmaoffset
)
430 int id
, diskcount
= 0, cdcount
= 0, *counter_ptr
;
431 char nodebuff
[256], aliasbuff
[256];
434 DPRINTF("Initializing SCSI...");
436 esp
= malloc(sizeof(esp_private_t
));
438 DPRINTF("Can't allocate ESP private structure\n");
444 if (espdma_init(slot
, base
, dmaoffset
, &esp
->espdma
) != 0) {
447 /* Get the IO region */
448 esp
->ll
= (void *)ofmem_map_io(base
+ (uint64_t)espoffset
,
449 sizeof(struct esp_regs
));
450 if (esp
->ll
== NULL
) {
451 DPRINTF("Can't map ESP registers\n");
455 esp
->buffer
= (void *)dvma_alloc(BUFSIZE
, &esp
->buffer_dvma
);
456 if (!esp
->buffer
|| !esp
->buffer_dvma
) {
457 DPRINTF("Can't get a DVMA buffer\n");
462 esp
->ll
->regs
[ESP_CMD
] = ESP_CMD_RC
;
464 DPRINTF("ESP at 0x%lx, buffer va 0x%lx dva 0x%lx\n", (unsigned long)esp
,
465 (unsigned long)esp
->buffer
, (unsigned long)esp
->buffer_dvma
);
467 DPRINTF("Initializing SCSI devices...");
469 for (id
= 0; id
< 8; id
++) {
471 if (!inquiry(esp
, &esp
->sd
[id
]))
473 read_capacity(esp
, &esp
->sd
[id
]);
475 #ifdef CONFIG_DEBUG_ESP
476 dump_drive(&esp
->sd
[id
]);
480 REGISTER_NAMED_NODE(ob_esp
, "/iommu/sbus/espdma/esp");
483 push_str("/iommu/sbus/espdma/esp");
484 fword("find-device");
498 push_str("clock-frequency");
501 for (id
= 0; id
< 8; id
++) {
502 if (!esp
->sd
[id
].present
)
504 push_str("/iommu/sbus/espdma/esp");
505 fword("find-device");
508 fword("device-name");
510 fword("device-type");
511 fword("is-deblocker");
519 fword("finish-device");
520 snprintf(nodebuff
, sizeof(nodebuff
), "/iommu/sbus/espdma/esp/sd@%d,0",
522 REGISTER_NODE_METHODS(ob_sd
, nodebuff
);
523 if (esp
->sd
[id
].media
== TYPE_ROM
) {
524 counter_ptr
= &cdcount
;
526 counter_ptr
= &diskcount
;
528 if (*counter_ptr
== 0) {
529 add_alias(nodebuff
, esp
->sd
[id
].media_str
[0]);
530 add_alias(nodebuff
, esp
->sd
[id
].media_str
[1]);
532 snprintf(aliasbuff
, sizeof(aliasbuff
), "%s%d",
533 esp
->sd
[id
].media_str
[0], *counter_ptr
);
534 add_alias(nodebuff
, aliasbuff
);
535 snprintf(aliasbuff
, sizeof(aliasbuff
), "%s%d",
536 esp
->sd
[id
].media_str
[1], *counter_ptr
);
537 add_alias(nodebuff
, aliasbuff
);
538 snprintf(aliasbuff
, sizeof(aliasbuff
), "sd(0,%d,0)", id
);
539 add_alias(nodebuff
, aliasbuff
);
540 snprintf(aliasbuff
, sizeof(aliasbuff
), "sd(0,%d,0)@0,0", id
);
541 add_alias(nodebuff
, aliasbuff
);