|
@@ -9,8 +9,9 @@
|
|
|
#include "irq.h"
|
|
|
#include "abcio.h"
|
|
|
|
|
|
-struct abc_dev *abc_device[64];
|
|
|
+static struct abc_dev *abc_device[64];
|
|
|
static struct abc_dev *selected_dev;
|
|
|
+static uint8_t abc_devsel = -1;
|
|
|
|
|
|
static inline void abc_select(struct abc_dev *dev)
|
|
|
{
|
|
@@ -52,7 +53,7 @@ IRQHANDLER(abc)
|
|
|
|
|
|
case 1:
|
|
|
{
|
|
|
- struct abc_dev *dev = abc_device[data & 0x3f];
|
|
|
+ struct abc_dev *dev = abc_device[abc_devsel = data & 0x3f];
|
|
|
abc_select(dev);
|
|
|
|
|
|
if (dev)
|
|
@@ -62,6 +63,7 @@ IRQHANDLER(abc)
|
|
|
|
|
|
case 7:
|
|
|
/* XXX: broadcast reset to devices? */
|
|
|
+ abc_devsel = -1;
|
|
|
abc_select(NULL);
|
|
|
break;
|
|
|
|
|
@@ -92,3 +94,44 @@ IRQHANDLER(abc)
|
|
|
|
|
|
ABC_BUSY_STATUS = what;
|
|
|
}
|
|
|
+
|
|
|
+void abc_setup_out_queue(struct abc_dev *dev, void *buf, size_t len,
|
|
|
+ uint8_t status, uint8_t status_first_mask)
|
|
|
+{
|
|
|
+ mask_irq(ABC_IRQ);
|
|
|
+
|
|
|
+ dev->status_first_out_mask = status_first_mask;
|
|
|
+ dev->out_buf = buf;
|
|
|
+ dev->out_cnt = len;
|
|
|
+ ABC_INP1_DATA = dev->inp_data[1] = status;
|
|
|
+
|
|
|
+ unmask_irq(ABC_IRQ);
|
|
|
+}
|
|
|
+
|
|
|
+void abc_setup_inp_queue(struct abc_dev *dev, const void *buf, size_t len,
|
|
|
+ uint8_t status, uint8_t status_first_mask)
|
|
|
+{
|
|
|
+ mask_irq(ABC_IRQ);
|
|
|
+
|
|
|
+ dev->status_first_inp_mask = status_first_mask;
|
|
|
+ dev->inp_buf = buf;
|
|
|
+ dev->inp_cnt = len;
|
|
|
+ ABC_INP0_DATA = *dev->inp_buf++;
|
|
|
+ ABC_INP1_DATA = dev->inp_data[1] = status;
|
|
|
+
|
|
|
+ unmask_irq(ABC_IRQ);
|
|
|
+}
|
|
|
+
|
|
|
+void abc_register(struct abc_dev *dev, unsigned int devsel)
|
|
|
+{
|
|
|
+ if (devsel > 63)
|
|
|
+ return;
|
|
|
+
|
|
|
+ mask_irq(ABC_IRQ);
|
|
|
+
|
|
|
+ abc_device[devsel] = dev;
|
|
|
+ if (devsel == abc_devsel)
|
|
|
+ abc_select(dev);
|
|
|
+
|
|
|
+ unmask_irq(ABC_IRQ);
|
|
|
+}
|