summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linux')
-rw-r--r--linux/Makefrag.am13
-rw-r--r--linux/dev/arch/i386/kernel/irq.c2
-rw-r--r--linux/dev/drivers/block/ahci.c1009
-rw-r--r--linux/dev/drivers/block/floppy.c2
-rw-r--r--linux/dev/drivers/block/genhd.c26
-rw-r--r--linux/dev/glue/block.c20
-rw-r--r--linux/dev/glue/kmem.c6
-rw-r--r--linux/dev/include/ahci.h268
-rw-r--r--linux/dev/include/asm-i386/string.h36
-rw-r--r--linux/dev/include/linux/blk.h5
-rw-r--r--linux/dev/include/linux/blkdev.h1
-rw-r--r--linux/dev/include/linux/fs.h4
-rw-r--r--linux/dev/include/linux/mm.h1
-rw-r--r--linux/dev/include/linux/types.h9
-rw-r--r--linux/pcmcia-cs/clients/axnet_cs.c2
-rw-r--r--linux/src/drivers/block/ide-cd.c51
-rw-r--r--linux/src/drivers/block/ide.c26
-rw-r--r--linux/src/drivers/block/ide.h1
-rw-r--r--linux/src/drivers/net/3c507.c4
-rw-r--r--linux/src/drivers/net/3c509.c2
-rw-r--r--linux/src/drivers/net/3c515.c4
-rw-r--r--linux/src/drivers/net/ac3200.c2
-rw-r--r--linux/src/drivers/net/apricot.c2
-rw-r--r--linux/src/drivers/net/at1700.c2
-rw-r--r--linux/src/drivers/net/de4x5.c2
-rw-r--r--linux/src/drivers/net/de600.c2
-rw-r--r--linux/src/drivers/net/de620.c2
-rw-r--r--linux/src/drivers/net/depca.c2
-rw-r--r--linux/src/drivers/net/e2100.c2
-rw-r--r--linux/src/drivers/net/eepro.c2
-rw-r--r--linux/src/drivers/net/eepro100.c2
-rw-r--r--linux/src/drivers/net/eexpress.c2
-rw-r--r--linux/src/drivers/net/ewrk3.c2
-rw-r--r--linux/src/drivers/net/fmv18x.c2
-rw-r--r--linux/src/drivers/net/hp-plus.c2
-rw-r--r--linux/src/drivers/net/hp.c2
-rw-r--r--linux/src/drivers/net/lance.c2
-rw-r--r--linux/src/drivers/net/ne.c2
-rw-r--r--linux/src/drivers/net/pci-scan.c2
-rw-r--r--linux/src/drivers/net/pcnet32.c2
-rw-r--r--linux/src/drivers/net/seeq8005.c2
-rw-r--r--linux/src/drivers/net/smc-ultra.c2
-rw-r--r--linux/src/drivers/net/smc-ultra32.c2
-rw-r--r--linux/src/drivers/net/sundance.c2
-rw-r--r--linux/src/drivers/net/tlan.c4
-rw-r--r--linux/src/drivers/net/wd.c2
-rw-r--r--linux/src/drivers/scsi/AM53C974.c2
-rw-r--r--linux/src/drivers/scsi/FlashPoint.c14
-rw-r--r--linux/src/drivers/scsi/NCR5380.c4
-rw-r--r--linux/src/drivers/scsi/t128.c4
-rw-r--r--linux/src/include/asm-i386/bitops.h28
-rw-r--r--linux/src/include/asm-i386/io.h12
-rw-r--r--linux/src/include/asm-i386/segment.h8
-rw-r--r--linux/src/include/asm-i386/semaphore.h30
-rw-r--r--linux/src/include/linux/compiler-gcc5.h67
-rw-r--r--linux/src/include/linux/hdreg.h9
-rw-r--r--linux/src/include/linux/pci.h2
-rw-r--r--linux/src/include/linux/string.h8
58 files changed, 1594 insertions, 138 deletions
diff --git a/linux/Makefrag.am b/linux/Makefrag.am
index 7c7b432d..1b690108 100644
--- a/linux/Makefrag.am
+++ b/linux/Makefrag.am
@@ -36,6 +36,11 @@ liblinux_a_CPPFLAGS = $(AM_CPPFLAGS) \
# Because of the use of `extern inline' in some Linux header files without
# corresponding text segment definitions, we must always optimize.
liblinux_a_CFLAGS = -O2 $(AM_CFLAGS)
+
+# See <http://lists.gnu.org/archive/html/bug-hurd/2006-01/msg00148.html>.
+liblinux_a_CFLAGS += \
+ -fno-strict-aliasing
+
# TODO. Do we really need `-traditional'?
liblinux_a_CCASFLAGS = $(AM_CCASFLAGS) \
-D__ASSEMBLY__ -traditional \
@@ -78,6 +83,8 @@ liblinux_a_SOURCES += \
linux/src/drivers/block/ide-cd.c \
linux/src/drivers/block/ide.c \
linux/src/drivers/block/ide.h \
+ linux/dev/drivers/block/ahci.c \
+ linux/dev/include/ahci.h \
linux/src/drivers/block/ide_modes.h \
linux/src/drivers/block/rz1000.c \
linux/src/drivers/block/triton.c
@@ -747,6 +754,12 @@ EXTRA_DIST += \
linux/dev/README \
linux/src/COPYING
+# Those get #included...
+EXTRA_DIST += \
+ linux/src/drivers/scsi/FlashPoint.c \
+ linux/src/drivers/scsi/eata_pio_proc.c \
+ linux/src/drivers/scsi/scsiiom.c
+
# Instead of listing each file individually...
EXTRA_DIST += \
linux/dev/include \
diff --git a/linux/dev/arch/i386/kernel/irq.c b/linux/dev/arch/i386/kernel/irq.c
index 68bf0c4b..7753814b 100644
--- a/linux/dev/arch/i386/kernel/irq.c
+++ b/linux/dev/arch/i386/kernel/irq.c
@@ -695,7 +695,7 @@ init_IRQ (void)
* Program counter 0 of 8253 to interrupt hz times per second.
*/
outb_p (PIT_C0 | PIT_SQUAREMODE | PIT_READMODE, PITCTL_PORT);
- outb_p (latch && 0xff, PITCTR0_PORT);
+ outb_p (latch & 0xff, PITCTR0_PORT);
outb (latch >> 8, PITCTR0_PORT);
/*
diff --git a/linux/dev/drivers/block/ahci.c b/linux/dev/drivers/block/ahci.c
new file mode 100644
index 00000000..9bb2e6b4
--- /dev/null
+++ b/linux/dev/drivers/block/ahci.c
@@ -0,0 +1,1009 @@
+/*
+ * Copyright (C) 2013 Free Software Foundation
+ *
+ * This program is free software ; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation ; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY ; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with the program ; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <ahci.h>
+#include <kern/assert.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include <linux/bios32.h>
+#include <linux/major.h>
+#include <linux/hdreg.h>
+#include <linux/genhd.h>
+#include <asm/io.h>
+
+#define MAJOR_NR SCSI_DISK_MAJOR
+#include <linux/blk.h>
+
+/* Standard AHCI BAR for mmio */
+#define AHCI_PCI_BAR 5
+
+/* minor: 2 bits for device number, 6 bits for partition number. */
+
+#define MAX_PORTS 8
+#define PARTN_BITS 5
+#define PARTN_MASK ((1<<PARTN_BITS)-1)
+
+/* We need to use one DMA scatter element per physical page.
+ * ll_rw_block creates at most 8 buffer heads */
+/* See MAX_BUF */
+#define PRDTL_SIZE 8
+
+#define WAIT_MAX (1*HZ) /* Wait at most 1s for requests completion */
+
+/* AHCI standard structures */
+
+struct ahci_prdt {
+ u32 dba; /* Data base address */
+ u32 dbau; /* upper 32bit */
+ u32 rsv0; /* Reserved */
+
+ u32 dbc; /* Byte count bits 0-21,
+ * bit31 interrupt on completion. */
+};
+
+struct ahci_cmd_tbl {
+ u8 cfis[64];
+ u8 acmd[16];
+ u8 rsv[48];
+
+ struct ahci_prdt prdtl[PRDTL_SIZE];
+};
+
+struct ahci_command {
+ u32 opts; /* Command options */
+
+ u32 prdbc; /* Physical Region Descriptor byte count */
+
+ u32 ctba; /* Command Table Descriptor Base Address */
+ u32 ctbau; /* upper 32bit */
+
+ u32 rsv1[4]; /* Reserved */
+};
+
+struct ahci_fis_dma {
+ u8 fis_type;
+ u8 flags;
+ u8 rsved[2];
+ u64 id;
+ u32 rsvd;
+ u32 offset;
+ u32 count;
+ u32 resvd;
+};
+
+struct ahci_fis_pio {
+ u8 fis_type;
+ u8 flags;
+ u8 status;
+ u8 error;
+
+ u8 lba0;
+ u8 lba1;
+ u8 lba2;
+ u8 device;
+
+ u8 lba3;
+ u8 lba4;
+ u8 lba5;
+ u8 rsv2;
+
+ u8 countl;
+ u8 counth;
+ u8 rsv3;
+ u8 e_status;
+
+ u16 tc; /* Transfer Count */
+ u8 rsv4[2];
+};
+
+struct ahci_fis_d2h {
+ u8 fis_type;
+ u8 flags;
+ u8 status;
+ u8 error;
+
+ u8 lba0;
+ u8 lba1;
+ u8 lba2;
+ u8 device;
+
+ u8 lba3;
+ u8 lba4;
+ u8 lba5;
+ u8 rsv2;
+
+ u8 countl;
+ u8 counth;
+ u8 rsv3[2];
+
+ u8 rsv4[4];
+};
+
+struct ahci_fis_dev {
+ u8 rsvd[8];
+};
+
+struct ahci_fis_h2d {
+ u8 fis_type;
+ u8 flags;
+ u8 command;
+ u8 featurel;
+
+ u8 lba0;
+ u8 lba1;
+ u8 lba2;
+ u8 device;
+
+ u8 lba3;
+ u8 lba4;
+ u8 lba5;
+ u8 featureh;
+
+ u8 countl;
+ u8 counth;
+ u8 icc;
+ u8 control;
+
+ u8 rsv1[4];
+};
+
+struct ahci_fis_data {
+ u8 fis_type;
+ u8 flags;
+ u8 rsv1[2];
+ u32 data1[];
+};
+
+struct ahci_fis {
+ struct ahci_fis_dma dma_fis;
+ u8 pad0[4];
+
+ struct ahci_fis_pio pio_fis;
+ u8 pad1[12];
+
+ struct ahci_fis_d2h d2h_fis;
+ u8 pad2[4];
+
+ struct ahci_fis_dev dev_fis;
+
+ u8 ufis[64];
+
+ u8 rsv[0x100 - 0xa0];
+};
+
+struct ahci_port {
+ u32 clb; /* Command List Base address */
+ u32 clbu; /* upper 32bit */
+ u32 fb; /* FIS Base */
+ u32 fbu; /* upper 32bit */
+ u32 is; /* Interrupt Status */
+ u32 ie; /* Interrupt Enable */
+ u32 cmd; /* Command and Status */
+ u32 rsv0; /* Reserved */
+ u32 tfd; /* Task File Data */
+ u32 sig; /* Signature */
+ u32 ssts; /* SATA Status */
+ u32 sctl; /* SATA Control */
+ u32 serr; /* SATA Error */
+ u32 sact; /* SATA Active */
+ u32 ci; /* Command Issue */
+ u32 sntf; /* SATA Notification */
+ u32 fbs; /* FIS-based switch control */
+ u8 rsv1[0x70 - 0x44]; /* Reserved */
+ u8 vendor[0x80 - 0x70]; /* Vendor-specific */
+};
+
+struct ahci_host {
+ u32 cap; /* Host capabilities */
+ u32 ghc; /* Global Host Control */
+ u32 is; /* Interrupt Status */
+ u32 pi; /* Port Implemented */
+ u32 v; /* Version */
+ u32 ccc_ctl; /* Command Completion Coalescing control */
+ u32 ccc_pts; /* Command Completion Coalescing ports */
+ u32 em_loc; /* Enclosure Management location */
+ u32 em_ctrl; /* Enclosure Management control */
+ u32 cap2; /* Host capabilities extended */
+ u32 bohc; /* BIOS/OS Handoff Control and status */
+ u8 rsv[0xa0 - 0x2c]; /* Reserved */
+ u8 vendor[0x100 - 0xa0]; /* Vendor-specific */
+ struct ahci_port ports[]; /* Up to 32 ports */
+};
+
+/* Our own data */
+
+static struct port {
+ /* memory-mapped regions */
+ const volatile struct ahci_host *ahci_host;
+ const volatile struct ahci_port *ahci_port;
+
+ /* host-memory buffers */
+ struct ahci_command *command;
+ struct ahci_fis *fis;
+ struct ahci_cmd_tbl *prdtl;
+
+ struct hd_driveid id;
+ unsigned is_cd;
+ unsigned long long capacity; /* Nr of sectors */
+ u32 status; /* interrupt status */
+ unsigned cls; /* Command list maximum size.
+ We currently only use 1. */
+ struct wait_queue *q; /* IRQ wait queue */
+ struct hd_struct *part; /* drive partition table */
+ unsigned lba48; /* Whether LBA48 is supported */
+ unsigned identify; /* Whether we are just identifying
+ at boot */
+ struct gendisk *gd;
+} ports[MAX_PORTS];
+
+
+/* do_request() gets called by the block layer to push a request to the disk.
+ We just push one, and when an interrupt tells it's over, we call do_request()
+ ourself again to push the next request, etc. */
+
+/* Request completed, either successfully or with an error */
+static void ahci_end_request(int uptodate)
+{
+ struct request *rq = CURRENT;
+ struct buffer_head *bh;
+
+ rq->errors = 0;
+ if (!uptodate) {
+ if (!rq->quiet)
+ printk("end_request: I/O error, dev %s, sector %lu\n",
+ kdevname(rq->rq_dev), rq->sector);
+ }
+
+ for (bh = rq->bh; bh; )
+ {
+ struct buffer_head *next = bh->b_reqnext;
+ bh->b_reqnext = NULL;
+ mark_buffer_uptodate (bh, uptodate);
+ unlock_buffer (bh);
+ bh = next;
+ }
+
+ CURRENT = rq->next;
+ if (rq->sem != NULL)
+ up(rq->sem);
+ rq->rq_status = RQ_INACTIVE;
+ wake_up(&wait_for_request);
+}
+
+/* Push the request to the controler port */
+static void ahci_do_port_request(struct port *port, unsigned long long sector, struct request *rq)
+{
+ struct ahci_command *command = port->command;
+ struct ahci_cmd_tbl *prdtl = port->prdtl;
+ struct ahci_fis_h2d *fis_h2d;
+ unsigned slot = 0;
+ struct buffer_head *bh;
+ unsigned i;
+
+ rq->rq_status = RQ_SCSI_BUSY;
+
+ /* Shouldn't ever happen: the block glue is limited at 8 blocks */
+ assert(rq->nr_sectors < 0x10000);
+
+ fis_h2d = (void*) &prdtl[slot].cfis;
+ fis_h2d->fis_type = FIS_TYPE_REG_H2D;
+ fis_h2d->flags = 128;
+ if (port->lba48)
+ if (rq->cmd == READ)
+ fis_h2d->command = WIN_READDMA_EXT;
+ else
+ fis_h2d->command = WIN_WRITEDMA_EXT;
+ else
+ if (rq->cmd == READ)
+ fis_h2d->command = WIN_READDMA;
+ else
+ fis_h2d->command = WIN_WRITEDMA;
+
+ fis_h2d->device = 1<<6; /* LBA */
+
+ fis_h2d->lba0 = sector;
+ fis_h2d->lba1 = sector >> 8;
+ fis_h2d->lba2 = sector >> 16;
+
+ fis_h2d->lba3 = sector >> 24;
+ fis_h2d->lba4 = sector >> 32;
+ fis_h2d->lba5 = sector >> 40;
+
+ fis_h2d->countl = rq->nr_sectors;
+ fis_h2d->counth = rq->nr_sectors >> 8;
+
+ command[slot].opts = sizeof(*fis_h2d) / sizeof(u32);
+
+ if (rq->cmd == WRITE)
+ command[slot].opts |= AHCI_CMD_WRITE;
+
+ for (i = 0, bh = rq->bh; bh; i++, bh = bh->b_reqnext)
+ {
+ assert(i < PRDTL_SIZE);
+ assert((((unsigned long) bh->b_data) & ~PAGE_MASK) ==
+ (((unsigned long) bh->b_data + bh->b_size - 1) & ~PAGE_MASK));
+ prdtl[slot].prdtl[i].dbau = 0;
+ prdtl[slot].prdtl[i].dba = vmtophys(bh->b_data);
+ prdtl[slot].prdtl[i].dbc = bh->b_size - 1;
+ }
+
+ command[slot].opts |= i << 16;
+
+ /* Make sure main memory buffers are up to date */
+ mb();
+
+ /* Issue command */
+ writel(1 << slot, &port->ahci_port->ci);
+
+ /* TODO: IRQ timeout handler */
+}
+
+/* Called by block core to push a request */
+/* TODO: ideally, would have one request queue per port */
+/* TODO: ideally, would use tags to process several requests at a time */
+static void ahci_do_request() /* invoked with cli() */
+{
+ struct request *rq;
+ unsigned minor, unit;
+ unsigned long long block, blockend;
+ struct port *port;
+
+ rq = CURRENT;
+ if (!rq)
+ return;
+
+ if (rq->rq_status != RQ_ACTIVE)
+ /* Current one is already ongoing, let the interrupt handler
+ * push the new one when the current one is finished. */
+ return;
+
+ if (MAJOR(rq->rq_dev) != MAJOR_NR) {
+ printk("bad ahci major %u\n", MAJOR(rq->rq_dev));
+ goto kill_rq;
+ }
+
+ minor = MINOR(rq->rq_dev);
+ unit = minor >> PARTN_BITS;
+ if (unit > MAX_PORTS) {
+ printk("bad ahci unit %u\n", unit);
+ goto kill_rq;
+ }
+
+ port = &ports[unit];
+
+ /* Compute start sector */
+ block = rq->sector;
+ block += port->part[minor & PARTN_MASK].start_sect;
+
+ /* And check end */
+ blockend = block + rq->nr_sectors;
+ if (blockend < block) {
+ if (!rq->quiet)
+ printk("bad blockend %lu vs %lu\n", (unsigned long) blockend, (unsigned long) block);
+ goto kill_rq;
+ }
+ if (blockend > port->capacity) {
+ if (!rq->quiet)
+ {
+ printk("offset for %u was %lu\n", minor, port->part[minor & PARTN_MASK].start_sect);
+ printk("bad access: block %lu, count= %lu\n", (unsigned long) blockend, (unsigned long) port->capacity);
+ }
+ goto kill_rq;
+ }
+
+ /* Push this to the port */
+ ahci_do_port_request(port, block, rq);
+ return;
+
+kill_rq:
+ ahci_end_request(0);
+}
+
+/* The given port got an interrupt, terminate the current request if any */
+static void ahci_port_interrupt(struct port *port, u32 status)
+{
+ unsigned slot = 0;
+
+ if (readl(&port->ahci_port->ci) & (1 << slot)) {
+ /* Command still pending */
+ return;
+ }
+
+ if (port->identify) {
+ port->status = status;
+ wake_up(&port->q);
+ return;
+ }
+
+ if (!CURRENT || CURRENT->rq_status != RQ_SCSI_BUSY) {
+ /* No request currently running */
+ return;
+ }
+
+ if (status & (PORT_IRQ_TF_ERR | PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR | PORT_IRQ_IF_ERR | PORT_IRQ_IF_NONFATAL)) {
+ printk("ahci error %x %x\n", status, readl(&port->ahci_port->tfd));
+ ahci_end_request(0);
+ return;
+ }
+
+ ahci_end_request(1);
+}
+
+/* Start of IRQ handler. Iterate over all ports for this host */
+static void ahci_interrupt (int irq, void *host, struct pt_regs *regs)
+{
+ struct port *port;
+ struct ahci_host *ahci_host = host;
+ u32 irq_mask;
+ u32 status;
+
+ irq_mask = readl(&ahci_host->is);
+
+ if (!irq_mask)
+ return;
+
+ for (port = &ports[0]; port < &ports[MAX_PORTS]; port++) {
+ if (port->ahci_host == ahci_host && (irq_mask & (1 << (port->ahci_port - ahci_host->ports)))) {
+ status = readl(&port->ahci_port->is);
+ /* Clear interrupt before possibly triggering others */
+ writel(status, &port->ahci_port->is);
+ ahci_port_interrupt (port, status);
+ }
+ }
+
+ if (CURRENT)
+ /* Still some requests, queue another one */
+ ahci_do_request();
+
+ /* Clear host after clearing ports */
+ writel(irq_mask, &ahci_host->is);
+
+ /* unlock */
+}
+
+static int ahci_ioctl (struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int major, unit;
+
+ if (!inode || !inode->i_rdev)
+ return -EINVAL;
+
+ major = MAJOR(inode->i_rdev);
+ if (major != MAJOR_NR)
+ return -ENOTTY;
+
+ unit = DEVICE_NR(inode->i_rdev);
+ if (unit >= MAX_PORTS)
+ return -EINVAL;
+
+ switch (cmd) {
+ case BLKRRPART:
+ if (!suser()) return -EACCES;
+ if (!ports[unit].gd)
+ return -EINVAL;
+ resetup_one_dev(ports[unit].gd, unit);
+ return 0;
+ default:
+ return -EPERM;
+ }
+}
+
+static int ahci_open (struct inode *inode, struct file *file)
+{
+ int target;
+
+ if (MAJOR(inode->i_rdev) != MAJOR_NR)
+ return -ENXIO;
+
+ target = MINOR(inode->i_rdev) >> PARTN_BITS;
+ if (target >= MAX_PORTS)
+ return -ENXIO;
+
+ if (!ports[target].ahci_port)
+ return -ENXIO;
+
+ return 0;
+}
+
+static void ahci_release (struct inode *inode, struct file *file)
+{
+}
+
+static int ahci_fsync (struct inode *inode, struct file *file)
+{
+ printk("fsync\n");
+ return -ENOSYS;
+}
+
+static struct file_operations ahci_fops = {
+ .lseek = NULL,
+ .read = block_read,
+ .write = block_write,
+ .readdir = NULL,
+ .select = NULL,
+ .ioctl = ahci_ioctl,
+ .mmap = NULL,
+ .open = ahci_open,
+ .release = ahci_release,
+ .fsync = ahci_fsync,
+ .fasync = NULL,
+ .check_media_change = NULL,
+ .revalidate = NULL,
+};
+
+/* Disk timed out while processing identify, interrupt ahci_probe_port */
+static void identify_timeout(unsigned long data)
+{
+ struct port *port = (void*) data;
+
+ wake_up(&port->q);
+}
+
+static struct timer_list identify_timer = { .function = identify_timeout };
+
+static int ahci_identify(const volatile struct ahci_host *ahci_host, const volatile struct ahci_port *ahci_port, struct port *port, unsigned cmd)
+{
+ struct hd_driveid id;
+ struct ahci_fis_h2d *fis_h2d;
+ struct ahci_command *command = port->command;
+ struct ahci_cmd_tbl *prdtl = port->prdtl;
+ unsigned long flags;
+ unsigned slot;
+ unsigned long first_part;
+ unsigned long long timeout;
+ int ret = 0;
+
+ /* Identify device */
+ /* TODO: make this a request */
+ slot = 0;
+
+ fis_h2d = (void*) &prdtl[slot].cfis;
+ fis_h2d->fis_type = FIS_TYPE_REG_H2D;
+ fis_h2d->flags = 128;
+ fis_h2d->command = cmd;
+ fis_h2d->device = 0;
+
+ /* Fetch the 512 identify data */
+ memset(&id, 0, sizeof(id));
+
+ command[slot].opts = sizeof(*fis_h2d) / sizeof(u32);
+
+ first_part = PAGE_ALIGN((unsigned long) &id) - (unsigned long) &id;
+
+ if (first_part && first_part < sizeof(id)) {
+ /* split over two pages */
+
+ command[slot].opts |= (2 << 16);
+
+ prdtl[slot].prdtl[0].dbau = 0;
+ prdtl[slot].prdtl[0].dba = vmtophys((void*) &id);
+ prdtl[slot].prdtl[0].dbc = first_part - 1;
+ prdtl[slot].prdtl[1].dbau = 0;
+ prdtl[slot].prdtl[1].dba = vmtophys((void*) &id + first_part);
+ prdtl[slot].prdtl[1].dbc = sizeof(id) - first_part - 1;
+ }
+ else
+ {
+ command[slot].opts |= (1 << 16);
+
+ prdtl[slot].prdtl[0].dbau = 0;
+ prdtl[slot].prdtl[0].dba = vmtophys((void*) &id);
+ prdtl[slot].prdtl[0].dbc = sizeof(id) - 1;
+ }
+
+ timeout = jiffies + WAIT_MAX;
+ while (readl(&ahci_port->tfd) & (BUSY_STAT | DRQ_STAT))
+ if (jiffies > timeout) {
+ printk("sd%u: timeout waiting for ready\n", port-ports);
+ port->ahci_host = NULL;
+ port->ahci_port = NULL;
+ return 3;
+ }
+
+ save_flags(flags);
+ cli();
+
+ port->identify = 1;
+ port->status = 0;
+
+ /* Issue command */
+ mb();
+ writel(1 << slot, &ahci_port->ci);
+
+ timeout = jiffies + WAIT_MAX;
+ identify_timer.expires = timeout;
+ identify_timer.data = (unsigned long) port;
+ add_timer(&identify_timer);
+ while (!port->status) {
+ if (jiffies >= timeout) {
+ printk("sd%u: timeout waiting for ready\n", port-ports);
+ port->ahci_host = NULL;
+ port->ahci_port = NULL;
+ del_timer(&identify_timer);
+ restore_flags(flags);
+ return 3;
+ }
+ sleep_on(&port->q);
+ }
+ del_timer(&identify_timer);
+ restore_flags(flags);
+
+ if ((port->status & PORT_IRQ_TF_ERR) || readl(&ahci_port->is) & PORT_IRQ_TF_ERR)
+ {
+ /* Identify error */
+ port->capacity = 0;
+ port->lba48 = 0;
+ ret = 2;
+ } else {
+ memcpy(&port->id, &id, sizeof(id));
+ port->is_cd = 0;
+
+ ide_fixstring(id.model, sizeof(id.model), 1);
+ ide_fixstring(id.fw_rev, sizeof(id.fw_rev), 1);
+ ide_fixstring(id.serial_no, sizeof(id.serial_no), 1);
+ if (cmd == WIN_PIDENTIFY)
+ {
+ unsigned char type = (id.config >> 8) & 0x1f;
+
+ printk("sd%u: %s, ATAPI ", port - ports, id.model);
+ if (type == 5)
+ {
+ printk("unsupported CDROM drive\n");
+ port->is_cd = 1;
+ port->lba48 = 0;
+ port->capacity = 0;
+ }
+ else
+ {
+ printk("unsupported type %d\n", type);
+ port->lba48 = 0;
+ port->capacity = 0;
+ return 2;
+ }
+ return 0;
+ }
+
+ if (id.command_set_2 & (1U<<10))
+ {
+ port->lba48 = 1;
+ port->capacity = id.lba_capacity_2;
+ if (port->capacity >= (1ULL << 32))
+ {
+ port->capacity = (1ULL << 32) - 1;
+ printk("Warning: truncating disk size to 2TiB\n");
+ }
+ }
+ else
+ {
+ port->lba48 = 0;
+ port->capacity = id.lba_capacity;
+ if (port->capacity > (1ULL << 24))
+ {
+ port->capacity = (1ULL << 24);
+ printk("Warning: truncating disk size to 128GiB\n");
+ }
+ }
+ if (port->capacity/2048 >= 10240)
+ printk("sd%u: %s, %uGB w/%dkB Cache\n", port - ports, id.model, (unsigned) (port->capacity/(2048*1024)), id.buf_size/2);
+ else
+ printk("sd%u: %s, %uMB w/%dkB Cache\n", port - ports, id.model, (unsigned) (port->capacity/2048), id.buf_size/2);
+ }
+ port->identify = 0;
+
+ return ret;
+}
+
+/* Probe one AHCI port */
+static void ahci_probe_port(const volatile struct ahci_host *ahci_host, const volatile struct ahci_port *ahci_port)
+{
+ struct port *port;
+ void *mem;
+ unsigned cls = ((readl(&ahci_host->cap) >> 8) & 0x1f) + 1;
+ struct ahci_command *command;
+ struct ahci_fis *fis;
+ struct ahci_cmd_tbl *prdtl;
+ vm_size_t size =
+ cls * sizeof(*command)
+ + sizeof(*fis)
+ + cls * sizeof(*prdtl);
+ unsigned i;
+ unsigned long long timeout;
+
+ for (i = 0; i < MAX_PORTS; i++) {
+ if (!ports[i].ahci_port)
+ break;
+ }
+ if (i == MAX_PORTS)
+ return;
+ port = &ports[i];
+
+ /* Has to be 1K-aligned */
+ mem = vmalloc (size);
+ if (!mem)
+ return;
+ assert (!(((unsigned long) mem) & (1024-1)));
+ memset (mem, 0, size);
+
+ port->ahci_host = ahci_host;
+ port->ahci_port = ahci_port;
+ port->cls = cls;
+
+ port->command = command = mem;
+ port->fis = fis = (void*) command + cls * sizeof(*command);
+ port->prdtl = prdtl = (void*) fis + sizeof(*fis);
+
+ /* Stop commands */
+ writel(readl(&ahci_port->cmd) & ~PORT_CMD_START, &ahci_port->cmd);
+ timeout = jiffies + WAIT_MAX;
+ while (readl(&ahci_port->cmd) & PORT_CMD_LIST_ON)
+ if (jiffies > timeout) {
+ printk("sd%u: timeout waiting for list completion\n", port-ports);
+ port->ahci_host = NULL;
+ port->ahci_port = NULL;
+ return;
+ }
+
+ writel(readl(&ahci_port->cmd) & ~PORT_CMD_FIS_RX, &ahci_port->cmd);
+ timeout = jiffies + WAIT_MAX;
+ while (readl(&ahci_port->cmd) & PORT_CMD_FIS_ON)
+ if (jiffies > timeout) {
+ printk("sd%u: timeout waiting for FIS completion\n", port-ports);
+ port->ahci_host = NULL;
+ port->ahci_port = NULL;
+ return;
+ }
+
+ /* We don't support 64bit */
+ /* Point controller to our buffers */
+ writel(0, &ahci_port->clbu);
+ writel(vmtophys((void*) command), &ahci_port->clb);
+ writel(0, &ahci_port->fbu);
+ writel(vmtophys((void*) fis), &ahci_port->fb);
+
+ /* Clear any previous interrupts */
+ writel(readl(&ahci_port->is), &ahci_port->is);
+ writel(1 << (ahci_port - ahci_host->ports), &ahci_host->is);
+
+ /* And activate them */
+ writel(DEF_PORT_IRQ, &ahci_port->ie);
+ writel(readl(&ahci_host->ghc) | HOST_IRQ_EN, &ahci_host->ghc);
+
+ for (i = 0; i < cls; i++)
+ {
+ command[i].ctbau = 0;
+ command[i].ctba = vmtophys((void*) &prdtl[i]);
+ }
+
+ /* Start commands */
+ timeout = jiffies + WAIT_MAX;
+ while (readl(&ahci_port->cmd) & PORT_CMD_LIST_ON)
+ if (jiffies > timeout) {
+ printk("sd%u: timeout waiting for list completion\n", port-ports);
+ port->ahci_host = NULL;
+ port->ahci_port = NULL;
+ return;
+ }
+
+ writel(readl(&ahci_port->cmd) | PORT_CMD_FIS_RX | PORT_CMD_START, &ahci_port->cmd);
+
+ if (ahci_identify(ahci_host, ahci_port, port, WIN_IDENTIFY) >= 2)
+ /* Try ATAPI */
+ ahci_identify(ahci_host, ahci_port, port, WIN_PIDENTIFY);
+}
+
+/* Probe one AHCI PCI device */
+static void ahci_probe_dev(unsigned char bus, unsigned char device)
+{
+ unsigned char hdrtype;
+ unsigned char dev, fun;
+ const volatile struct ahci_host *ahci_host;
+ const volatile struct ahci_port *ahci_port;
+ unsigned nports, n, i;
+ unsigned port_map;
+ unsigned bar;
+ unsigned char irq;
+
+ dev = PCI_SLOT(device);
+ fun = PCI_FUNC(device);
+
+ /* Get configuration */
+ if (pcibios_read_config_byte(bus, device, PCI_HEADER_TYPE, &hdrtype) != PCIBIOS_SUCCESSFUL) {
+ printk("ahci: %02u:%02u.%u: Can not read configuration", bus, dev, fun);
+ return;
+ }
+
+ if (hdrtype != 0) {
+ printk("ahci: %02u:%02u.%u: Unknown hdrtype %d\n", bus, dev, fun, hdrtype);
+ return;
+ }
+
+ if (pcibios_read_config_dword(bus, device, PCI_BASE_ADDRESS_5, &bar) != PCIBIOS_SUCCESSFUL) {
+ printk("ahci: %02u:%02u.%u: Can not read BAR 5", bus, dev, fun);
+ return;
+ }
+ if (bar & 0x01) {
+ printk("ahci: %02u:%02u.%u: BAR 5 is I/O?!", bus, dev, fun);
+ return;
+ }
+ bar &= ~0x0f;
+
+ if (pcibios_read_config_byte(bus, device, PCI_INTERRUPT_LINE, &irq) != PCIBIOS_SUCCESSFUL) {
+ printk("ahci: %02u:%02u.%u: Can not read IRQ", bus, dev, fun);
+ return;
+ }
+
+ printk("AHCI SATA %02u:%02u.%u BAR 0x%x IRQ %u\n", bus, dev, fun, bar, irq);
+
+ /* Map mmio */
+ ahci_host = vremap(bar, 0x2000);
+
+ /* Request IRQ */
+ if (request_irq(irq, &ahci_interrupt, SA_SHIRQ, "ahci", (void*) ahci_host)) {
+ printk("ahci: %02u:%02u.%u: Can not get irq %u\n", bus, dev, fun, irq);
+ return;
+ }
+
+ nports = (readl(&ahci_host->cap) & 0x1f) + 1;
+ port_map = readl(&ahci_host->pi);
+
+ for (n = 0, i = 0; i < AHCI_MAX_PORTS; i++)
+ if (port_map & (1U << i))
+ n++;
+
+ if (nports != n) {
+ printk("ahci: %02u:%02u.%u: Odd number of ports %u, assuming %u is correct\n", bus, dev, fun, n, nports);
+ port_map = 0;
+ }
+ if (!port_map) {
+ port_map = (1U << nports) - 1;
+ }
+
+ for (i = 0; i < AHCI_MAX_PORTS; i++) {
+ u32 ssts;
+ u8 spd, ipm;
+
+ if (!(port_map & (1U << i)))
+ continue;
+
+ ahci_port = &ahci_host->ports[i];
+
+ ssts = readl(&ahci_port->ssts);
+ spd = ssts & 0xf;
+ switch (spd)
+ {
+ case 0x0:
+ /* Device not present */
+ continue;
+ case 0x1:
+ printk("ahci: %02u:%02u.%u: Port %u communication not established. TODO: power on device\n", bus, dev, fun, i);
+ continue;
+ case 0x3:
+ /* Present and communication established */
+ break;
+ case 0x4:
+ printk("ahci: %02u:%02u.%u: Phy offline?!\n", bus, dev, fun, i);
+ continue;
+ default:
+ printk("ahci: %02u:%02u.%u: Unknown port %u SPD %x\n", bus, dev, fun, i, spd);
+ continue;
+ }
+
+ ipm = (ssts >> 8) & 0xf;
+ switch (ipm)
+ {
+ case 0x0:
+ /* Device not present */
+ continue;
+ case 0x1:
+ /* Active */
+ break;
+ case 0x2:
+ printk("ahci: %02u:%02u.%u: Port %u in Partial power management. TODO: power on device\n", bus, dev, fun, i);
+ continue;
+ case 0x6:
+ printk("ahci: %02u:%02u.%u: Port %u in Slumber power management. TODO: power on device\n", bus, dev, fun, i);
+ continue;
+ default:
+ printk("ahci: %02u:%02u.%u: Unknown port %u IPM %x\n", bus, dev, fun, i, ipm);
+ continue;
+ }
+
+ /* OK! Probe this port */
+ ahci_probe_port(ahci_host, ahci_port);
+ }
+}
+
+/* genhd callback to set size of disks */
+static void ahci_geninit(struct gendisk *gd)
+{
+ unsigned unit;
+ struct port *port;
+
+ for (unit = 0; unit < gd->nr_real; unit++) {
+ port = &ports[unit];
+ port->part[0].nr_sects = port->capacity;
+ if (!port->part[0].nr_sects)
+ port->part[0].nr_sects = -1;
+ }
+}
+
+/* Probe all AHCI PCI devices */
+void ahci_probe_pci(void)
+{
+ unsigned char bus, device;
+ unsigned short index;
+ int ret;
+ unsigned nports, unit, nminors;
+ struct port *port;
+ struct gendisk *gd, **gdp;
+ int *bs;
+
+ for (index = 0;
+ (ret = pcibios_find_class(PCI_CLASS_STORAGE_SATA_AHCI, index, &bus, &device)) == PCIBIOS_SUCCESSFUL;
+ index++)
+ {
+ /* Note: this prevents from also having a SCSI controler.
+ * It shouldn't harm too much until we have proper hardware
+ * enumeration.
+ */
+ if (register_blkdev(MAJOR_NR, "sd", &ahci_fops) < 0)
+ printk("could not register ahci\n");
+ ahci_probe_dev(bus, device);
+ }
+
+ for (nports = 0, port = &ports[0]; port < &ports[MAX_PORTS]; port++)
+ if (port->ahci_port)
+ nports++;
+
+ nminors = nports * (1<<PARTN_BITS);
+
+ gd = kmalloc(sizeof(*gd), GFP_KERNEL);
+ gd->sizes = kmalloc(nminors * sizeof(*gd->sizes), GFP_KERNEL);
+ gd->part = kmalloc(nminors * sizeof(*gd->part), GFP_KERNEL);
+ bs = kmalloc(nminors * sizeof(*bs), GFP_KERNEL);
+
+ blksize_size[MAJOR_NR] = bs;
+ for (unit = 0; unit < nminors; unit++)
+ /* We prefer to transfer whole pages */
+ *bs++ = PAGE_SIZE;
+
+ memset(gd->part, 0, nminors * sizeof(*gd->part));
+
+ for (unit = 0; unit < nports; unit++) {
+ ports[unit].gd = gd;
+ ports[unit].part = &gd->part[unit << PARTN_BITS];
+ }
+
+ gd->major = MAJOR_NR;
+ gd->major_name = "sd";
+ gd->minor_shift = PARTN_BITS;
+ gd->max_p = 1<<PARTN_BITS;
+ gd->max_nr = nports;
+ gd->nr_real = nports;
+ gd->init = ahci_geninit;
+ gd->next = NULL;
+
+ for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
+ ;
+ *gdp = gd;
+
+ blk_dev[MAJOR_NR].request_fn = ahci_do_request;
+}
diff --git a/linux/dev/drivers/block/floppy.c b/linux/dev/drivers/block/floppy.c
index 4c0977a3..83d66f05 100644
--- a/linux/dev/drivers/block/floppy.c
+++ b/linux/dev/drivers/block/floppy.c
@@ -3723,7 +3723,7 @@ static int floppy_revalidate(kdev_t dev)
return 1;
}
if (bh && !buffer_uptodate(bh))
- ll_rw_block(READ, 1, &bh);
+ ll_rw_block(READ, 1, &bh, 1);
process_fd_request();
wait_on_buffer(bh);
brelse(bh);
diff --git a/linux/dev/drivers/block/genhd.c b/linux/dev/drivers/block/genhd.c
index 95b499b1..3a861386 100644
--- a/linux/dev/drivers/block/genhd.c
+++ b/linux/dev/drivers/block/genhd.c
@@ -27,6 +27,8 @@
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#endif
+#include <linux/hdreg.h>
+#include <alloca.h>
#include <asm/system.h>
@@ -768,12 +770,36 @@ static void setup_dev(struct gendisk *dev)
void device_setup(void)
{
extern void console_map_init(void);
+ extern char *kernel_cmdline;
+ char *c, *param, *white;
struct gendisk *p;
int nr=0;
#ifdef MACH
linux_intr_pri = SPL6;
#endif
+ for (c = kernel_cmdline; c; )
+ {
+ param = strstr(c, " ide");
+ if (!param)
+ param = strstr(c, " hd");
+ if (!param)
+ break;
+ if (param) {
+ param++;
+ white = strchr(param, ' ');
+ if (!white) {
+ ide_setup(param);
+ c = NULL;
+ } else {
+ char *word = alloca(white - param + 1);
+ strncpy(word, param, white - param);
+ word[white-param] = '\0';
+ ide_setup(word);
+ c = white + 1;
+ }
+ }
+ }
#ifndef MACH
chr_dev_init();
#endif
diff --git a/linux/dev/glue/block.c b/linux/dev/glue/block.c
index 8c41f088..da4ef38e 100644
--- a/linux/dev/glue/block.c
+++ b/linux/dev/glue/block.c
@@ -384,7 +384,7 @@ bread (kdev_t dev, int block, int size)
bh = getblk (dev, block, size);
if (bh)
{
- ll_rw_block (READ, 1, &bh);
+ ll_rw_block (READ, 1, &bh, 0);
wait_on_buffer (bh);
if (! buffer_uptodate (bh))
{
@@ -444,7 +444,7 @@ enqueue_request (struct request *req)
/* Perform the I/O operation RW on the buffer list BH
containing NR buffers. */
void
-ll_rw_block (int rw, int nr, struct buffer_head **bh)
+ll_rw_block (int rw, int nr, struct buffer_head **bh, int quiet)
{
int i, bshift, bsize;
unsigned major;
@@ -476,6 +476,7 @@ ll_rw_block (int rw, int nr, struct buffer_head **bh)
r->rq_dev = bh[0]->b_dev;
r->cmd = rw;
r->errors = 0;
+ r->quiet = quiet;
r->sector = bh[0]->b_blocknr << (bshift - 9);
r->current_nr_sectors = bh[0]->b_size >> 9;
r->buffer = bh[0]->b_data;
@@ -528,7 +529,7 @@ rdwr_partial (int rw, kdev_t dev, loff_t *off,
bh->b_data = alloc_buffer (bh->b_size);
if (! bh->b_data)
return -ENOMEM;
- ll_rw_block (READ, 1, &bh);
+ ll_rw_block (READ, 1, &bh, 0);
wait_on_buffer (bh);
if (buffer_uptodate (bh))
{
@@ -542,7 +543,7 @@ rdwr_partial (int rw, kdev_t dev, loff_t *off,
{
memcpy (bh->b_data + o, *buf, c);
bh->b_state = (1 << BH_Dirty) | (1 << BH_Lock);
- ll_rw_block (WRITE, 1, &bh);
+ ll_rw_block (WRITE, 1, &bh, 0);
wait_on_buffer (bh);
if (! buffer_uptodate (bh))
{
@@ -589,8 +590,8 @@ rdwr_full (int rw, kdev_t dev, loff_t *off, char **buf, int *resid, int bshift)
set_bit (BH_Lock, &bh->b_state);
if (rw == WRITE)
set_bit (BH_Dirty, &bh->b_state);
- cc = PAGE_SIZE - (((int) *buf) & PAGE_MASK);
- if (cc >= BSIZE && ((int) *buf & 511) == 0)
+ cc = PAGE_SIZE - (((int) *buf + (nb << bshift)) & PAGE_MASK);
+ if (cc >= BSIZE && (((int) *buf + (nb << bshift)) & 511) == 0)
cc &= ~BMASK;
else
{
@@ -623,7 +624,8 @@ rdwr_full (int rw, kdev_t dev, loff_t *off, char **buf, int *resid, int bshift)
}
if (! err)
{
- ll_rw_block (rw, i, bhp);
+ assert (i > 0);
+ ll_rw_block (rw, i, bhp, 0);
wait_on_buffer (bhp[i - 1]);
}
for (bh = bhead, cc = 0, j = 0; j < i; cc += bh->b_size, bh++, j++)
@@ -1650,7 +1652,7 @@ device_get_status (void *d, dev_flavor_t flavor, dev_status_t status,
/* It would be nice to return the block size as reported by
the driver, but a lot of user level code assumes the sector
size to be 512. */
- status[DEV_GET_SIZE_RECORD_SIZE] = 512;
+ status[DEV_GET_RECORDS_RECORD_SIZE] = 512;
/* Always return DEV_GET_RECORDS_COUNT. This is what all native
Mach drivers do, and makes it possible to detect the absence
of the call by setting it to a different value on input. MiG
@@ -1703,7 +1705,7 @@ device_get_status (void *d, dev_flavor_t flavor, dev_status_t status,
static io_return_t
device_set_status (void *d, dev_flavor_t flavor, dev_status_t status,
- mach_msg_type_number_t *status_count)
+ mach_msg_type_number_t status_count)
{
struct block_data *bd = d;
diff --git a/linux/dev/glue/kmem.c b/linux/dev/glue/kmem.c
index 28321711..ff052ffc 100644
--- a/linux/dev/glue/kmem.c
+++ b/linux/dev/glue/kmem.c
@@ -560,6 +560,12 @@ vfree (void *addr)
vmalloc_list_remove (p);
}
+unsigned long
+vmtophys (void *addr)
+{
+ return kvtophys((vm_offset_t) addr);
+}
+
/* XXX: Quick hacking. */
/* Remap physical address into virtual address. */
void *
diff --git a/linux/dev/include/ahci.h b/linux/dev/include/ahci.h
new file mode 100644
index 00000000..31977b63
--- /dev/null
+++ b/linux/dev/include/ahci.h
@@ -0,0 +1,268 @@
+#ifndef _GNUMACH_AHCI_H
+#define _GNUMACH_AHCI_H
+extern void ahci_probe_pci(void);
+
+/* From linux 3.9's drivers/ata/ahci.h */
+
+/*
+ * ahci.h - Common AHCI SATA definitions and declarations
+ *
+ * Maintained by: Jeff Garzik <jgarzik@pobox.com>
+ * Please ALWAYS copy linux-ide@vger.kernel.org
+ * on emails.
+ *
+ * Copyright 2004-2005 Red Hat, Inc.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * libata documentation is available via 'make {ps|pdf}docs',
+ * as Documentation/DocBook/libata.*
+ *
+ * AHCI hardware documentation:
+ * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
+ * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf
+ *
+ */
+
+enum {
+ AHCI_MAX_PORTS = 32,
+ AHCI_MAX_SG = 168, /* hardware max is 64K */
+ AHCI_DMA_BOUNDARY = 0xffffffff,
+ AHCI_MAX_CMDS = 32,
+ AHCI_CMD_SZ = 32,
+ AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ,
+ AHCI_RX_FIS_SZ = 256,
+ AHCI_CMD_TBL_CDB = 0x40,
+ AHCI_CMD_TBL_HDR_SZ = 0x80,
+ AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 16),
+ AHCI_CMD_TBL_AR_SZ = AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS,
+ AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ +
+ AHCI_RX_FIS_SZ,
+ AHCI_PORT_PRIV_FBS_DMA_SZ = AHCI_CMD_SLOT_SZ +
+ AHCI_CMD_TBL_AR_SZ +
+ (AHCI_RX_FIS_SZ * 16),
+ AHCI_IRQ_ON_SG = (1 << 31),
+ AHCI_CMD_ATAPI = (1 << 5),
+ AHCI_CMD_WRITE = (1 << 6),
+ AHCI_CMD_PREFETCH = (1 << 7),
+ AHCI_CMD_RESET = (1 << 8),
+ AHCI_CMD_CLR_BUSY = (1 << 10),
+
+ RX_FIS_PIO_SETUP = 0x20, /* offset of PIO Setup FIS data */
+ RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */
+ RX_FIS_SDB = 0x58, /* offset of SDB FIS data */
+ RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */
+
+ /* global controller registers */
+ HOST_CAP = 0x00, /* host capabilities */
+ HOST_CTL = 0x04, /* global host control */
+ HOST_IRQ_STAT = 0x08, /* interrupt status */
+ HOST_PORTS_IMPL = 0x0c, /* bitmap of implemented ports */
+ HOST_VERSION = 0x10, /* AHCI spec. version compliancy */
+ HOST_EM_LOC = 0x1c, /* Enclosure Management location */
+ HOST_EM_CTL = 0x20, /* Enclosure Management Control */
+ HOST_CAP2 = 0x24, /* host capabilities, extended */
+
+ /* HOST_CTL bits */
+ HOST_RESET = (1 << 0), /* reset controller; self-clear */
+ HOST_IRQ_EN = (1 << 1), /* global IRQ enable */
+ HOST_AHCI_EN = (1 << 31), /* AHCI enabled */
+
+ /* HOST_CAP bits */
+ HOST_CAP_SXS = (1 << 5), /* Supports External SATA */
+ HOST_CAP_EMS = (1 << 6), /* Enclosure Management support */
+ HOST_CAP_CCC = (1 << 7), /* Command Completion Coalescing */
+ HOST_CAP_PART = (1 << 13), /* Partial state capable */
+ HOST_CAP_SSC = (1 << 14), /* Slumber state capable */
+ HOST_CAP_PIO_MULTI = (1 << 15), /* PIO multiple DRQ support */
+ HOST_CAP_FBS = (1 << 16), /* FIS-based switching support */
+ HOST_CAP_PMP = (1 << 17), /* Port Multiplier support */
+ HOST_CAP_ONLY = (1 << 18), /* Supports AHCI mode only */
+ HOST_CAP_CLO = (1 << 24), /* Command List Override support */
+ HOST_CAP_LED = (1 << 25), /* Supports activity LED */
+ HOST_CAP_ALPM = (1 << 26), /* Aggressive Link PM support */
+ HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */
+ HOST_CAP_MPS = (1 << 28), /* Mechanical presence switch */
+ HOST_CAP_SNTF = (1 << 29), /* SNotification register */
+ HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */
+ HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */
+
+ /* HOST_CAP2 bits */
+ HOST_CAP2_BOH = (1 << 0), /* BIOS/OS handoff supported */
+ HOST_CAP2_NVMHCI = (1 << 1), /* NVMHCI supported */
+ HOST_CAP2_APST = (1 << 2), /* Automatic partial to slumber */
+ HOST_CAP2_SDS = (1 << 3), /* Support device sleep */
+ HOST_CAP2_SADM = (1 << 4), /* Support aggressive DevSlp */
+ HOST_CAP2_DESO = (1 << 5), /* DevSlp from slumber only */
+
+ /* registers for each SATA port */
+ PORT_LST_ADDR = 0x00, /* command list DMA addr */
+ PORT_LST_ADDR_HI = 0x04, /* command list DMA addr hi */
+ PORT_FIS_ADDR = 0x08, /* FIS rx buf addr */
+ PORT_FIS_ADDR_HI = 0x0c, /* FIS rx buf addr hi */
+ PORT_IRQ_STAT = 0x10, /* interrupt status */
+ PORT_IRQ_MASK = 0x14, /* interrupt enable/disable mask */
+ PORT_CMD = 0x18, /* port command */
+ PORT_TFDATA = 0x20, /* taskfile data */
+ PORT_SIG = 0x24, /* device TF signature */
+ PORT_CMD_ISSUE = 0x38, /* command issue */
+ PORT_SCR_STAT = 0x28, /* SATA phy register: SStatus */
+ PORT_SCR_CTL = 0x2c, /* SATA phy register: SControl */
+ PORT_SCR_ERR = 0x30, /* SATA phy register: SError */
+ PORT_SCR_ACT = 0x34, /* SATA phy register: SActive */
+ PORT_SCR_NTF = 0x3c, /* SATA phy register: SNotification */
+ PORT_FBS = 0x40, /* FIS-based Switching */
+ PORT_DEVSLP = 0x44, /* device sleep */
+
+ /* PORT_IRQ_{STAT,MASK} bits */
+ PORT_IRQ_COLD_PRES = (1 << 31), /* cold presence detect */
+ PORT_IRQ_TF_ERR = (1 << 30), /* task file error */
+ PORT_IRQ_HBUS_ERR = (1 << 29), /* host bus fatal error */
+ PORT_IRQ_HBUS_DATA_ERR = (1 << 28), /* host bus data error */
+ PORT_IRQ_IF_ERR = (1 << 27), /* interface fatal error */
+ PORT_IRQ_IF_NONFATAL = (1 << 26), /* interface non-fatal error */
+ PORT_IRQ_OVERFLOW = (1 << 24), /* xfer exhausted available S/G */
+ PORT_IRQ_BAD_PMP = (1 << 23), /* incorrect port multiplier */
+
+ PORT_IRQ_PHYRDY = (1 << 22), /* PhyRdy changed */
+ PORT_IRQ_DEV_ILCK = (1 << 7), /* device interlock */
+ PORT_IRQ_CONNECT = (1 << 6), /* port connect change status */
+ PORT_IRQ_SG_DONE = (1 << 5), /* descriptor processed */
+ PORT_IRQ_UNK_FIS = (1 << 4), /* unknown FIS rx'd */
+ PORT_IRQ_SDB_FIS = (1 << 3), /* Set Device Bits FIS rx'd */
+ PORT_IRQ_DMAS_FIS = (1 << 2), /* DMA Setup FIS rx'd */
+ PORT_IRQ_PIOS_FIS = (1 << 1), /* PIO Setup FIS rx'd */
+ PORT_IRQ_D2H_REG_FIS = (1 << 0), /* D2H Register FIS rx'd */
+
+ PORT_IRQ_FREEZE = PORT_IRQ_HBUS_ERR |
+ PORT_IRQ_IF_ERR |
+ PORT_IRQ_CONNECT |
+ PORT_IRQ_PHYRDY |
+ PORT_IRQ_UNK_FIS |
+ PORT_IRQ_BAD_PMP,
+ PORT_IRQ_ERROR = PORT_IRQ_FREEZE |
+ PORT_IRQ_TF_ERR |
+ PORT_IRQ_HBUS_DATA_ERR,
+ DEF_PORT_IRQ = PORT_IRQ_ERROR | PORT_IRQ_SG_DONE |
+ PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS |
+ PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS,
+
+ /* PORT_CMD bits */
+ PORT_CMD_ASP = (1 << 27), /* Aggressive Slumber/Partial */
+ PORT_CMD_ALPE = (1 << 26), /* Aggressive Link PM enable */
+ PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */
+ PORT_CMD_FBSCP = (1 << 22), /* FBS Capable Port */
+ PORT_CMD_PMP = (1 << 17), /* PMP attached */
+ PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */
+ PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */
+ PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */
+ PORT_CMD_CLO = (1 << 3), /* Command list override */
+ PORT_CMD_POWER_ON = (1 << 2), /* Power up device */
+ PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */
+ PORT_CMD_START = (1 << 0), /* Enable port DMA engine */
+
+ PORT_CMD_ICC_MASK = (0xf << 28), /* i/f ICC state mask */
+ PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */
+ PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
+ PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */
+
+ /* PORT_FBS bits */
+ PORT_FBS_DWE_OFFSET = 16, /* FBS device with error offset */
+ PORT_FBS_ADO_OFFSET = 12, /* FBS active dev optimization offset */
+ PORT_FBS_DEV_OFFSET = 8, /* FBS device to issue offset */
+ PORT_FBS_DEV_MASK = (0xf << PORT_FBS_DEV_OFFSET), /* FBS.DEV */
+ PORT_FBS_SDE = (1 << 2), /* FBS single device error */
+ PORT_FBS_DEC = (1 << 1), /* FBS device error clear */
+ PORT_FBS_EN = (1 << 0), /* Enable FBS */
+
+ /* PORT_DEVSLP bits */
+ PORT_DEVSLP_DM_OFFSET = 25, /* DITO multiplier offset */
+ PORT_DEVSLP_DM_MASK = (0xf << 25), /* DITO multiplier mask */
+ PORT_DEVSLP_DITO_OFFSET = 15, /* DITO offset */
+ PORT_DEVSLP_MDAT_OFFSET = 10, /* Minimum assertion time */
+ PORT_DEVSLP_DETO_OFFSET = 2, /* DevSlp exit timeout */
+ PORT_DEVSLP_DSP = (1 << 1), /* DevSlp present */
+ PORT_DEVSLP_ADSE = (1 << 0), /* Aggressive DevSlp enable */
+
+ /* hpriv->flags bits */
+
+#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)
+
+ AHCI_HFLAG_NO_NCQ = (1 << 0),
+ AHCI_HFLAG_IGN_IRQ_IF_ERR = (1 << 1), /* ignore IRQ_IF_ERR */
+ AHCI_HFLAG_IGN_SERR_INTERNAL = (1 << 2), /* ignore SERR_INTERNAL */
+ AHCI_HFLAG_32BIT_ONLY = (1 << 3), /* force 32bit */
+ AHCI_HFLAG_MV_PATA = (1 << 4), /* PATA port */
+ AHCI_HFLAG_NO_MSI = (1 << 5), /* no PCI MSI */
+ AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */
+ AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */
+ AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */
+ AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */
+ AHCI_HFLAG_SRST_TOUT_IS_OFFLINE = (1 << 11), /* treat SRST timeout as
+ link offline */
+ AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */
+ AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */
+ AHCI_HFLAG_YES_FBS = (1 << 14), /* force FBS cap on */
+ AHCI_HFLAG_DELAY_ENGINE = (1 << 15), /* do not start engine on
+ port start (wait until
+ error-handling stage) */
+ AHCI_HFLAG_MULTI_MSI = (1 << 16), /* multiple PCI MSIs */
+
+ /* ap->flags bits */
+
+ /*
+ AHCI_FLAG_COMMON = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA |
+ ATA_FLAG_ACPI_SATA | ATA_FLAG_AN,
+ */
+
+ ICH_MAP = 0x90, /* ICH MAP register */
+
+ /* em constants */
+ EM_MAX_SLOTS = 8,
+ EM_MAX_RETRY = 5,
+
+ /* em_ctl bits */
+ EM_CTL_RST = (1 << 9), /* Reset */
+ EM_CTL_TM = (1 << 8), /* Transmit Message */
+ EM_CTL_MR = (1 << 0), /* Message Received */
+ EM_CTL_ALHD = (1 << 26), /* Activity LED */
+ EM_CTL_XMT = (1 << 25), /* Transmit Only */
+ EM_CTL_SMB = (1 << 24), /* Single Message Buffer */
+ EM_CTL_SGPIO = (1 << 19), /* SGPIO messages supported */
+ EM_CTL_SES = (1 << 18), /* SES-2 messages supported */
+ EM_CTL_SAFTE = (1 << 17), /* SAF-TE messages supported */
+ EM_CTL_LED = (1 << 16), /* LED messages supported */
+
+ /* em message type */
+ EM_MSG_TYPE_LED = (1 << 0), /* LED */
+ EM_MSG_TYPE_SAFTE = (1 << 1), /* SAF-TE */
+ EM_MSG_TYPE_SES2 = (1 << 2), /* SES-2 */
+ EM_MSG_TYPE_SGPIO = (1 << 3), /* SGPIO */
+
+ FIS_TYPE_REG_H2D = 0x27,
+ FIS_TYPE_REG_D2H = 0x34,
+ FIS_TYPE_DMA_ACT = 0x39,
+ FIS_TYPE_DMA_SETUP = 0x41,
+ FIS_TYPE_DATA = 0x46,
+ FIS_TYPE_BIST = 0x58,
+ FIS_TYPE_PIO_SETUP = 0x5F,
+ FIS_TYPE_DEV_BITS = 0xA1,
+};
+
+/* End from linux 3.9 */
+
+#endif /* _GNUMACH_AHCI_H */
diff --git a/linux/dev/include/asm-i386/string.h b/linux/dev/include/asm-i386/string.h
index bdb75455..f41ca5c0 100644
--- a/linux/dev/include/asm-i386/string.h
+++ b/linux/dev/include/asm-i386/string.h
@@ -28,7 +28,7 @@
*/
#define __HAVE_ARCH_STRCPY
-extern inline char * strcpy(char * dest,const char *src)
+static inline char * strcpy(char * dest,const char *src)
{
int d0, d1, d2;
__asm__ __volatile__(
@@ -43,7 +43,7 @@ return dest;
}
#define __HAVE_ARCH_STRNCPY
-extern inline char * strncpy(char * dest,const char *src,size_t count)
+static inline char * strncpy(char * dest,const char *src,size_t count)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
@@ -63,7 +63,7 @@ return dest;
}
#define __HAVE_ARCH_STRCAT
-extern inline char * strcat(char * dest,const char * src)
+static inline char * strcat(char * dest,const char * src)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
@@ -81,7 +81,7 @@ return dest;
}
#define __HAVE_ARCH_STRNCAT
-extern inline char * strncat(char * dest,const char * src,size_t count)
+static inline char * strncat(char * dest,const char * src,size_t count)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
@@ -105,7 +105,7 @@ return dest;
}
#define __HAVE_ARCH_STRCMP
-extern inline int strcmp(const char * cs,const char * ct)
+static inline int strcmp(const char * cs,const char * ct)
{
int d0, d1;
register int __res;
@@ -127,7 +127,7 @@ return __res;
}
#define __HAVE_ARCH_STRNCMP
-extern inline int strncmp(const char * cs,const char * ct,size_t count)
+static inline int strncmp(const char * cs,const char * ct,size_t count)
{
register int __res;
int d0, d1, d2;
@@ -151,7 +151,7 @@ return __res;
}
#define __HAVE_ARCH_STRCHR
-extern inline char * strchr(const char * s, int c)
+static inline char * strchr(const char * s, int c)
{
int d0;
register char * __res;
@@ -171,7 +171,7 @@ return __res;
}
#define __HAVE_ARCH_STRRCHR
-extern inline char * strrchr(const char * s, int c)
+static inline char * strrchr(const char * s, int c)
{
int d0, d1;
register char * __res;
@@ -189,7 +189,7 @@ return __res;
}
#define __HAVE_ARCH_STRLEN
-extern inline size_t strlen(const char * s)
+static inline size_t strlen(const char * s)
{
int d0;
register int __res;
@@ -203,7 +203,7 @@ __asm__ __volatile__(
return __res;
}
-extern inline void * __memcpy(void * to, const void * from, size_t n)
+static inline void * __memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
__asm__ __volatile__(
@@ -226,7 +226,7 @@ return (to);
* This looks horribly ugly, but the compiler can optimize it totally,
* as the count is constant.
*/
-extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
+static inline void * __constant_memcpy(void * to, const void * from, size_t n)
{
switch (n) {
case 0:
@@ -299,7 +299,7 @@ __asm__ __volatile__( \
__memcpy((t),(f),(n)))
#define __HAVE_ARCH_MEMMOVE
-extern inline void * memmove(void * dest,const void * src, size_t n)
+static inline void * memmove(void * dest,const void * src, size_t n)
{
int d0, d1, d2;
if (dest<src)
@@ -327,7 +327,7 @@ return dest;
#define memcmp __builtin_memcmp
#define __HAVE_ARCH_MEMCHR
-extern inline void * memchr(const void * cs,int c,size_t count)
+static inline void * memchr(const void * cs,int c,size_t count)
{
int d0;
register void * __res;
@@ -344,7 +344,7 @@ __asm__ __volatile__(
return __res;
}
-extern inline void * __memset_generic(void * s, char c,size_t count)
+static inline void * __memset_generic(void * s, char c,size_t count)
{
int d0, d1;
__asm__ __volatile__(
@@ -365,7 +365,7 @@ return s;
* things 32 bits at a time even when we don't know the size of the
* area at compile-time..
*/
-extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
+static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
{
int d0, d1;
__asm__ __volatile__(
@@ -386,7 +386,7 @@ return (s);
/* Added by Gertjan van Wingerde to make minix and sysv module work */
#define __HAVE_ARCH_STRNLEN
-extern inline size_t strnlen(const char * s, size_t count)
+static inline size_t strnlen(const char * s, size_t count)
{
int d0;
register int __res;
@@ -410,7 +410,7 @@ return __res;
* This looks horribly ugly, but the compiler can optimize it totally,
* as we by now know that both pattern and count is constant..
*/
-extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
+static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
{
switch (count) {
case 0:
@@ -469,7 +469,7 @@ __asm__ __volatile__("cld\n\t" \
* find the first occurrence of byte 'c', or 1 past the area if none
*/
#define __HAVE_ARCH_MEMSCAN
-extern inline void * memscan(void * addr, int c, size_t size)
+static inline void * memscan(void * addr, int c, size_t size)
{
if (!size)
return addr;
diff --git a/linux/dev/include/linux/blk.h b/linux/dev/include/linux/blk.h
index 412b8641..156d91c4 100644
--- a/linux/dev/include/linux/blk.h
+++ b/linux/dev/include/linux/blk.h
@@ -391,8 +391,9 @@ static void end_request(int uptodate) {
req->errors = 0;
if (!uptodate) {
- printk("end_request: I/O error, dev %s, sector %lu\n",
- kdevname(req->rq_dev), req->sector);
+ if (!req->quiet)
+ printk("end_request: I/O error, dev %s, sector %lu\n",
+ kdevname(req->rq_dev), req->sector);
#ifdef MACH
for (bh = req->bh; bh; )
{
diff --git a/linux/dev/include/linux/blkdev.h b/linux/dev/include/linux/blkdev.h
index e9a40d7e..5bf0a288 100644
--- a/linux/dev/include/linux/blkdev.h
+++ b/linux/dev/include/linux/blkdev.h
@@ -23,6 +23,7 @@ struct request {
kdev_t rq_dev;
int cmd; /* READ or WRITE */
int errors;
+ int quiet;
unsigned long sector;
unsigned long nr_sectors;
unsigned long current_nr_sectors;
diff --git a/linux/dev/include/linux/fs.h b/linux/dev/include/linux/fs.h
index 740ebb54..a2f9383e 100644
--- a/linux/dev/include/linux/fs.h
+++ b/linux/dev/include/linux/fs.h
@@ -638,7 +638,7 @@ extern int nr_buffer_heads;
#define NR_LIST 4
#ifdef MACH
-extern inline void
+static inline void
mark_buffer_uptodate (struct buffer_head *bh, int on)
{
if (on)
@@ -733,7 +733,7 @@ extern struct file * get_empty_filp(void);
extern int close_fp(struct file *filp);
extern struct buffer_head * get_hash_table(kdev_t dev, int block, int size);
extern struct buffer_head * getblk(kdev_t dev, int block, int size);
-extern void ll_rw_block(int rw, int nr, struct buffer_head * bh[]);
+extern void ll_rw_block(int rw, int nr, struct buffer_head * bh[], int quiet);
extern void ll_rw_page(int rw, kdev_t dev, unsigned long nr, char * buffer);
extern void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buffer);
extern int is_read_only(kdev_t dev);
diff --git a/linux/dev/include/linux/mm.h b/linux/dev/include/linux/mm.h
index 0500e0cf..cd061378 100644
--- a/linux/dev/include/linux/mm.h
+++ b/linux/dev/include/linux/mm.h
@@ -281,6 +281,7 @@ extern void * vmalloc(unsigned long size);
extern void * vremap(unsigned long offset, unsigned long size);
extern void vfree(void * addr);
extern int vread(char *buf, char *addr, int count);
+extern unsigned long vmtophys (void *);
/* mmap.c */
extern unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
diff --git a/linux/dev/include/linux/types.h b/linux/dev/include/linux/types.h
index 57bb25f4..b697d9ec 100644
--- a/linux/dev/include/linux/types.h
+++ b/linux/dev/include/linux/types.h
@@ -109,6 +109,15 @@ struct ustat {
char f_fpack[6];
};
+/* stdint.h */
+typedef s8 int8_t;
+typedef u8 uint8_t;
+typedef s16 int16_t;
+typedef u16 uint16_t;
+typedef s32 int32_t;
+typedef u32 uint32_t;
+typedef s64 int64_t;
+typedef u64 uint64_t;
/* Yes, this is ugly. But that's why it is called glue code. */
diff --git a/linux/pcmcia-cs/clients/axnet_cs.c b/linux/pcmcia-cs/clients/axnet_cs.c
index bcd79b0e..2e7d9edc 100644
--- a/linux/pcmcia-cs/clients/axnet_cs.c
+++ b/linux/pcmcia-cs/clients/axnet_cs.c
@@ -1814,7 +1814,7 @@ static void set_multicast_list(struct net_device *dev)
static int axdev_init(struct net_device *dev)
{
if (ei_debug > 1)
- printk(version_8390);
+ printk("%s", version_8390);
if (dev->priv == NULL)
{
diff --git a/linux/src/drivers/block/ide-cd.c b/linux/src/drivers/block/ide-cd.c
index e4548f54..020a8313 100644
--- a/linux/src/drivers/block/ide-cd.c
+++ b/linux/src/drivers/block/ide-cd.c
@@ -649,7 +649,7 @@ static void cdrom_end_request (int uptodate, ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
- if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate) {
+ if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate && !rq->quiet) {
struct packet_command *pc = (struct packet_command *)
rq->buffer;
cdrom_analyze_sense_data (drive,
@@ -727,16 +727,18 @@ static int cdrom_decode_status (ide_drive_t *drive, int good_stat,
because workman constantly polls the drive
with this command, and we don't want
to uselessly fill up the syslog. */
- if (pc->c[0] != SCMD_READ_SUBCHANNEL)
+ if (pc->c[0] != SCMD_READ_SUBCHANNEL && !rq->quiet)
printk ("%s : tray open or drive not ready\n",
drive->name);
} else if (sense_key == UNIT_ATTENTION) {
/* Check for media change. */
cdrom_saw_media_change (drive);
- printk ("%s: media changed\n", drive->name);
+ if (!rq->quiet)
+ printk ("%s: media changed\n", drive->name);
} else {
/* Otherwise, print an error. */
- ide_dump_status (drive, "packet command error",
+ if (!rq->quiet)
+ ide_dump_status (drive, "packet command error",
stat);
}
@@ -768,7 +770,8 @@ static int cdrom_decode_status (ide_drive_t *drive, int good_stat,
cdrom_saw_media_change (drive);
/* Fail the request. */
- printk ("%s : tray open\n", drive->name);
+ if (!rq->quiet)
+ printk ("%s : tray open\n", drive->name);
cdrom_end_request (0, drive);
} else if (sense_key == UNIT_ATTENTION) {
/* Media change. */
@@ -783,7 +786,8 @@ static int cdrom_decode_status (ide_drive_t *drive, int good_stat,
sense_key == DATA_PROTECT) {
/* No point in retrying after an illegal
request or data protect error.*/
- ide_dump_status (drive, "command error", stat);
+ if (!rq->quiet)
+ ide_dump_status (drive, "command error", stat);
cdrom_end_request (0, drive);
} else if ((err & ~ABRT_ERR) != 0) {
/* Go to the default handler
@@ -1406,7 +1410,7 @@ void cdrom_sleep (int time)
#endif
static
-int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
+int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc, int quiet)
{
struct atapi_request_sense my_reqbuf;
int retries = 10;
@@ -1423,6 +1427,7 @@ int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
ide_init_drive_cmd (&req);
req.cmd = PACKET_COMMAND;
req.buffer = (char *)pc;
+ req.quiet = quiet;
(void) ide_do_drive_cmd (drive, &req, ide_wait);
if (pc->stat != 0) {
@@ -1563,7 +1568,7 @@ cdrom_check_status (ide_drive_t *drive,
pc.c[7] = CDROM_STATE_FLAGS (drive)->sanyo_slot % 3;
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 1);
}
@@ -1588,7 +1593,7 @@ cdrom_lockdoor (ide_drive_t *drive, int lockflag,
pc.c[0] = ALLOW_MEDIUM_REMOVAL;
pc.c[4] = (lockflag != 0);
- stat = cdrom_queue_packet_command (drive, &pc);
+ stat = cdrom_queue_packet_command (drive, &pc, 0);
}
if (stat == 0)
@@ -1622,7 +1627,7 @@ cdrom_eject (ide_drive_t *drive, int ejectflag,
pc.c[0] = START_STOP;
pc.c[4] = 2 + (ejectflag != 0);
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1637,7 +1642,7 @@ cdrom_pause (ide_drive_t *drive, int pauseflag,
pc.c[0] = SCMD_PAUSE_RESUME;
pc.c[8] = !pauseflag;
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1653,7 +1658,7 @@ cdrom_startstop (ide_drive_t *drive, int startflag,
pc.c[0] = START_STOP;
pc.c[1] = 1;
pc.c[4] = startflag;
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1676,7 +1681,7 @@ cdrom_read_capacity (ide_drive_t *drive, unsigned *capacity,
pc.buffer = (unsigned char *)&capbuf;
pc.buflen = sizeof (capbuf);
- stat = cdrom_queue_packet_command (drive, &pc);
+ stat = cdrom_queue_packet_command (drive, &pc, 1);
if (stat == 0)
*capacity = ntohl (capbuf.lba);
@@ -1702,7 +1707,7 @@ cdrom_read_tocentry (ide_drive_t *drive, int trackno, int msf_flag,
pc.c[8] = (buflen & 0xff);
pc.c[9] = (format << 6);
if (msf_flag) pc.c[1] = 2;
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 1);
}
@@ -1834,7 +1839,7 @@ cdrom_read_subchannel (ide_drive_t *drive, int format,
pc.c[3] = format,
pc.c[7] = (buflen >> 8);
pc.c[8] = (buflen & 0xff);
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1855,7 +1860,7 @@ cdrom_mode_sense (ide_drive_t *drive, int pageno, int modeflag,
pc.c[2] = pageno | (modeflag << 6);
pc.c[7] = (buflen >> 8);
pc.c[8] = (buflen & 0xff);
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1875,7 +1880,7 @@ cdrom_mode_select (ide_drive_t *drive, int pageno, char *buf, int buflen,
pc.c[2] = pageno;
pc.c[7] = (buflen >> 8);
pc.c[8] = (buflen & 0xff);
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -1903,7 +1908,7 @@ cdrom_play_lba_range_1 (ide_drive_t *drive, int lba_start, int lba_end,
}
#endif /* not STANDARD_ATAPI */
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
@@ -2004,7 +2009,7 @@ cdrom_read_block (ide_drive_t *drive, int format, int lba, int nblocks,
else
pc.c[9] = 0x10;
- stat = cdrom_queue_packet_command (drive, &pc);
+ stat = cdrom_queue_packet_command (drive, &pc, 0);
#if ! STANDARD_ATAPI
/* If the drive doesn't recognize the READ CD opcode, retry the command
@@ -2059,7 +2064,7 @@ cdrom_load_unload (ide_drive_t *drive, int slot,
pc.c[0] = LOAD_UNLOAD;
pc.c[4] = 2 + (slot >= 0);
pc.c[8] = slot;
- return cdrom_queue_packet_command (drive, &pc);
+ return cdrom_queue_packet_command (drive, &pc, 0);
}
}
@@ -2575,7 +2580,7 @@ int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
pc.buffer = buf;
}
- stat = cdrom_queue_packet_command (drive, &pc);
+ stat = cdrom_queue_packet_command (drive, &pc, 0);
if (len > 0)
memcpy_tofs ((void *)arg, buf, len);
@@ -2638,6 +2643,10 @@ int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive)
if (stat == 0 || my_reqbuf.sense_key == UNIT_ATTENTION) {
(void) cdrom_lockdoor (drive, 1, &my_reqbuf);
(void) cdrom_read_toc (drive, &my_reqbuf);
+ } else {
+ /* Otherwise return as missing */
+ --drive->usage;
+ return -ENXIO;
}
}
diff --git a/linux/src/drivers/block/ide.c b/linux/src/drivers/block/ide.c
index 7ab790d4..41a26017 100644
--- a/linux/src/drivers/block/ide.c
+++ b/linux/src/drivers/block/ide.c
@@ -302,6 +302,8 @@
#include <linux/genhd.h>
#include <linux/malloc.h>
+#include <ahci.h>
+
#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/segment.h>
@@ -1925,6 +1927,7 @@ void ide_init_drive_cmd (struct request *rq)
rq->rq_status = RQ_ACTIVE;
rq->rq_dev = ????;
#endif
+ rq->quiet = 0;
}
/*
@@ -2523,7 +2526,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
drive->media = ide_tape;
drive->present = 1;
drive->removable = 1;
- if (drive->autotune != 2 && HWIF(drive)->dmaproc != NULL) {
+ if (drive->autotune != 2 && HWIF(drive)->dmaproc != NULL && !drive->nodma) {
if (!HWIF(drive)->dmaproc(ide_dma_check, drive))
printk(", DMA");
}
@@ -2650,7 +2653,7 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect))
drive->special.b.set_multmode = 1;
}
- if (drive->autotune != 2 && HWIF(drive)->dmaproc != NULL) {
+ if (drive->autotune != 2 && HWIF(drive)->dmaproc != NULL && !drive->nodma) {
if (!(HWIF(drive)->dmaproc(ide_dma_check, drive))) {
if ((id->field_valid & 4) && (id->dma_ultra & (id->dma_ultra >> 8) & 7))
printk(", UDMA");
@@ -3105,6 +3108,7 @@ static int match_parm (char *s, const char *keywords[], int vals[], int max_vals
* Not fully supported by all chipset types,
* and quite likely to cause trouble with
* older/odd IDE drives.
+ * "hdx=nodma" : disallow DMA for the drive
*
* "idebus=xx" : inform IDE driver of VESA/PCI bus speed in Mhz,
* where "xx" is between 20 and 66 inclusive,
@@ -3149,7 +3153,11 @@ void ide_setup (char *s)
ide_hwif_t *hwif;
ide_drive_t *drive;
unsigned int hw, unit;
+#ifdef MACH
+ const char max_drive = '0' + ((MAX_HWIFS * MAX_DRIVES) - 1);
+#else
const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
+#endif
const char max_hwif = '0' + (MAX_HWIFS - 1);
printk("ide_setup: %s", s);
@@ -3158,11 +3166,19 @@ void ide_setup (char *s)
/*
* Look for drive options: "hdx="
*/
+#ifdef MACH
+ if (s[0] == 'h' && s[1] == 'd' && s[2] >= '0' && s[2] <= max_drive) {
+#else
if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
+#endif
const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom",
"serialize", "autotune", "noautotune",
- "slow", "ide-scsi", NULL};
+ "slow", "ide-scsi", "nodma", NULL};
+#ifdef MACH
+ unit = s[2] - '0';
+#else
unit = s[2] - 'a';
+#endif
hw = unit / MAX_DRIVES;
unit = unit % MAX_DRIVES;
hwif = &ide_hwifs[hw];
@@ -3197,6 +3213,9 @@ void ide_setup (char *s)
case -9: /* "ide-scsi" */
drive->ide_scsi = 1;
goto done;
+ case -10: /* "nodma" */
+ drive->nodma = 1;
+ goto done;
case 3: /* cyl,head,sect */
drive->media = ide_disk;
drive->cyl = drive->bios_cyl = vals[0];
@@ -3682,6 +3701,7 @@ static void probe_for_hwifs (void)
#ifdef CONFIG_BLK_DEV_PROMISE
init_dc4030();
#endif
+ ahci_probe_pci();
}
static int hwif_init (int h)
diff --git a/linux/src/drivers/block/ide.h b/linux/src/drivers/block/ide.h
index edeedc97..28e371bf 100644
--- a/linux/src/drivers/block/ide.h
+++ b/linux/src/drivers/block/ide.h
@@ -344,6 +344,7 @@ typedef struct ide_drive_s {
unsigned nobios : 1; /* flag: do not probe bios for drive */
unsigned slow : 1; /* flag: slow data port */
unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */
+ unsigned nodma : 1; /* disk should not use dma for read/write */
#if FAKE_FDISK_FOR_EZDRIVE
unsigned remap_0_to_1 : 1; /* flag: partitioned with ezdrive */
#endif /* FAKE_FDISK_FOR_EZDRIVE */
diff --git a/linux/src/drivers/net/3c507.c b/linux/src/drivers/net/3c507.c
index 63f85a4c..58ba2d75 100644
--- a/linux/src/drivers/net/3c507.c
+++ b/linux/src/drivers/net/3c507.c
@@ -354,7 +354,7 @@ int el16_probe1(struct device *dev, int ioaddr)
dev = init_etherdev(0, sizeof(struct net_local));
if (net_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("%s: 3c507 at %#x,", dev->name, ioaddr);
@@ -410,7 +410,7 @@ int el16_probe1(struct device *dev, int ioaddr)
dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
if (net_debug)
- printk(version);
+ printk("%s", version);
/* Initialize the device structure. */
dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
diff --git a/linux/src/drivers/net/3c509.c b/linux/src/drivers/net/3c509.c
index f8842882..727595cd 100644
--- a/linux/src/drivers/net/3c509.c
+++ b/linux/src/drivers/net/3c509.c
@@ -314,7 +314,7 @@ int el3_probe(struct device *dev)
el3_root_dev = dev;
if (el3_debug > 0)
- printk(version);
+ printk("%s", version);
/* The EL3-specific entries in the device structure. */
dev->open = &el3_open;
diff --git a/linux/src/drivers/net/3c515.c b/linux/src/drivers/net/3c515.c
index fd6ec50c..52f47032 100644
--- a/linux/src/drivers/net/3c515.c
+++ b/linux/src/drivers/net/3c515.c
@@ -404,7 +404,7 @@ init_module(void)
if (debug >= 0)
vortex_debug = debug;
if (vortex_debug)
- printk(version);
+ printk("%s", version);
root_vortex_dev = NULL;
cards_found = vortex_scan(0);
@@ -419,7 +419,7 @@ int tc515_probe(struct device *dev)
cards_found = vortex_scan(dev);
if (vortex_debug > 0 && cards_found)
- printk(version);
+ printk("%s", version);
return cards_found ? 0 : -ENODEV;
}
diff --git a/linux/src/drivers/net/ac3200.c b/linux/src/drivers/net/ac3200.c
index 0337bab7..600949fa 100644
--- a/linux/src/drivers/net/ac3200.c
+++ b/linux/src/drivers/net/ac3200.c
@@ -208,7 +208,7 @@ static int ac_probe1(int ioaddr, struct device *dev)
dev->mem_start, dev->mem_end-1);
if (ei_debug > 0)
- printk(version);
+ printk("%s", version);
ei_status.reset_8390 = &ac_reset_8390;
ei_status.block_input = &ac_block_input;
diff --git a/linux/src/drivers/net/apricot.c b/linux/src/drivers/net/apricot.c
index d106e50d..57fccafb 100644
--- a/linux/src/drivers/net/apricot.c
+++ b/linux/src/drivers/net/apricot.c
@@ -720,7 +720,7 @@ int apricot_probe(struct device *dev)
dev->irq = 10;
printk(" IRQ %d.\n", dev->irq);
- if (i596_debug > 0) printk(version);
+ if (i596_debug > 0) printk("%s", version);
/* The APRICOT-specific entries in the device structure. */
dev->open = &i596_open;
diff --git a/linux/src/drivers/net/at1700.c b/linux/src/drivers/net/at1700.c
index 9e42ab48..f4025f46 100644
--- a/linux/src/drivers/net/at1700.c
+++ b/linux/src/drivers/net/at1700.c
@@ -258,7 +258,7 @@ int at1700_probe1(struct device *dev, int ioaddr)
outb(0x00, ioaddr + CONFIG_1);
if (net_debug)
- printk(version);
+ printk("%s", version);
/* Initialize the device structure. */
dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
diff --git a/linux/src/drivers/net/de4x5.c b/linux/src/drivers/net/de4x5.c
index a66f0564..c85bcdbf 100644
--- a/linux/src/drivers/net/de4x5.c
+++ b/linux/src/drivers/net/de4x5.c
@@ -1308,7 +1308,7 @@ de4x5_hw_init(struct device *dev, u_long iobase))
}
if (de4x5_debug & DEBUG_VERSION) {
- printk(version);
+ printk("%s", version);
}
/* The DE4X5-specific entries in the device structure. */
diff --git a/linux/src/drivers/net/de600.c b/linux/src/drivers/net/de600.c
index 2488cd76..ce969422 100644
--- a/linux/src/drivers/net/de600.c
+++ b/linux/src/drivers/net/de600.c
@@ -644,7 +644,7 @@ de600_probe(struct device *dev)
printk("%s: D-Link DE-600 pocket adapter", dev->name);
/* Alpha testers must have the version number to report bugs. */
if (de600_debug > 1)
- printk(version);
+ printk("%s", version);
/* probe for adapter */
rx_page = 0;
diff --git a/linux/src/drivers/net/de620.c b/linux/src/drivers/net/de620.c
index ec639101..0e0c5522 100644
--- a/linux/src/drivers/net/de620.c
+++ b/linux/src/drivers/net/de620.c
@@ -843,7 +843,7 @@ de620_probe(struct device *dev)
dev->irq = irq;
if (de620_debug)
- printk(version);
+ printk("%s", version);
printk("D-Link DE-620 pocket adapter");
diff --git a/linux/src/drivers/net/depca.c b/linux/src/drivers/net/depca.c
index e1b03429..2048812d 100644
--- a/linux/src/drivers/net/depca.c
+++ b/linux/src/drivers/net/depca.c
@@ -649,7 +649,7 @@ depca_hw_init(struct device *dev, u_long ioaddr)
}
if (!status) {
if (depca_debug > 1) {
- printk(version);
+ printk("%s", version);
}
/* The DEPCA-specific entries in the device structure. */
diff --git a/linux/src/drivers/net/e2100.c b/linux/src/drivers/net/e2100.c
index 7ba12d31..537295a2 100644
--- a/linux/src/drivers/net/e2100.c
+++ b/linux/src/drivers/net/e2100.c
@@ -162,7 +162,7 @@ int e21_probe1(struct device *dev, int ioaddr)
outb(0, ioaddr + E21_ASIC); /* and disable the secondary interface. */
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
/* We should have a "dev" from Space.c or the static module table. */
if (dev == NULL) {
diff --git a/linux/src/drivers/net/eepro.c b/linux/src/drivers/net/eepro.c
index 2c3a6b26..3d4fc578 100644
--- a/linux/src/drivers/net/eepro.c
+++ b/linux/src/drivers/net/eepro.c
@@ -498,7 +498,7 @@ eepro_probe1(struct device *dev, short ioaddr)
}
if (net_debug)
- printk(version);
+ printk("%s", version);
/* Grab the region so we can find another board if autoIRQ fails. */
request_region(ioaddr, EEPRO_IO_EXTENT, "eepro");
diff --git a/linux/src/drivers/net/eepro100.c b/linux/src/drivers/net/eepro100.c
index 6909cdc4..d03462cd 100644
--- a/linux/src/drivers/net/eepro100.c
+++ b/linux/src/drivers/net/eepro100.c
@@ -726,7 +726,7 @@ static void *speedo_found1(struct pci_dev *pdev, void *init_dev,
eeprom[8], eeprom[9]>>8, eeprom[9] & 0xff);
for (i = 0; i < 4; i++)
if (eeprom[5] & (1<<i))
- printk(connectors[i]);
+ printk("%s", connectors[i]);
printk("\n"KERN_INFO" Primary interface chip %s PHY #%d.\n",
phys[(eeprom[6]>>8)&15], eeprom[6] & 0x1f);
if (eeprom[7] & 0x0700)
diff --git a/linux/src/drivers/net/eexpress.c b/linux/src/drivers/net/eexpress.c
index d7065509..9c816ee9 100644
--- a/linux/src/drivers/net/eexpress.c
+++ b/linux/src/drivers/net/eexpress.c
@@ -794,7 +794,7 @@ static int eexp_hw_probe(struct device *dev, unsigned short ioaddr)
}
if (net_debug)
- printk(version);
+ printk("%s", version);
dev->open = eexp_open;
dev->stop = eexp_close;
dev->hard_start_xmit = eexp_xmit;
diff --git a/linux/src/drivers/net/ewrk3.c b/linux/src/drivers/net/ewrk3.c
index f91315ff..07b0f13f 100644
--- a/linux/src/drivers/net/ewrk3.c
+++ b/linux/src/drivers/net/ewrk3.c
@@ -589,7 +589,7 @@ ewrk3_hw_init(struct device *dev, u_long iobase)
if (!status) {
if (ewrk3_debug > 1) {
- printk(version);
+ printk("%s", version);
}
/* The EWRK3-specific entries in the device structure. */
diff --git a/linux/src/drivers/net/fmv18x.c b/linux/src/drivers/net/fmv18x.c
index 121dd0bb..b29ddf00 100644
--- a/linux/src/drivers/net/fmv18x.c
+++ b/linux/src/drivers/net/fmv18x.c
@@ -249,7 +249,7 @@ int fmv18x_probe1(struct device *dev, short ioaddr)
outb(dev->if_port, ioaddr + MODE13);
if (net_debug)
- printk(version);
+ printk("%s", version);
/* Initialize the device structure. */
dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
diff --git a/linux/src/drivers/net/hp-plus.c b/linux/src/drivers/net/hp-plus.c
index c8e36111..c2b71169 100644
--- a/linux/src/drivers/net/hp-plus.c
+++ b/linux/src/drivers/net/hp-plus.c
@@ -164,7 +164,7 @@ int hpp_probe1(struct device *dev, int ioaddr)
}
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("%s: %s at %#3x,", dev->name, name, ioaddr);
diff --git a/linux/src/drivers/net/hp.c b/linux/src/drivers/net/hp.c
index 741924f9..6ddbfd2e 100644
--- a/linux/src/drivers/net/hp.c
+++ b/linux/src/drivers/net/hp.c
@@ -136,7 +136,7 @@ int hp_probe1(struct device *dev, int ioaddr)
}
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);
diff --git a/linux/src/drivers/net/lance.c b/linux/src/drivers/net/lance.c
index f64f0fee..fe3cf687 100644
--- a/linux/src/drivers/net/lance.c
+++ b/linux/src/drivers/net/lance.c
@@ -674,7 +674,7 @@ int lance_probe1(struct device *dev, int ioaddr, int irq, int options)
}
if (lance_debug > 0 && did_version++ == 0)
- printk(version);
+ printk("%s", version);
/* The LANCE-specific entries in the device structure. */
dev->open = lance_open;
diff --git a/linux/src/drivers/net/ne.c b/linux/src/drivers/net/ne.c
index 825b768e..ea2f9290 100644
--- a/linux/src/drivers/net/ne.c
+++ b/linux/src/drivers/net/ne.c
@@ -291,7 +291,7 @@ static int ne_probe1(struct device *dev, int ioaddr)
}
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("NE*000 ethercard probe at %#3x:", ioaddr);
diff --git a/linux/src/drivers/net/pci-scan.c b/linux/src/drivers/net/pci-scan.c
index 60525b76..ffb7b128 100644
--- a/linux/src/drivers/net/pci-scan.c
+++ b/linux/src/drivers/net/pci-scan.c
@@ -31,7 +31,7 @@ static int min_pci_latency = 32;
#if ! defined(__KERNEL__)
#define __KERNEL__ 1
#endif
-#if !defined(__OPTIMIZE__)
+#if !defined(__OPTIMIZE__) && /* Mach glue, we think this is ok now: */ 0
#warning You must compile this file with the correct options!
#warning See the last lines of the source file.
#error You must compile this driver with the proper options, including "-O".
diff --git a/linux/src/drivers/net/pcnet32.c b/linux/src/drivers/net/pcnet32.c
index 02e70982..da0e8709 100644
--- a/linux/src/drivers/net/pcnet32.c
+++ b/linux/src/drivers/net/pcnet32.c
@@ -344,7 +344,7 @@ static int pcnet32_probe1(struct device *dev, unsigned int ioaddr, unsigned char
dev->irq = irq_line;
if (pcnet32_debug > 0)
- printk(version);
+ printk("%s", version);
/* The PCNET32-specific entries in the device structure. */
dev->open = &pcnet32_open;
diff --git a/linux/src/drivers/net/seeq8005.c b/linux/src/drivers/net/seeq8005.c
index c4d48521..4adebdea 100644
--- a/linux/src/drivers/net/seeq8005.c
+++ b/linux/src/drivers/net/seeq8005.c
@@ -274,7 +274,7 @@ static int seeq8005_probe1(struct device *dev, int ioaddr)
dev = init_etherdev(0, sizeof(struct net_local));
if (net_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr);
diff --git a/linux/src/drivers/net/smc-ultra.c b/linux/src/drivers/net/smc-ultra.c
index 074a235b..f593aeb6 100644
--- a/linux/src/drivers/net/smc-ultra.c
+++ b/linux/src/drivers/net/smc-ultra.c
@@ -156,7 +156,7 @@ int ultra_probe1(struct device *dev, int ioaddr)
dev = init_etherdev(0, 0);
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
model_name = (idreg & 0xF0) == 0x20 ? "SMC Ultra" : "SMC EtherEZ";
diff --git a/linux/src/drivers/net/smc-ultra32.c b/linux/src/drivers/net/smc-ultra32.c
index f616e259..6cde4c27 100644
--- a/linux/src/drivers/net/smc-ultra32.c
+++ b/linux/src/drivers/net/smc-ultra32.c
@@ -153,7 +153,7 @@ int ultra32_probe1(struct device *dev, int ioaddr)
}
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
model_name = "SMC Ultra32";
diff --git a/linux/src/drivers/net/sundance.c b/linux/src/drivers/net/sundance.c
index 47f32ebd..37231644 100644
--- a/linux/src/drivers/net/sundance.c
+++ b/linux/src/drivers/net/sundance.c
@@ -986,7 +986,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
if (np->msg_level & NETIF_MSG_TX_QUEUED) {
- printk(KERN_DEBUG "%s: Transmit frame #%d len %ld queued in slot %ld.\n",
+ printk(KERN_DEBUG "%s: Transmit frame #%d len %ld queued in slot %u.\n",
dev->name, np->cur_tx, skb->len, entry);
}
return 0;
diff --git a/linux/src/drivers/net/tlan.c b/linux/src/drivers/net/tlan.c
index 11e12bbc..fedc11f3 100644
--- a/linux/src/drivers/net/tlan.c
+++ b/linux/src/drivers/net/tlan.c
@@ -1132,7 +1132,7 @@ u32 TLan_HandleTxEOF( struct device *dev, u16 host_int )
if ( head_list->cStat & TLAN_CSTAT_EOC )
eoc = 1;
- if ( ! head_list->cStat & TLAN_CSTAT_FRM_CMP ) {
+ if (!(head_list->cStat & TLAN_CSTAT_FRM_CMP)) {
printk( "TLAN: Received interrupt for uncompleted TX frame.\n" );
}
@@ -1244,7 +1244,7 @@ u32 TLan_HandleRxEOF( struct device *dev, u16 host_int )
eoc = 1;
}
- if ( ! head_list->cStat & TLAN_CSTAT_FRM_CMP ) {
+ if (!(head_list->cStat & TLAN_CSTAT_FRM_CMP)) {
printk( "TLAN: Received interrupt for uncompleted RX frame.\n" );
} else if ( bbuf ) {
skb = dev_alloc_skb( head_list->frameSize + 7 );
diff --git a/linux/src/drivers/net/wd.c b/linux/src/drivers/net/wd.c
index a737a01d..dd879021 100644
--- a/linux/src/drivers/net/wd.c
+++ b/linux/src/drivers/net/wd.c
@@ -137,7 +137,7 @@ int wd_probe1(struct device *dev, int ioaddr)
}
if (ei_debug && version_printed++ == 0)
- printk(version);
+ printk("%s", version);
printk("%s: WD80x3 at %#3x, ", dev->name, ioaddr);
for (i = 0; i < 6; i++)
diff --git a/linux/src/drivers/scsi/AM53C974.c b/linux/src/drivers/scsi/AM53C974.c
index 5178ccf7..da139ced 100644
--- a/linux/src/drivers/scsi/AM53C974.c
+++ b/linux/src/drivers/scsi/AM53C974.c
@@ -1919,7 +1919,7 @@ if ((statreg & STATREG_PHASE) != PHASE_MSGIN) {
goto EXIT_ABORT; }
msg[0] = AM53C974_read_8(FFREG);
-if (!msg[0] & 0x80) {
+if (!(msg[0] & 0x80)) {
printk("scsi%d: error: expecting IDENTIFY message, got ", instance->host_no);
print_msg(msg);
hostdata->aborted = 1;
diff --git a/linux/src/drivers/scsi/FlashPoint.c b/linux/src/drivers/scsi/FlashPoint.c
index aae35c03..8d2f1020 100644
--- a/linux/src/drivers/scsi/FlashPoint.c
+++ b/linux/src/drivers/scsi/FlashPoint.c
@@ -3756,17 +3756,17 @@ STATIC int SetDevSyncRate(PSCCBcard pCurrCard, PUCB p_ucb)
}
if(currTar_Info->TarEEValue && EE_SYNC_MASK == syncVal)
return(0);
- currTar_Info->TarEEValue = (currTar_Info->TarEEValue & !EE_SYNC_MASK)
+ currTar_Info->TarEEValue = (!(EE_SYNC_MASK & currTar_Info->TarEEValue))
| syncVal;
syncOffset = (SYNC_RATE_TBL + scsiID) / 2;
temp2.tempw = utilEERead(ioPort, syncOffset);
if(scsiID & 0x01)
{
- temp2.tempb[0] = (temp2.tempb[0] & !EE_SYNC_MASK) | syncVal;
+ temp2.tempb[0] = (!(EE_SYNC_MASK & temp2.tempb[0])) | syncVal;
}
else
{
- temp2.tempb[1] = (temp2.tempb[1] & !EE_SYNC_MASK) | syncVal;
+ temp2.tempb[1] = (!(EE_SYNC_MASK & temp2.tempb[1])) | syncVal;
}
utilEEWriteOnOff(ioPort, 1);
utilEEWrite(ioPort, temp2.tempw, syncOffset);
@@ -3845,7 +3845,7 @@ int SetDevWideMode(PSCCBcard pCurrCard,PUCB p_ucb)
}
else
{
- if(!currTar_Info->TarEEValue & EE_WIDE_SCSI)
+ if(!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
{
return(0);
}
@@ -3854,18 +3854,18 @@ int SetDevWideMode(PSCCBcard pCurrCard,PUCB p_ucb)
scsiWideMode = 0;
}
}
- currTar_Info->TarEEValue = (currTar_Info->TarEEValue & !EE_WIDE_SCSI)
+ currTar_Info->TarEEValue = (!(EE_WIDE_SCSI & currTar_Info->TarEEValue))
| scsiWideMode;
syncOffset = (SYNC_RATE_TBL + scsiID) / 2;
temp2.tempw = utilEERead(ioPort, syncOffset);
if(scsiID & 0x01)
{
- temp2.tempb[0] = (temp2.tempb[0] & !EE_WIDE_SCSI) | scsiWideMode;
+ temp2.tempb[0] = (!(EE_WIDE_SCSI & temp2.tempb[0])) | scsiWideMode;
}
else
{
- temp2.tempb[1] = (temp2.tempb[1] & !EE_WIDE_SCSI) | scsiWideMode;
+ temp2.tempb[1] = (!(EE_WIDE_SCSI & temp2.tempb[1])) | scsiWideMode;
}
utilEEWriteOnOff(ioPort, 1);
utilEEWrite(ioPort, temp2.tempw, syncOffset);
diff --git a/linux/src/drivers/scsi/NCR5380.c b/linux/src/drivers/scsi/NCR5380.c
index 295f2ad2..4f085e9b 100644
--- a/linux/src/drivers/scsi/NCR5380.c
+++ b/linux/src/drivers/scsi/NCR5380.c
@@ -1949,7 +1949,7 @@ static int do_abort (struct Scsi_Host *host) {
* the target sees, so we just handshake.
*/
- while (!(tmp = NCR5380_read(STATUS_REG)) & SR_REQ);
+ while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ));
NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
@@ -2900,7 +2900,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance) {
NCR5380_transfer_pio(instance, &phase, &len, &data);
- if (!msg[0] & 0x80) {
+ if (!(msg[0] & 0x80)) {
printk("scsi%d : expecting IDENTIFY message, got ",
instance->host_no);
print_msg(msg);
diff --git a/linux/src/drivers/scsi/t128.c b/linux/src/drivers/scsi/t128.c
index d4c7452b..198e910b 100644
--- a/linux/src/drivers/scsi/t128.c
+++ b/linux/src/drivers/scsi/t128.c
@@ -327,7 +327,7 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
for (; i; --i) {
while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
#else
- while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
+ while (!((instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY)) barrier();
for (; i; --i) {
#endif
*d++ = *reg;
@@ -370,7 +370,7 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src
for (; i; --i) {
while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
#else
- while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
+ while (!((instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY)) barrier();
for (; i; --i) {
#endif
*reg = *s++;
diff --git a/linux/src/include/asm-i386/bitops.h b/linux/src/include/asm-i386/bitops.h
index fc4cf192..e2a4c14a 100644
--- a/linux/src/include/asm-i386/bitops.h
+++ b/linux/src/include/asm-i386/bitops.h
@@ -28,7 +28,7 @@ struct __dummy { unsigned long a[100]; };
#define ADDR (*(struct __dummy *) addr)
#define CONST_ADDR (*(const struct __dummy *) addr)
-extern __inline__ int set_bit(int nr, SMPVOL void * addr)
+static __inline__ int set_bit(int nr, SMPVOL void * addr)
{
int oldbit;
@@ -39,7 +39,7 @@ extern __inline__ int set_bit(int nr, SMPVOL void * addr)
return oldbit;
}
-extern __inline__ int clear_bit(int nr, SMPVOL void * addr)
+static __inline__ int clear_bit(int nr, SMPVOL void * addr)
{
int oldbit;
@@ -50,7 +50,7 @@ extern __inline__ int clear_bit(int nr, SMPVOL void * addr)
return oldbit;
}
-extern __inline__ int change_bit(int nr, SMPVOL void * addr)
+static __inline__ int change_bit(int nr, SMPVOL void * addr)
{
int oldbit;
@@ -61,7 +61,7 @@ extern __inline__ int change_bit(int nr, SMPVOL void * addr)
return oldbit;
}
-extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
+static __inline__ int test_and_set_bit(int nr, volatile void * addr)
{
int oldbit;
@@ -72,7 +72,7 @@ extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
return oldbit;
}
-extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
{
int oldbit;
@@ -83,7 +83,7 @@ extern __inline__ int test_and_clear_bit(int nr, volatile void * addr)
return oldbit;
}
-extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
+static __inline__ int test_and_change_bit(int nr, volatile void * addr)
{
int oldbit;
@@ -98,7 +98,7 @@ extern __inline__ int test_and_change_bit(int nr, volatile void * addr)
/*
* This routine doesn't need to be atomic.
*/
-extern __inline__ int test_bit(int nr, const SMPVOL void * addr)
+static __inline__ int test_bit(int nr, const SMPVOL void * addr)
{
return ((1UL << (nr & 31)) & (((const unsigned int *) addr)[nr >> 5])) != 0;
}
@@ -106,8 +106,9 @@ extern __inline__ int test_bit(int nr, const SMPVOL void * addr)
/*
* Find-bit routines..
*/
-extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
+static __inline__ int find_first_zero_bit(void * addr, unsigned size)
{
+ int d0, d1, d2;
int res;
if (!size)
@@ -123,13 +124,12 @@ extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
"1:\tsubl %%ebx,%%edi\n\t"
"shll $3,%%edi\n\t"
"addl %%edi,%%edx"
- :"=d" (res)
- :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
- :"ax", "cx", "di");
+ :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
+ :"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
return res;
}
-extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
+static __inline__ int find_next_zero_bit (void * addr, int size, int offset)
{
unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
int set = 0, bit = offset & 31, res;
@@ -160,7 +160,7 @@ extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
* ffz = Find First Zero in word. Undefined if no zero exists,
* so code should check against ~0UL first..
*/
-extern __inline__ unsigned long ffz(unsigned long word)
+static __inline__ unsigned long ffz(unsigned long word)
{
__asm__("bsfl %1,%0"
:"=r" (word)
@@ -176,7 +176,7 @@ extern __inline__ unsigned long ffz(unsigned long word)
* differs in spirit from the above ffz (man ffs).
*/
-extern __inline__ int ffs(int x)
+static __inline__ int ffs(int x)
{
int r;
diff --git a/linux/src/include/asm-i386/io.h b/linux/src/include/asm-i386/io.h
index f961f1d2..34cf105b 100644
--- a/linux/src/include/asm-i386/io.h
+++ b/linux/src/include/asm-i386/io.h
@@ -45,12 +45,12 @@
* make the kernel segment mapped at 0, we need to do translation
* on the i386 as well)
*/
-extern inline unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(volatile void * address)
{
return (unsigned long) _kvtophys(address);
}
-extern inline void * phys_to_virt(unsigned long address)
+static inline void * phys_to_virt(unsigned long address)
{
return (void *) phystokv(address);
}
@@ -90,7 +90,7 @@ extern inline void * phys_to_virt(unsigned long address)
*/
#define __OUT1(s,x) \
-extern inline void __out##s(unsigned x value, unsigned short port) {
+static inline void __out##s(unsigned x value, unsigned short port) {
#define __OUT2(s,s1,s2) \
__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
@@ -102,7 +102,7 @@ __OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \
__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; }
#define __IN1(s) \
-extern inline RETURN_TYPE __in##s(unsigned short port) { RETURN_TYPE _v;
+static inline RETURN_TYPE __in##s(unsigned short port) { RETURN_TYPE _v;
#define __IN2(s,s1,s2) \
__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
@@ -114,12 +114,12 @@ __IN1(s##_p) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; retu
__IN1(s##c_p) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; }
#define __INS(s) \
-extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
+static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
{ __asm__ __volatile__ ("cld ; rep ; ins" #s \
: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
#define __OUTS(s) \
-extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
+static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
diff --git a/linux/src/include/asm-i386/segment.h b/linux/src/include/asm-i386/segment.h
index 5f8af993..d23aa173 100644
--- a/linux/src/include/asm-i386/segment.h
+++ b/linux/src/include/asm-i386/segment.h
@@ -60,7 +60,11 @@ static inline void __attribute__((always_inline)) __put_user(unsigned long x, vo
:"ir" (x), "m" (*__sd(y)));
break;
default:
+#ifdef __OPTIMIZE__
bad_user_access_length();
+#else
+ asm volatile("ud2");
+#endif
}
}
@@ -85,7 +89,11 @@ static inline unsigned long __attribute__((always_inline)) __get_user(const void
:"m" (*__const_sd(y)));
return result;
default:
+#ifdef __OPTIMIZE__
return bad_user_access_length();
+#else
+ asm volatile("ud2");
+#endif
}
}
diff --git a/linux/src/include/asm-i386/semaphore.h b/linux/src/include/asm-i386/semaphore.h
index 1486d1c1..18e12c10 100644
--- a/linux/src/include/asm-i386/semaphore.h
+++ b/linux/src/include/asm-i386/semaphore.h
@@ -30,6 +30,10 @@ struct semaphore {
#define MUTEX ((struct semaphore) { 1, 0, 0, NULL })
#define MUTEX_LOCKED ((struct semaphore) { 0, 0, 0, NULL })
+/* Special register calling convention:
+ * eax contains return address
+ * ecx contains semaphore address
+ */
asmlinkage void down_failed(void /* special register calling convention */);
asmlinkage void up_wakeup(void /* special register calling convention */);
@@ -41,20 +45,21 @@ extern void __up(struct semaphore * sem);
* "down_failed" is a special asm handler that calls the C
* routine that actually waits. See arch/i386/lib/semaphore.S
*/
-extern inline void down(struct semaphore * sem)
+static inline void down(struct semaphore * sem)
{
+ int d0;
__asm__ __volatile__(
"# atomic down operation\n\t"
"movl $1f,%%eax\n\t"
#ifdef __SMP__
"lock ; "
#endif
- "decl 0(%0)\n\t"
+ "decl %1\n\t"
"js " SYMBOL_NAME_STR(down_failed) "\n"
"1:\n"
- :/* no outputs */
+ :"=&a" (d0), "=m" (sem->count)
:"c" (sem)
- :"ax","dx","memory");
+ :"memory");
}
/*
@@ -81,7 +86,7 @@ asmlinkage int down_failed_interruptible(void); /* params in registers */
* process can be killed. The down_failed_interruptible routine
* returns negative for signalled and zero for semaphore acquired.
*/
-extern inline int down_interruptible(struct semaphore * sem)
+static inline int down_interruptible(struct semaphore * sem)
{
int ret ;
@@ -91,13 +96,13 @@ extern inline int down_interruptible(struct semaphore * sem)
#ifdef __SMP__
"lock ; "
#endif
- "decl 0(%1)\n\t"
+ "decl %1\n\t"
"js " SYMBOL_NAME_STR(down_failed_interruptible) "\n\t"
"xorl %%eax,%%eax\n"
"2:\n"
- :"=a" (ret)
+ :"=&a" (ret), "=m" (sem->count)
:"c" (sem)
- :"ax","dx","memory");
+ :"memory");
return(ret) ;
}
@@ -108,20 +113,21 @@ extern inline int down_interruptible(struct semaphore * sem)
* The default case (no contention) will result in NO
* jumps for both down() and up().
*/
-extern inline void up(struct semaphore * sem)
+static inline void up(struct semaphore * sem)
{
+ int d0;
__asm__ __volatile__(
"# atomic up operation\n\t"
"movl $1f,%%eax\n\t"
#ifdef __SMP__
"lock ; "
#endif
- "incl 0(%0)\n\t"
+ "incl %1\n\t"
"jle " SYMBOL_NAME_STR(up_wakeup)
"\n1:"
- :/* no outputs */
+ :"=&a" (d0), "=m" (sem->count)
:"c" (sem)
- :"ax", "dx", "memory");
+ :"memory");
}
#endif
diff --git a/linux/src/include/linux/compiler-gcc5.h b/linux/src/include/linux/compiler-gcc5.h
new file mode 100644
index 00000000..efee4937
--- /dev/null
+++ b/linux/src/include/linux/compiler-gcc5.h
@@ -0,0 +1,67 @@
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc5.h> directly, include <linux/compiler.h> instead."
+#endif
+
+#define __used __attribute__((__used__))
+#define __must_check __attribute__((warn_unused_result))
+#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
+
+/* Mark functions as cold. gcc will assume any path leading to a call
+ to them will be unlikely. This means a lot of manual unlikely()s
+ are unnecessary now for any paths leading to the usual suspects
+ like BUG(), printk(), panic() etc. [but let's keep them for now for
+ older compilers]
+
+ Early snapshots of gcc 4.3 don't support this and we can't detect this
+ in the preprocessor, but we can live with this because they're unreleased.
+ Maketime probing would be overkill here.
+
+ gcc also has a __attribute__((__hot__)) to move hot functions into
+ a special section, but I don't see any sense in this right now in
+ the kernel context */
+#define __cold __attribute__((__cold__))
+
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
+
+#ifndef __CHECKER__
+# define __compiletime_warning(message) __attribute__((warning(message)))
+# define __compiletime_error(message) __attribute__((error(message)))
+#endif /* __CHECKER__ */
+
+/*
+ * Mark a position in code as unreachable. This can be used to
+ * suppress control flow warnings after asm blocks that transfer
+ * control elsewhere.
+ *
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
+ * this in the preprocessor, but we can live with this because they're
+ * unreleased. Really, we need to have autoconf for the kernel.
+ */
+#define unreachable() __builtin_unreachable()
+
+/* Mark a function definition as prohibited from being cloned. */
+#define __noclone __attribute__((__noclone__))
+
+/*
+ * Tell the optimizer that something else uses this function or variable.
+ */
+#define __visible __attribute__((externally_visible))
+
+/*
+ * GCC 'asm goto' miscompiles certain code sequences:
+ *
+ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
+ *
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
+ *
+ * (asm goto is automatically volatile - the naming reflects this.)
+ */
+#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
+
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
+#define __HAVE_BUILTIN_BSWAP32__
+#define __HAVE_BUILTIN_BSWAP64__
+#define __HAVE_BUILTIN_BSWAP16__
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
+
+#define KASAN_ABI_VERSION 4
diff --git a/linux/src/include/linux/hdreg.h b/linux/src/include/linux/hdreg.h
index e223480d..4a388c5d 100644
--- a/linux/src/include/linux/hdreg.h
+++ b/linux/src/include/linux/hdreg.h
@@ -62,6 +62,8 @@
#define WIN_SETFEATURES 0xEF /* set special drive features */
#define WIN_READDMA 0xc8 /* read sectors using DMA transfers */
#define WIN_WRITEDMA 0xca /* write sectors using DMA transfers */
+#define WIN_READDMA_EXT 0x25 /* read sectors using LBA48 DMA transfers */
+#define WIN_WRITEDMA_EXT 0x35 /* write sectors using LBA48 DMA transfers */
/* Additional drive command codes used by ATAPI devices. */
#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */
@@ -168,7 +170,7 @@ struct hd_driveid {
unsigned short word80;
unsigned short word81;
unsigned short command_sets; /* bits 0:Smart 1:Security 2:Removable 3:PM */
- unsigned short word83; /* bits 14:Smart Enabled 13:0 zero */
+ unsigned short command_set_2; /* bits 14:Smart Enabled 13:0 zero */
unsigned short word84;
unsigned short word85;
unsigned short word86;
@@ -185,10 +187,7 @@ struct hd_driveid {
unsigned short word97; /* reserved (word 97) */
unsigned short word98; /* reserved (word 98) */
unsigned short word99; /* reserved (word 99) */
- unsigned short word100; /* reserved (word 100) */
- unsigned short word101; /* reserved (word 101) */
- unsigned short word102; /* reserved (word 102) */
- unsigned short word103; /* reserved (word 103) */
+ unsigned long long lba_capacity_2; /* 48-bit total number of sectors */
unsigned short word104; /* reserved (word 104) */
unsigned short word105; /* reserved (word 105) */
unsigned short word106; /* reserved (word 106) */
diff --git a/linux/src/include/linux/pci.h b/linux/src/include/linux/pci.h
index 3508979f..8aad3d59 100644
--- a/linux/src/include/linux/pci.h
+++ b/linux/src/include/linux/pci.h
@@ -140,6 +140,8 @@
#define PCI_CLASS_STORAGE_FLOPPY 0x0102
#define PCI_CLASS_STORAGE_IPI 0x0103
#define PCI_CLASS_STORAGE_RAID 0x0104
+#define PCI_CLASS_STORAGE_SATA 0x0106
+#define PCI_CLASS_STORAGE_SATA_AHCI 0x010601
#define PCI_CLASS_STORAGE_OTHER 0x0180
#define PCI_BASE_CLASS_NETWORK 0x02
diff --git a/linux/src/include/linux/string.h b/linux/src/include/linux/string.h
index 214503c2..62ff8802 100644
--- a/linux/src/include/linux/string.h
+++ b/linux/src/include/linux/string.h
@@ -12,25 +12,33 @@ extern "C" {
#endif
extern char * ___strtok;
+#if 0
extern char * strcpy(char *,const char *);
extern char * strncpy(char *,const char *, __kernel_size_t);
extern char * strcat(char *, const char *);
extern char * strncat(char *, const char *, __kernel_size_t);
extern char * strchr(const char *,int);
extern char * strrchr(const char *,int);
+#endif
extern char * strpbrk(const char *,const char *);
extern char * strtok(char *,const char *);
extern char * strstr(const char *,const char *);
+#if 0
extern __kernel_size_t strlen(const char *);
extern __kernel_size_t strnlen(const char *,__kernel_size_t);
+#endif
extern __kernel_size_t strspn(const char *,const char *);
+#if 0
extern int strcmp(const char *,const char *);
extern int strncmp(const char *,const char *,__kernel_size_t);
+#endif
extern void * memset(void *,int,__kernel_size_t);
extern void * memcpy(void *,const void *,__kernel_size_t);
+#if 0
extern void * memmove(void *,const void *,__kernel_size_t);
extern void * memscan(void *,int,__kernel_size_t);
+#endif
extern int memcmp(const void *,const void *,__kernel_size_t);
/*